2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <sys/types.h>
23 #include <android/log.h>
24 #include <android_native_app_glue.h>
25 #include <dali-demo-native-activity-jni.h>
26 #include <dali/devel-api/adaptor-framework/application-devel.h>
27 #include <dali/integration-api/debug.h>
28 #include <dali/integration-api/adaptor-framework/android/android-framework.h>
31 // from android_native_app_glue.c
33 #define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "dalidemo", __VA_ARGS__))
35 #define LOGV(...) ((void)0)
41 void free_saved_state(struct android_app *android_app)
43 LOGV("free_saved_state");
44 pthread_mutex_lock(&android_app->mutex);
46 if (android_app->savedState != NULL)
48 free(android_app->savedState);
49 android_app->savedState = NULL;
50 android_app->savedStateSize = 0;
53 pthread_mutex_unlock(&android_app->mutex);
56 void android_app_destroy(struct android_app *android_app)
58 LOGV("android_app_destroy");
59 free_saved_state(android_app);
60 pthread_mutex_lock(&android_app->mutex);
62 if (android_app->inputQueue != NULL)
64 AInputQueue_detachLooper(android_app->inputQueue);
67 AConfiguration_delete(android_app->config);
68 android_app->destroyed = 1;
70 pthread_cond_broadcast(&android_app->cond);
71 pthread_mutex_unlock(&android_app->mutex);
73 // Can't touch android_app object after this.
78 void ExtractAsset(struct android_app* state, const std::string& assetPath, const std::string& filePath)
80 AAsset* asset = AAssetManager_open(state->activity->assetManager, assetPath.c_str(), AASSET_MODE_BUFFER);
83 size_t length = AAsset_getLength(asset) + 1;
85 char* buffer = new char[length];
86 length = AAsset_read(asset, buffer, length);
88 FILE* file = fopen(filePath.c_str(), "wb");
91 fwrite(buffer, 1, length, file);
100 void ExtractAssets(struct android_app* state, const std::string& assetDirPath, const std::string& filesDirPath)
102 AAssetDir* assetDir = AAssetManager_openDir(state->activity->assetManager, assetDirPath.c_str());
105 if (mkdir(filesDirPath.c_str(), S_IRWXU) != -1)
107 const char *filename = NULL;
108 std::string assetPath = assetDirPath + "/";
109 while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL)
111 ExtractAsset(state, assetPath + filename, filesDirPath + "/" + filename);
115 AAssetDir_close(assetDir);
119 void ExtractFontConfig(struct android_app* state, std::string assetFontConfig, std::string fontsPath)
121 AAsset* asset = AAssetManager_open(state->activity->assetManager, assetFontConfig.c_str(), AASSET_MODE_BUFFER);
124 size_t length = AAsset_getLength(asset) + 1;
126 char* buffer = new char[length];
127 length = AAsset_read(asset, buffer, length);
129 std::string fontConfig = std::string(buffer, length);
130 int i = fontConfig.find("~");
131 if (i != std::string::npos)
133 std::string filesDir = state->activity->internalDataPath;
134 fontConfig.replace(i, 1, filesDir);
137 std::string fontsFontConfig = fontsPath;
138 FILE* file = fopen(fontsFontConfig.c_str(), "wb");
141 fwrite(fontConfig.c_str(), 1, fontConfig.size(), file);
150 extern "C" void FcConfigPathInit(const char* path, const char* file);
152 void android_main( struct android_app* state )
154 LOGV("android_main() >>");
156 std::string filesDir = state->activity->internalDataPath;
158 std::string fontconfigPath = filesDir + "/fonts";
159 setenv("FONTCONFIG_PATH", fontconfigPath.c_str(), 1);
161 std::string fontconfigFile = fontconfigPath + "/fonts.conf";
162 setenv("FONTCONFIG_FILE", fontconfigFile.c_str(), 1);
164 struct stat st = { 0 };
165 FcConfigPathInit( fontconfigPath.c_str(), fontconfigFile.c_str() );
167 if (stat(fontconfigPath.c_str(), &st) == -1)
169 mkdir(fontconfigPath.c_str(), S_IRWXU);
170 ExtractFontConfig(state, "fonts/fonts.conf", fontconfigPath + "/fonts.conf");
171 ExtractFontConfig(state, "fonts/fonts.dtd", fontconfigPath + "/fonts.dtd" );
172 ExtractFontConfig(state, "fonts/local.conf", fontconfigPath + "/local.conf");
173 ExtractAssets(state, "fonts/dejavu", fontconfigPath + "/dejavu");
174 ExtractAssets(state, "fonts/tizen", fontconfigPath + "/tizen");
175 ExtractAssets(state, "fonts/bitmap", fontconfigPath + "/bitmap");
178 Dali::Integration::AndroidFramework::New();
179 Dali::Integration::AndroidFramework::Get().SetNativeApplication(state);
180 Dali::Integration::AndroidFramework::Get().SetApplicationConfiguration(state->config);
181 Dali::Integration::AndroidFramework::Get().SetApplicationAssets(state->activity->assetManager);
182 Dali::Integration::AndroidFramework::Get().SetInternalDataPath(filesDir);
184 DaliDemoNativeActivity nativeActivity(state->activity);
187 std::string libpath = "/data/data/com.sec.dalidemo/lib/libdali-demo.so";
188 std::string callParam = nativeActivity.GetIntentStringExtra("start");
189 if (callParam.empty())
191 callParam = nativeActivity.GetMetaData("start");
194 if (!callParam.empty())
196 libpath = "/data/data/com.sec.dalidemo/lib/lib" + callParam + ".so";
199 void* handle = dlopen(libpath.c_str(), RTLD_LAZY);
205 dlerror(); /* Clear any existing error */
207 int (*main)(int, char**) = (int(*)(int, char**))dlsym(handle, "main");
210 status = main( 0, nullptr );
219 android_app_destroy(state);
221 Dali::Integration::AndroidFramework::Get().SetNativeApplication(nullptr);
222 Dali::Integration::AndroidFramework::Get().SetApplicationConfiguration(nullptr);
223 Dali::Integration::AndroidFramework::Get().SetApplicationAssets(nullptr);
224 Dali::Integration::AndroidFramework::Delete();
226 LOGV("android_main() <<");
228 // We need to kill the application process manually, DALi cannot exit the process properly due to memory leaks