From: Anton Obzhirov Date: Wed, 25 Mar 2020 10:14:36 +0000 (+0000) Subject: Change dali demo launching using DaliDemoNativeActivity JNI. X-Git-Tag: dali_1.9.6~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-demo.git;a=commitdiff_plain;h=1a27a252fb5e89357e422e2a40468886ed4d0a6d Change dali demo launching using DaliDemoNativeActivity JNI. Also start new activity in its own private process. Change-Id: I4ad00730247ce39d9acf26eabb3f06ecc3d8e8b8 --- diff --git a/build/android/app/src/main/AndroidManifest.xml b/build/android/app/src/main/AndroidManifest.xml index 15e8dc0..e10568e 100644 --- a/build/android/app/src/main/AndroidManifest.xml +++ b/build/android/app/src/main/AndroidManifest.xml @@ -14,13 +14,30 @@ android:label="@string/app_name" android:name="com.sec.dalidemo.DaliDemoApplication"> + + + + + + + + + - + android:windowSoftInputMode="stateAlwaysVisible" + android:process=":dalidemos"> @@ -37,7 +54,8 @@ android:icon="@mipmap/dali_examples" android:label="@string/examples_name" android:screenOrientation="portrait" - android:windowSoftInputMode="stateAlwaysVisible"> + android:windowSoftInputMode="stateAlwaysVisible" + android:process=":daliexamples"> @@ -54,7 +72,8 @@ android:icon="@mipmap/dali_tests" android:label="@string/tests_name" android:screenOrientation="portrait" - android:windowSoftInputMode="stateAlwaysVisible"> + android:windowSoftInputMode="stateAlwaysVisible" + android:process=":dalitests"> diff --git a/build/android/app/src/main/cpp/CMakeLists.txt b/build/android/app/src/main/cpp/CMakeLists.txt index 39e67ad..fff12ab 100644 --- a/build/android/app/src/main/cpp/CMakeLists.txt +++ b/build/android/app/src/main/cpp/CMakeLists.txt @@ -24,6 +24,7 @@ ADD_LIBRARY(native-activity SHARED main.cpp) TARGET_INCLUDE_DIRECTORIES(native-activity PRIVATE ${ANDROID_NDK}/sources/android/native_app_glue) +INCLUDE_DIRECTORIES(.) INCLUDE_DIRECTORIES(${DALI_ENV_DIR}/include) INCLUDE_DIRECTORIES(${DALI_ENV_DIR}/include/dali) diff --git a/build/android/app/src/main/cpp/dali-demo-native-activity-jni.h b/build/android/app/src/main/cpp/dali-demo-native-activity-jni.h new file mode 100644 index 0000000..2b2df8d --- /dev/null +++ b/build/android/app/src/main/cpp/dali-demo-native-activity-jni.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed 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. + */ + +#ifndef ANDROID_DALI_DEMO_NATIVE_ACTIVITY_JNI_H +#define ANDROID_DALI_DEMO_NATIVE_ACTIVITY_JNI_H + +#include +#include + +class DaliDemoNativeActivity +{ +public: + DaliDemoNativeActivity(ANativeActivity* activity) + : activity(activity) + { + } + + class JString + { + public: + JString(JNIEnv* env, const std::string& str) + : env(env), + string(env->NewStringUTF(str.c_str())) + { + } + + JString(JNIEnv* env, jstring str) + : env(env), + string(str) + { + } + + std::string ToString() + { + std::string out; + if (string) + { + const char* utf = env->GetStringUTFChars(string, 0); + out = std::string(utf); + env->ReleaseStringUTFChars(string, utf); + } + return out; + } + + ~JString() + { + if (string) + { + env->DeleteLocalRef(string); + } + } + + private: + friend class DaliDemoNativeActivity; + JNIEnv* env; + jstring string; + }; + + class NativeActivityJNI + { + public: + NativeActivityJNI(ANativeActivity* activity) + : activity(activity) + { + activity->vm->AttachCurrentThread(&env, nullptr); + clazz = env->GetObjectClass(activity->clazz); + } + + ~NativeActivityJNI() + { + activity->vm->DetachCurrentThread(); + } + + std::string CallStringMethod(const std::string& name, const std::string& arg) + { + jmethodID methodID = env->GetMethodID(clazz, name.c_str(), "(Ljava/lang/String;)Ljava/lang/String;"); + JString argument(env, arg); + JString returnValue(env, (jstring)env->CallObjectMethod(activity->clazz, methodID, argument.string)); + return returnValue.ToString(); + } + + void CallVoidMethod(const std::string& name, const std::string& arg) + { + jmethodID methodID = env->GetMethodID(clazz, name.c_str(), "(Ljava/lang/String;)V"); + JString argument(env, arg); + env->CallVoidMethod(activity->clazz, methodID, argument.string); + } + + private: + ANativeActivity* activity; + JNIEnv* env; + jclass clazz; + }; + + std::string GetMetaData(const std::string& key) + { + NativeActivityJNI nativeActivityJNI(activity); + return nativeActivityJNI.CallStringMethod("getMetaData", key); + } + + std::string GetIntentStringExtra(const std::string& key) + { + NativeActivityJNI nativeActivityJNI(activity); + return nativeActivityJNI.CallStringMethod("getIntentStringExtra", key); + } + + void LaunchExample(const std::string& exampleName) + { + NativeActivityJNI nativeActivityJNI(activity); + return nativeActivityJNI.CallVoidMethod("launchExample", exampleName); + } + +private: + ANativeActivity* activity; +}; + +#endif //ANDROID_DALI_DEMO_NATIVE_ACTIVITY_JNI_H diff --git a/build/android/app/src/main/cpp/main.cpp b/build/android/app/src/main/cpp/main.cpp index 02fb4c4..09fe76a 100644 --- a/build/android/app/src/main/cpp/main.cpp +++ b/build/android/app/src/main/cpp/main.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -39,16 +40,17 @@ namespace void free_saved_state(struct android_app *android_app) { - pthread_mutex_lock(&android_app->mutex); + LOGV("free_saved_state"); + pthread_mutex_lock(&android_app->mutex); - if (android_app->savedState != NULL) - { - free(android_app->savedState); - android_app->savedState = NULL; - android_app->savedStateSize = 0; - } + if (android_app->savedState != NULL) + { + free(android_app->savedState); + android_app->savedState = NULL; + android_app->savedStateSize = 0; + } - pthread_mutex_unlock(&android_app->mutex); + pthread_mutex_unlock(&android_app->mutex); } void android_app_destroy(struct android_app *android_app) @@ -145,77 +147,12 @@ void ExtractFontConfig(struct android_app* state, std::string assetFontConfig, s } } -class DaliDemoNativeActivity -{ -public: - ANativeActivity* activity; - DaliDemoNativeActivity(ANativeActivity* activity) - : activity(activity) - { - } - - class NativeActivityJNI - { - public: - ANativeActivity* activity; - JNIEnv* env; - jclass clazz; - - NativeActivityJNI(ANativeActivity* activity) - : activity(activity) - { - activity->vm->AttachCurrentThread(&env, NULL); - clazz = env->GetObjectClass(activity->clazz); - } - - ~NativeActivityJNI() - { - activity->vm->DetachCurrentThread(); - } - - jstring toJString(const std::string& str) - { - return env->NewStringUTF(str.c_str()); - } - - std::string toString(jstring jstr) - { - std::string out; - if (jstr) - { - const char* utf = env->GetStringUTFChars(jstr, 0); - out = std::string(utf); - env->ReleaseStringUTFChars(jstr, utf); - } - - return out; - } - - std::string callStringMethod(const std::string& name, const std::string& arg) - { - jmethodID methodID = env->GetMethodID(clazz, name.c_str(), "(Ljava/lang/String;)Ljava/lang/String;"); - jstring jstr = (jstring)env->CallObjectMethod(activity->clazz, methodID, toJString(arg)); - return toString(jstr); - } - }; - - std::string getMetaData(const std::string& key) - { - NativeActivityJNI nativeActivityJNI(activity); - return nativeActivityJNI.callStringMethod("getMetaData", key); - } - - std::string getIntentStringExtra(const std::string& key) - { - NativeActivityJNI nativeActivityJNI(activity); - return nativeActivityJNI.callStringMethod("getIntentStringExtra", key); - } -}; - extern "C" void FcConfigPathInit(const char* path, const char* file); void android_main( struct android_app* state ) { + LOGV("android_main() >>"); + std::string filesDir = state->activity->internalDataPath; std::string fontconfigPath = filesDir + "/fonts"; @@ -239,19 +176,19 @@ void android_main( struct android_app* state ) } Dali::Integration::AndroidFramework::New(); - Dali::Integration::AndroidFramework::Get().SetNativeApplication( state ); - Dali::Integration::AndroidFramework::Get().SetApplicationConfiguration( state->config ); - Dali::Integration::AndroidFramework::Get().SetApplicationAssets( state->activity->assetManager ); - Dali::Integration::AndroidFramework::Get().SetInternalDataPath( filesDir ); + Dali::Integration::AndroidFramework::Get().SetNativeApplication(state); + Dali::Integration::AndroidFramework::Get().SetApplicationConfiguration(state->config); + Dali::Integration::AndroidFramework::Get().SetApplicationAssets(state->activity->assetManager); + Dali::Integration::AndroidFramework::Get().SetInternalDataPath(filesDir); DaliDemoNativeActivity nativeActivity(state->activity); int status = 0; std::string libpath = "/data/data/com.sec.dalidemo/lib/libdali-demo.so"; - std::string callParam = nativeActivity.getIntentStringExtra("start"); + std::string callParam = nativeActivity.GetIntentStringExtra("start"); if (callParam.empty()) { - callParam = nativeActivity.getMetaData("start"); + callParam = nativeActivity.GetMetaData("start"); } if (!callParam.empty()) @@ -259,7 +196,7 @@ void android_main( struct android_app* state ) libpath = "/data/data/com.sec.dalidemo/lib/lib" + callParam + ".so"; } - void* handle = dlopen( libpath.c_str(), RTLD_LAZY ); + void* handle = dlopen(libpath.c_str(), RTLD_LAZY); if (!handle) { std::exit(status); @@ -286,7 +223,9 @@ void android_main( struct android_app* state ) Dali::Integration::AndroidFramework::Get().SetApplicationAssets(nullptr); Dali::Integration::AndroidFramework::Delete(); - // We need to kill the application process manually, DALi cannot restart in the same process due to memory leaks + LOGV("android_main() <<"); + + // We need to kill the application process manually, DALi cannot exit the process properly due to memory leaks std::exit(status); } diff --git a/build/android/app/src/main/java/com/sec/dalidemo/DaliDemoNativeActivity.java b/build/android/app/src/main/java/com/sec/dalidemo/DaliDemoNativeActivity.java index 64a7853..e894f60 100644 --- a/build/android/app/src/main/java/com/sec/dalidemo/DaliDemoNativeActivity.java +++ b/build/android/app/src/main/java/com/sec/dalidemo/DaliDemoNativeActivity.java @@ -4,6 +4,7 @@ import android.annotation.TargetApi; import android.app.NativeActivity; import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; @@ -94,4 +95,10 @@ public class DaliDemoNativeActivity extends NativeActivity { public final String getIntentStringExtra(String key) { return getIntent().getStringExtra(key); } + + public final void launchExample(String exampleName) { + Intent intent = new Intent(this, DaliDemoNativeActivity.class); + intent.putExtra("start", exampleName); + startActivity(intent); + } } diff --git a/build/android/app/src/main/java/com/sec/dalidemo/DaliDemosNativeActivity.java b/build/android/app/src/main/java/com/sec/dalidemo/DaliDemosNativeActivity.java new file mode 100644 index 0000000..a2a735c --- /dev/null +++ b/build/android/app/src/main/java/com/sec/dalidemo/DaliDemosNativeActivity.java @@ -0,0 +1,4 @@ +package com.sec.dalidemo; + +public class DaliDemosNativeActivity extends DaliDemoNativeActivity { +} diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 838f3c3..53fa788 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -207,6 +207,12 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REQUIRED_CFLAGS} ${DALI_DEMO_CFLAGS} -Werr SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}") INCLUDE_DIRECTORIES(${ROOT_SRC_DIR}) +IF(ANDROID) + INCLUDE_DIRECTORIES( ${ANDROID_NDK}/sources/android/native_app_glue ) + INCLUDE_DIRECTORIES( ${ANDROID_NDK}/sysroot/usr ) + INCLUDE_DIRECTORIES( ${ANDROID_NDK}/sysroot/usr/include/android ) + INCLUDE_DIRECTORIES( ${ROOT_SRC_DIR}/build/android/app/src/main/cpp ) +ENDIF() ADD_SUBDIRECTORY(demo) ADD_SUBDIRECTORY(examples) diff --git a/shared/execute-process-android.cpp b/shared/execute-process-android.cpp index d042a55..2b91241 100644 --- a/shared/execute-process-android.cpp +++ b/shared/execute-process-android.cpp @@ -21,28 +21,23 @@ // EXTERNAL INCLUDES #include #include + #include +#include +#include + +#include +#include void ExecuteProcess( const std::string& processName, Dali::Application& application ) { - std::stringstream stream; - stream << "am start -a android.intent.action.MAIN -n com.sec.dalidemo/.DaliDemoNativeActivity --user 0 --es start " << processName.c_str(); - pid_t parentPID = getpid(); - - pid_t pid = fork(); - if( pid == 0 ) + struct android_app* nativeApp = Dali::Integration::AndroidFramework::Get().GetNativeApplication(); + if (!nativeApp) { - do - { - sleep( 1 ); - } - while( kill( parentPID, 0 ) == 0 ); - - system( stream.str().c_str() ); - exit( 0 ); - } - else - { - application.Quit(); + DALI_LOG_ERROR("Couldn't get native app."); + return; } + + DaliDemoNativeActivity nativeActivity(nativeApp->activity); + nativeActivity.LaunchExample(processName); }