diff --git a/README.md b/README.md index d154302..cebd1db 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,13 @@ Before running make install as normal: - Ubuntu 16.04 or later - GCC version 6 + - Android DALi dependencies ### Building the Repository +To download Android DALi dependencies clone https://github.com/dalihub/android-dependencies +in your DALi folder (folder containing dali-demo). + + $ git clone https://github.com/dalihub/android-dependencies.git To build the repository enter the 'build/android' folder: @@ -93,6 +98,11 @@ For debug build: $ DEBUG=1 ./build.sh +To debug from Android Studio set Android DALi enviroment using setenv script in 'build/android' and launch Android Studio from the enviroment: + + $ . setenv + $ /bin/studio.sh + To clean the build: $ ./build.sh clean @@ -102,3 +112,4 @@ To install apks: $ adb install -r ./app/build/outputs/apk/debug/dali-demo-debug.apk $ adb install -r ./app/build/outputs/apk/release/dali-demo-release.apk + 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/android/build.sh b/build/android/build.sh index 6e0bf9f..09fa170 100755 --- a/build/android/build.sh +++ b/build/android/build.sh @@ -43,6 +43,10 @@ fi if [ ! -d "$ANDROID_NDK" ]; then if [ -d "$ANDROID_SDK" ]; then NDK_DIR=$(find $ANDROID_SDK -maxdepth 2 -name ndk-build | sed 's/\/ndk-build//') + # Some sdk folder structures have extra dir for ndk folders. + if [ ! -d "$NDK_DIR" ]; then + NDK_DIR=$(find $ANDROID_SDK -maxdepth 3 -name ndk-build | sed 's/\/ndk-build//') + fi if [ -d "$NDK_DIR" ]; then export ANDROID_NDK=$NDK_DIR fi diff --git a/build/android/setenv b/build/android/setenv new file mode 100755 index 0000000..c85e935 --- /dev/null +++ b/build/android/setenv @@ -0,0 +1,35 @@ +[ -z $ROOT_DIR ] && ROOT_DIR=$HOME +echo "Using ROOT_DIR=\"$ROOT_DIR\"" + +[ -z $DALI_DIR ] && DALI_DIR=$(cd ../../../;pwd) +echo "Using DALI_DIR=\"$DALI_DIR\"" +export DALI_DIR=$DALI_DIR + +[ -z $DALI_ENV_DIR ] && DALI_ENV_DIR=$DALI_DIR/dali-env/android +echo "Using DALI_ENV_DIR=\"$DALI_ENV_DIR\"" +export DALI_ENV_DIR=$DALI_ENV_DIR + +[ -z $TARGET ] && export TARGET=armeabi-v7a +echo "Using TARGET=\"$TARGET\"" + +if [ ! -d "$ANDROID_SDK" ]; then +# try default path + if [ -d "$ROOT_DIR/Android/Sdk" ]; then + export ANDROID_SDK=$ROOT_DIR/Android/Sdk + fi +fi +echo "Using ANDROID_SDK=\"$ANDROID_SDK\"" + +if [ ! -d "$ANDROID_NDK" ]; then + if [ -d "$ANDROID_SDK" ]; then + NDK_DIR=$(find $ANDROID_SDK -maxdepth 2 -name ndk-build | sed 's/\/ndk-build//') + # Some sdk folder structures have extra dir for ndk folders. + if [ ! -d "$NDK_DIR" ]; then + NDK_DIR=$(find $ANDROID_SDK -maxdepth 3 -name ndk-build | sed 's/\/ndk-build//') + fi + if [ -d "$NDK_DIR" ]; then + export ANDROID_NDK=$NDK_DIR + fi + fi +fi +echo "Using ANDROID_NDK=\"$ANDROID_NDK\"" 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/examples/reflection-demo/gltf-scene.cpp b/examples/reflection-demo/gltf-scene.cpp index 424ffa2..46e39cf 100644 --- a/examples/reflection-demo/gltf-scene.cpp +++ b/examples/reflection-demo/gltf-scene.cpp @@ -185,7 +185,7 @@ void glTF::LoadFromFile( const std::string& filename ) } else { - GLTF_LOG( "GLTF: %s loaded, size = %d", binFile.c_str(), int(mBuffer.size())); + GLTF_LOG( "GLTF: %s loaded, size = %d", binFile.c_str(), int(jsonBuffer.size())); } // Abort if errors @@ -412,12 +412,18 @@ glTF_Buffer glTF::LoadFile( const std::string& filename ) std::vector buffer; if( fin ) { - fseek( fin, 0, SEEK_END ); + if( fseek( fin, 0, SEEK_END ) ) + { + return {}; + } auto size = ftell(fin); - fseek( fin, 0, SEEK_SET ); + if( fseek( fin, 0, SEEK_SET ) ) + { + return {}; + } buffer.resize(unsigned(size)); auto result = fread( buffer.data(), 1, size_t(size), fin ); - if( result < 0 ) + if( result != size_t(size) ) { GLTF_LOG("LoadFile: Result: %d", int(result)); // return empty buffer diff --git a/examples/reflection-demo/pico-json.h b/examples/reflection-demo/pico-json.h index c1cde44..e4f28e9 100644 --- a/examples/reflection-demo/pico-json.h +++ b/examples/reflection-demo/pico-json.h @@ -132,8 +132,8 @@ public: object* object_; }; protected: - int type_; - _storage u_; + int type_{}; + _storage u_ {}; public: value(); value(int type, bool); diff --git a/examples/reflection-demo/reflection-example.cpp b/examples/reflection-demo/reflection-example.cpp index c0eb880..3bf189f 100644 --- a/examples/reflection-demo/reflection-example.cpp +++ b/examples/reflection-demo/reflection-example.cpp @@ -639,30 +639,31 @@ private: } private: + Application& mApplication; - Layer mLayer3D; + Layer mLayer3D{}; - std::vector mActors; - std::vector mCameras; - std::vector> mModels; - std::vector mTextureSets; + std::vector mActors {}; + std::vector mCameras {}; + std::vector> mModels {}; + std::vector mTextureSets {}; - Animation mAnimation; - float mMockTime = 0.0f; - float mKFactor = 0.0f; - Property::Index mSunTimeUniformIndex; - Property::Index mSunKFactorUniformIndex; - PanGestureDetector mPanGestureDetector; + Animation mAnimation {}; + float mMockTime { 0.0f }; + float mKFactor { 0.0f }; + Property::Index mSunTimeUniformIndex {}; + Property::Index mSunKFactorUniformIndex {}; + PanGestureDetector mPanGestureDetector {}; - Vector3 mCameraPos; - Vector3 mLightDir; - Timer mTickTimer; + Vector3 mCameraPos { Vector3::ZERO }; + Vector3 mLightDir { Vector3::ZERO }; + Timer mTickTimer {}; - CameraActor mCamera3D; - CameraActor mReflectionCamera3D; - Actor mCenterActor; - Actor mCenterHorizActor; + CameraActor mCamera3D {}; + CameraActor mReflectionCamera3D {}; + Actor mCenterActor {}; + Actor mCenterHorizActor {}; }; int DALI_EXPORT_API main( int argc, char **argv ) diff --git a/packaging/com.samsung.dali-demo.spec b/packaging/com.samsung.dali-demo.spec index 3c49fe0..91cf2d5 100755 --- a/packaging/com.samsung.dali-demo.spec +++ b/packaging/com.samsung.dali-demo.spec @@ -2,7 +2,7 @@ Name: com.samsung.dali-demo Summary: The OpenGLES Canvas Core Demo -Version: 1.9.5 +Version: 1.9.6 Release: 1 Group: System/Libraries License: Apache-2.0 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); }