Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update gradle version and other changes in android apps #10867

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
129 changes: 104 additions & 25 deletions apps/android_camera/README.md
@@ -1,28 +1,107 @@
[//]: # Licensed to the Apache Software Foundation (ASF) under one
[//]: # or more contributor license agreements. See the NOTICE file
[//]: # distributed with this work for additional information
[//]: # regarding copyright ownership. The ASF licenses this file
[//]: # to you under the Apache License, Version 2.0 (the
[//]: # "License"); you may not use this file except in compliance
[//]: # with the License. You may obtain a copy of the License at
[//]: #
[//]: # http://www.apache.org/licenses/LICENSE-2.0
[//]: #
[//]: # Unless required by applicable law or agreed to in writing,
[//]: # software distributed under the License is distributed on an
[//]: # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
[//]: # KIND, either express or implied. See the License for the
[//]: # specific language governing permissions and limitations
[//]: # under the License.

Android Camera Demo Sample App
==============================

The Android Camera Demo Sample App provides a basic implementation of an Android
app that uses the tvm runtime to perform image classification in real time.

Converting Models
-----------------
<!--- Licensed to the Apache Software Foundation (ASF) under one -->
<!--- or more contributor license agreements. See the NOTICE file -->
<!--- distributed with this work for additional information -->
<!--- regarding copyright ownership. The ASF licenses this file -->
<!--- to you under the Apache License, Version 2.0 (the -->
<!--- "License"); you may not use this file except in compliance -->
<!--- with the License. You may obtain a copy of the License at -->

<!--- http://www.apache.org/licenses/LICENSE-2.0 -->

<!--- Unless required by applicable law or agreed to in writing, -->
<!--- software distributed under the License is distributed on an -->
<!--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -->
<!--- KIND, either express or implied. See the License for the -->
<!--- specific language governing permissions and limitations -->
<!--- under the License. -->


# Android Camera Demo Sample App

The Android Camera Demo Sample App provides a basic implementation of an Android app that uses the tvm runtime to perform image classification in real time.

You will need JDK, [Android NDK](https://developer.android.com/ndk) and an Android device to use this.

## Build and Installation

### <a name="preparemodels">Prepare Models</a>

The `models/prepare_models.py` script provides a example flow for dumping model
parameter files for use by the app.

1. Set path to the NDK CC: `export TVM_NDK_CC=[Path to CC, e.g. /opt/android-toolchain-arm64/bin/aarch64-linux-android-g++]`
2. Switch to the script directory: `cd models`
3. Run script: `python3 prepare_model.py`

#### Sample output
```
mobilenet_v2
getting model...
building...
dumping lib...
dumping graph...
dumping params...
dumping labels...
resnet18_v1
getting model...
building...
dumping lib...
dumping graph...
dumping params...
dumping labels...
```

### <a name="buildapk">Build APK</a>

We use [Gradle](https://gradle.org) to build. Please follow [the installation instruction](https://gradle.org/install) for your operating system.

Before you build the Android application, please refer to [TVM4J Installation Guide](https://github.com/apache/tvm/blob/main/jvm/README.md) and install tvm4j-core to your local maven repository. You can find tvm4j dependency declare in `app/build.gradle`. Modify it if it is necessary.

```
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('androidx.test.espresso:espresso-core:3.2.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.google.android.material:material:1.5.0'
implementation 'org.apache.tvm:tvm4j-core:0.0.1-SNAPSHOT'
testImplementation 'junit:junit:4.13.2'

implementation "androidx.concurrent:concurrent-futures:1.0.0"
implementation "androidx.camera:camera-core:1.0.0-beta01"
implementation "androidx.camera:camera-camera2:1.0.0-beta01"
implementation "androidx.camera:camera-view:1.0.0-alpha08"
implementation "androidx.camera:camera-extensions:1.0.0-alpha08"
implementation "androidx.camera:camera-lifecycle:1.0.0-beta01"
}
```

Now use Gradle to compile JNI, resolve Java dependencies and build the Android application together with tvm4j. Run following script to generate the apk file.

```bash
export ANDROID_HOME=[Path to your Android SDK, e.g., ~/Android/sdk]
cd apps/android_camera
gradle clean build
```

In `app/build/outputs/apk` you'll find `app-release-unsigned.apk`, use `dev_tools/gen_keystore.sh` to generate a signature and use `dev_tools/sign_apk.sh` to get the signed apk file `app/build/outputs/apk/release/tv8mdemo-release.apk`.

Upload `tv8mdemo-release.apk` to your Android device and install it:

```bash
$ANDROID_HOME/platform-tools/adb install app/build/outputs/apk/release/tv8mdemo-release.apk
```

If you see error:

adb: failed to install app/build/outputs/apk/release/tv8mdemo-release.apk:
Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE:
Package ml.apache.tvm.android.androidcamerademo signatures do not match the previously installed version; ignoring!]

Run uninstall first:

```bash
$ANDROID_HOME/platform-tools/adb uninstall ml.apache.tvm.android.androidcamerademo
```
50 changes: 40 additions & 10 deletions apps/android_camera/app/build.gradle
Expand Up @@ -17,20 +17,47 @@

apply plugin: 'com.android.application'

task generateJniHeaders(type: Exec, description: 'Generate JNI Headers') {
def headerPath = "${project.projectDir}/src/main/jni"
def classPath = "${project.projectDir}/../../../jvm/core/target/*"
def filePath = "${project.projectDir}/../../../jvm/core/src/main/java/org/apache/tvm/LibInfo.java"
commandLine "javac", "-h", headerPath, "-classpath", classPath, filePath
doLast {
file("${headerPath}/org_apache_tvm_LibInfo.h").renameTo(file("${headerPath}/org_apache_tvm_native_c_api.h"))
}
}

task copyFiles(type: Copy, description: 'Copy Sources for ndk-build') {
dependsOn "generateJniHeaders"
def ndkFilesPath = "${project.projectDir}/../../../jvm/native/src/main/native"
def srcPath = "${project.projectDir}/src/main/jni/"

from "${ndkFilesPath}/org_apache_tvm_native_c_api.cc", "${ndkFilesPath}/jni_helper_func.h"
into srcPath
}

task deleteLibs(type: Delete, description: "Delete Compiled Libraries") {
dependsOn "copyFiles"
def libsPath = "${project.projectDir}/src/main/libs"
delete libsPath
}

task buildJni(type: Exec, description: 'Build JNI libs') {
commandLine 'sh', 'src/main/jni/build.sh'
dependsOn "deleteLibs"
def buildPath = "${project.projectDir}/src/main/jni"
commandLine "ndk-build", "--directory", buildPath
}

tasks.withType(JavaCompile) {
//compileTask -> compileTask.dependsOn buildJni
compileTask -> compileTask.dependsOn buildJni
}

android {
compileSdkVersion 29
compileSdkVersion 31
defaultConfig {
applicationId "ml.apache.tvm.android.androidcamerademo"
minSdkVersion 24
targetSdkVersion 29
targetSdkVersion 26
renderscriptTargetApi 18
renderscriptSupportModeEnabled true
versionCode 1
Expand All @@ -53,21 +80,24 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildToolsVersion = '29.0.3'

lintOptions {
disable "Instantiatable" // MainActivity and RPCActivity must extend android.app.Activity
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('androidx.test.espresso:espresso-core:3.2.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.google.android.material:material:1.5.0'
implementation 'org.apache.tvm:tvm4j-core:0.0.1-SNAPSHOT'
testImplementation 'junit:junit:4.13'
testImplementation 'junit:junit:4.13.2'

implementation("androidx.concurrent:concurrent-futures:1.0.0")
implementation "androidx.concurrent:concurrent-futures:1.0.0"
implementation "androidx.camera:camera-core:1.0.0-beta01"
implementation "androidx.camera:camera-camera2:1.0.0-beta01"
// If you want to use the CameraX View class
Expand Down
2 changes: 1 addition & 1 deletion apps/android_camera/app/src/main/AndroidManifest.xml
Expand Up @@ -28,7 +28,7 @@
tools:ignore="AllowBackup,MissingApplicationIcon">
<activity
android:name="org.apache.tvm.android.androidcamerademo.MainActivity"
android:label="@string/app_name"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"
tools:ignore="LockedOrientationActivity">
Expand Down
Expand Up @@ -382,7 +382,7 @@ private Bitmap YUV_420_888_toRGB(Image image, int width, int height) {
}

private float[] getFrame(ImageProxy imageProxy) {
@SuppressLint("UnsafeExperimentalUsageError")
@SuppressLint("UnsafeOptInUsageError")
Image image = imageProxy.getImage();
// extract the jpeg content
if (image == null) {
Expand Down
Expand Up @@ -78,6 +78,7 @@ private void startFragment() {
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (allPermissionsGranted()) {
startFragment();
} else {
Expand Down
3 changes: 3 additions & 0 deletions apps/android_camera/app/src/main/jni/Android.mk
Expand Up @@ -34,11 +34,14 @@ endif
include $(config)

LOCAL_SRC_FILES := org_apache_tvm_native_c_api.cc

LOCAL_LDFLAGS := -L$(SYSROOT)/usr/lib/ -llog

LOCAL_C_INCLUDES := $(ROOT_PATH)/include \
$(ROOT_PATH)/src/runtime/rpc \
$(ROOT_PATH)/3rdparty/dlpack/include \
$(ROOT_PATH)/3rdparty/dmlc-core/include \
$(MY_PATH)

LOCAL_MODULE = tvm4j_runtime_packed

Expand Down
4 changes: 4 additions & 0 deletions apps/android_camera/app/src/main/jni/tvm_runtime.h
Expand Up @@ -43,8 +43,12 @@
#include "../src/runtime/module.cc"
#include "../src/runtime/ndarray.cc"
#include "../src/runtime/object.cc"
#include "../src/runtime/profiling.cc"
#include "../src/runtime/registry.cc"
#include "../src/runtime/rpc/rpc_channel.cc"
#include "../src/runtime/rpc/rpc_endpoint.cc"
#include "../src/runtime/rpc/rpc_event_impl.cc"
#include "../src/runtime/rpc/rpc_local_session.cc"
#include "../src/runtime/rpc/rpc_module.cc"
#include "../src/runtime/rpc/rpc_server_env.cc"
#include "../src/runtime/rpc/rpc_session.cc"
Expand Down
Expand Up @@ -20,7 +20,7 @@
android:id="@+id/listview_row_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="2dp"
android:layout_marginEnd="2dp"
android:background="@drawable/item_selector"
android:padding="10dp"
android:textSize="18sp"
Expand Down
13 changes: 6 additions & 7 deletions apps/android_camera/build.gradle
Expand Up @@ -19,31 +19,30 @@

buildscript {
repositories {
jcenter()
gradlePluginPortal()
maven {
url 'https://maven.google.com'
}
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
classpath 'com.android.tools.build:gradle:7.1.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
jcenter()
gradlePluginPortal()
maven {
url 'https://maven.google.com'
url 'https://maven.google.com'
}
mavenLocal()
mavenCentral()
google()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
}
1 change: 0 additions & 1 deletion apps/android_camera/gradle.properties
@@ -1,4 +1,3 @@

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
Expand Down
2 changes: 1 addition & 1 deletion apps/android_camera/models/prepare_model.py
Expand Up @@ -106,7 +106,7 @@ def main(model_str, output_path):
f.write(graph)
print("dumping params...")
with open(output_path_str + "/" + "deploy_param.params", "wb") as f:
f.write(runtime.save_param_dict(params))
f.write(tvm.runtime.save_param_dict(params))
print("dumping labels...")
synset_url = "".join(
[
Expand Down