From 3cd18d0d7c37642b635c6748a60ffe62752e4606 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=A1=B0=EC=9B=85=EC=84=9D/MDE=20Lab=28SR=29/=EC=82=BC?= =?utf8?q?=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 24 Aug 2023 15:58:23 +0900 Subject: [PATCH 01/16] Call plugin has log control before preloading (#483) * Call pluginHasLogControl in the initialize VD create log thread in the pluginHasLogControl to redirect stdout,stderr to vlog. To prevent log missing in the candidate process, call pluginHasLogControl in the initialize() function. * call pluginHasLogControl before preloading --- NativeLauncher/launcher/lib/core_runtime.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/NativeLauncher/launcher/lib/core_runtime.cc b/NativeLauncher/launcher/lib/core_runtime.cc index af6ddad..ba874aa 100644 --- a/NativeLauncher/launcher/lib/core_runtime.cc +++ b/NativeLauncher/launcher/lib/core_runtime.cc @@ -422,6 +422,11 @@ int CoreRuntime::initialize(const char* appType, LaunchMode launchMode) return -1; } + // VD has their own signal handler. + if (!pluginHasLogControl()) { + registerSigHandler(); + } + int st = createDelegate(__hostHandle, __domainId, "Tizen.Runtime", "Tizen.Runtime.Environment", "SetEnvironmentVariable", (void**)&setEnvironmentVariable); if (st < 0 || setEnvironmentVariable == nullptr) { _ERR("Create delegate for Tizen.Runtime.dll -> Tizen.Runtime.Environment -> SetEnvironmentVariable failed (0x%08x)", st); @@ -452,11 +457,6 @@ int CoreRuntime::initialize(const char* appType, LaunchMode launchMode) removeDebugPipe(); } - // VD has their own signal handler. - if (!pluginHasLogControl()) { - registerSigHandler(); - } - __initialized = true; _INFO("CoreRuntime initialize success"); -- 2.7.4 From bf82c4dadc20abfda57f32c7313290a877db2e9e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=A1=B0=EC=9B=85=EC=84=9D/MDE=20Lab=28SR=29/=EC=82=BC?= =?utf8?q?=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 11 Oct 2023 10:18:39 +0900 Subject: [PATCH 02/16] Add DIAGNOSTIC to debugger script (#484) To set DOTNET_DiagnosticPorts environment for app launching, Add DIAGNOSTIC option to debugger script Only environment key value is described in debugger script. The environment value should be set when launching application like below. owner:~> launch_app [APP_ID] __AUL_SDK__ DIAGNOSTIC DOTNET_DiagnosticPorts [PortName] --- NativeLauncher/dotnet.debugger | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/NativeLauncher/dotnet.debugger b/NativeLauncher/dotnet.debugger index e2c765d..12ccfc9 100644 --- a/NativeLauncher/dotnet.debugger +++ b/NativeLauncher/dotnet.debugger @@ -20,6 +20,11 @@ APP_TYPE dotnet|dotnet-nui EXTRA_KEY __DLP_DEBUG_ARG__ [DEBUGGER] +NAME DIAGNOSTICS +APP_TYPE dotnet|dotnet-nui +EXTRA_ENV DOTNET_DiagnosticPorts + +[DEBUGGER] NAME HEAPTRACK EXE /home/owner/share/tmp/sdk_tools/profctl/profctl APP_TYPE dotnet|dotnet-nui -- 2.7.4 From c8b525e03ec5caf89e78ffa4a888aa57f2179540 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Thu, 26 Oct 2023 09:01:26 +0900 Subject: [PATCH 03/16] Add launchpad_loader_block/unblock_thread() method --- NativeLauncher/launcher/exec/loader.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/NativeLauncher/launcher/exec/loader.cc b/NativeLauncher/launcher/exec/loader.cc index 62fccdc..e1079be 100644 --- a/NativeLauncher/launcher/exec/loader.cc +++ b/NativeLauncher/launcher/exec/loader.cc @@ -161,6 +161,17 @@ static void __loader_create_cb(bundle *extra, int type, void *user_data) } } +static int __loader_prelaunch_cb(int argc, char **argv, const char *app_path, + const char *appid, const char *pkgid, const char *pkg_type, + void *user_data) +{ + int ret = launchpad_loader_block_threads(); + if (ret != 0) { + _ERR("Failed to prelaunch"); + } + return ret; +} + static int __loader_launch_cb(int argc, char **argv, const char *app_path, const char *appid, const char *pkgid, const char *pkg_type, void *user_data) @@ -169,12 +180,11 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path, if (root_path != NULL) { __appInfo.root = root_path; } - __appInfo.app_path = app_path; __appInfo.appid = appid; __appInfo.pkgid = pkgid; - return 0; + return launchpad_loader_unblock_threads(); } static int __loader_terminate_cb(int argc, char **argv, void *user_data) @@ -207,6 +217,7 @@ extern "C" int realMain(int argc, char *argv[]) loader_lifecycle_callback_s callbacks = { .create = __loader_create_cb, + .prelaunch = __loader_prelaunch_cb, .launch = __loader_launch_cb, .terminate = __loader_terminate_cb }; -- 2.7.4 From fe49959e3e6df3c13c09ba28cfabab1e330cb995 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Tue, 31 Oct 2023 07:11:43 +0900 Subject: [PATCH 04/16] Create vconf related to .NET as a file in RO location --- NativeLauncher/inc/launcher_env.h | 1 + NativeLauncher/tool/multi_target_resolver.cc | 91 +++++++++++++++++++--------- NativeLauncher/util/path_manager.cc | 10 +-- 3 files changed, 69 insertions(+), 33 deletions(-) diff --git a/NativeLauncher/inc/launcher_env.h b/NativeLauncher/inc/launcher_env.h index 31de2a5..f32405a 100644 --- a/NativeLauncher/inc/launcher_env.h +++ b/NativeLauncher/inc/launcher_env.h @@ -19,6 +19,7 @@ #define PLUGIN_PATH "/usr/share/dotnet.tizen/lib/libdotnet_plugin.so" #define ENV_FILE_PATH "/usr/share/dotnet.tizen/lib/coreclr_env.list" +#define DOTNET_RESOLVING_INFO_PATH "/usr/share/dotnet.tizen/lib/dotnet_resolving.info" #define AOT_METADATA_KEY "http://tizen.org/metadata/prefer_dotnet_aot" #define TAC_METADATA_KEY "http://tizen.org/metadata/prefer_nuget_cache" #define METADATA_VALUE_TRUE "true" diff --git a/NativeLauncher/tool/multi_target_resolver.cc b/NativeLauncher/tool/multi_target_resolver.cc index 839f6a0..38416a6 100644 --- a/NativeLauncher/tool/multi_target_resolver.cc +++ b/NativeLauncher/tool/multi_target_resolver.cc @@ -50,23 +50,47 @@ static int convertStrVersionToInt(const std::string& version) return ret; } +// Guided by Appfw, vconf daemon does not run at mic stage. +// So vconf_get_* api does not work normally. +// Therefore, it provides a second chance to read the file when vconf_get_* is null. +// /usr/share/dotnet.tizen/lib/dotnet_resolving.info +static std::string getDotnetResolvingInfo(const char* key) +{ + std::ifstream ifs(DOTNET_RESOLVING_INFO_PATH); + std::string line; + while (std::getline(ifs, line)) { + if (!strcmp(line.substr(0, line.find(" ")).c_str(), key)) { + ifs.close(); + return line.substr(line.rfind(" ") + 1); + } + } + _ERR("Faield to get vconf. %s is null", key); + return ""; +} + static std::vector getRidFallbackGraph() { + std::string tizen_rid_version; + char* tizen_rid_version_value = vconf_get_str(__TIZEN_RID_VERSION_KEY); + if (!tizen_rid_version_value) { + _INFO("Faield to get vconf. So, Read the dotnet_resolving.info file"); + tizen_rid_version = getDotnetResolvingInfo(__TIZEN_RID_VERSION_KEY); + } else { + tizen_rid_version = std::string(tizen_rid_version_value); + free(tizen_rid_version_value); + } + + std::vector rid_version; std::vector RID_FALLBACK_GRAPH; - char* tizen_rid_version = vconf_get_str(__TIZEN_RID_VERSION_KEY); - if (tizen_rid_version) { - std::vector rid_version; - splitPath(tizen_rid_version, rid_version); - std::reverse(std::begin(rid_version), std::end(rid_version)); - for (auto& ridVersion : rid_version) { - //.NET 6.0 is supported from Tizen 6.5.0 - if (convertStrVersionToInt(ridVersion) >= 650) { - platform_version_list.push_back(ridVersion.substr(0, ridVersion.rfind('.'))); - } - RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion + "-" + ARCHITECTURE_IDENTIFIER)); - RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion)); + splitPath(tizen_rid_version, rid_version); + std::reverse(std::begin(rid_version), std::end(rid_version)); + for (auto& ridVersion : rid_version) { + //.NET 6.0 is supported from Tizen 6.5.0 + if (convertStrVersionToInt(ridVersion) >= 650) { + platform_version_list.push_back(ridVersion.substr(0, ridVersion.rfind('.'))); } - free(tizen_rid_version); + RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion + "-" + ARCHITECTURE_IDENTIFIER)); + RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion)); } std::vector RID_FALLBACK_OS = {"tizen", "linux", "unix"}; @@ -82,26 +106,37 @@ static std::vector getRidFallbackGraph() static std::vector getTfmFallbackGraph() { + std::string dotnet_runtime_version; + char* dotnet_runtime_version_value = vconf_get_str(__DOTNET_RUNTIME_VERSION_KEY); + if (!dotnet_runtime_version_value) { + _INFO("Faield to get vconf. So, Read the dotnet_resolving.info file"); + dotnet_runtime_version = getDotnetResolvingInfo(__DOTNET_RUNTIME_VERSION_KEY); + } else { + dotnet_runtime_version = std::string(dotnet_runtime_version_value); + free(dotnet_runtime_version_value); + } + std::vector tfm_list; - char* dotnet_runtime_version = vconf_get_str(__DOTNET_RUNTIME_VERSION_KEY); - if (dotnet_runtime_version) { - std::vector dotnet_version; - splitPath(dotnet_runtime_version, dotnet_version); - for (auto& dotnetVersion : dotnet_version) { - for (auto& platformVersion : platform_version_list) { - tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen" + platformVersion)); - } - tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen")); - tfm_list.push_back(std::string("net" + dotnetVersion)); + std::vector dotnet_version; + splitPath(dotnet_runtime_version, dotnet_version); + for (auto& dotnetVersion : dotnet_version) { + for (auto& platformVersion : platform_version_list) { + tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen" + platformVersion)); } - free(dotnet_runtime_version); + tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen")); + tfm_list.push_back(std::string("net" + dotnetVersion)); } - char* tizen_tfm = vconf_get_str(__TIZEN_TFM_SUPPORT_KEY); - if (tizen_tfm) { - splitPath(tizen_tfm, tfm_list); - free(tizen_tfm); + std::string tizen_tfm; + char* tizen_tfm_value = vconf_get_str(__TIZEN_TFM_SUPPORT_KEY); + if (!tizen_tfm_value) { + _INFO("Faield to get vconf. So, Read the dotnet_resolving.info file"); + tizen_tfm = getDotnetResolvingInfo(__TIZEN_TFM_SUPPORT_KEY); + } else { + tizen_tfm = std::string(tizen_tfm_value); + free(tizen_tfm_value); } + splitPath(tizen_tfm, tfm_list); tfm_list.push_back("net5.0"); std::vector netcoreapp_version = {"3.1", "3.0", "2.2", "2.1", "2.0", "1.1", "1.0"}; diff --git a/NativeLauncher/util/path_manager.cc b/NativeLauncher/util/path_manager.cc index a91cad6..2eac3b7 100644 --- a/NativeLauncher/util/path_manager.cc +++ b/NativeLauncher/util/path_manager.cc @@ -81,11 +81,11 @@ PathManager::PathManager() : platformAssembliesPaths.push_back(runtimePath); // set tizenfx path - char* tmp = vconf_get_str(__TIZEN_API_PATH_KEY); - if (tmp) { - tizenfxPath = std::string(tmp); - _DBG("Device API Directory is set by vconf : %s", tmp); - free(tmp); + char* tizenfx_path = vconf_get_str(__TIZEN_API_PATH_KEY); + if (tizenfx_path) { + tizenfxPath = std::string(tizenfx_path); + _DBG("Device API Directory is set by vconf : %s", tizenfx_path); + free(tizenfx_path); } else { tizenfxPath = getAbsolutePath(__DEVICE_API_DIR); } -- 2.7.4 From bad09c61ae5eb3c17ea3ffa56cc70f2f350ef9b5 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Tue, 7 Nov 2023 15:22:48 +0900 Subject: [PATCH 05/16] Revert "Add launchpad_loader_block/unblock_thread() method" This reverts commit c8b525e03ec5caf89e78ffa4a888aa57f2179540. --- NativeLauncher/launcher/exec/loader.cc | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/NativeLauncher/launcher/exec/loader.cc b/NativeLauncher/launcher/exec/loader.cc index e1079be..62fccdc 100644 --- a/NativeLauncher/launcher/exec/loader.cc +++ b/NativeLauncher/launcher/exec/loader.cc @@ -161,17 +161,6 @@ static void __loader_create_cb(bundle *extra, int type, void *user_data) } } -static int __loader_prelaunch_cb(int argc, char **argv, const char *app_path, - const char *appid, const char *pkgid, const char *pkg_type, - void *user_data) -{ - int ret = launchpad_loader_block_threads(); - if (ret != 0) { - _ERR("Failed to prelaunch"); - } - return ret; -} - static int __loader_launch_cb(int argc, char **argv, const char *app_path, const char *appid, const char *pkgid, const char *pkg_type, void *user_data) @@ -180,11 +169,12 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path, if (root_path != NULL) { __appInfo.root = root_path; } + __appInfo.app_path = app_path; __appInfo.appid = appid; __appInfo.pkgid = pkgid; - return launchpad_loader_unblock_threads(); + return 0; } static int __loader_terminate_cb(int argc, char **argv, void *user_data) @@ -217,7 +207,6 @@ extern "C" int realMain(int argc, char *argv[]) loader_lifecycle_callback_s callbacks = { .create = __loader_create_cb, - .prelaunch = __loader_prelaunch_cb, .launch = __loader_launch_cb, .terminate = __loader_terminate_cb }; -- 2.7.4 From 07a22157e9ddad89658a459fae3b07835e820411 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Thu, 9 Nov 2023 10:05:34 +0900 Subject: [PATCH 06/16] Gets the user's uid related to installed app only. if there are many installed apps, it takes a lot of time to delete profile data. This is because it attempts to delete profile data for all uids. To optimize this, only uids related to the installed app are obtained. --- NativeLauncher/inc/profile_common.h | 2 +- .../installer-plugin/dotnet_apptype_plugin.cc | 2 +- NativeLauncher/tool/dotnettool.cc | 2 +- NativeLauncher/tool/profile_common.cc | 56 ++++++++++++++-------- 4 files changed, 38 insertions(+), 24 deletions(-) diff --git a/NativeLauncher/inc/profile_common.h b/NativeLauncher/inc/profile_common.h index 7495a23..87329be 100644 --- a/NativeLauncher/inc/profile_common.h +++ b/NativeLauncher/inc/profile_common.h @@ -31,7 +31,7 @@ typedef enum { * @param[in] pkgId package id * @return profile_error_e */ -profile_error_e removeAppProfileData(const std::string& pkgId); +profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data); /** * @brief remove all app profile data diff --git a/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc b/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc index 48e0ed3..25d2c4e 100644 --- a/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc +++ b/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc @@ -57,7 +57,7 @@ extern "C" int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char* pkgId) return 0; } - if (removeAppProfileData(pkgId) != PROFILE_ERROR_NONE) { + if (removeAppProfileData(pkgId, NULL) != PROFILE_ERROR_NONE) { _ERR("Failed to remove [%s] profile data", pkgId); } diff --git a/NativeLauncher/tool/dotnettool.cc b/NativeLauncher/tool/dotnettool.cc index 4343b49..0afa2ff 100644 --- a/NativeLauncher/tool/dotnettool.cc +++ b/NativeLauncher/tool/dotnettool.cc @@ -394,7 +394,7 @@ int main(int argc, char* argv[]) } while (it != args.end()) { std::string pkg = std::string(*it); - if (removeAppProfileData(pkg) != PROFILE_ERROR_NONE) { + if (removeAppProfileData(pkg, NULL) != PROFILE_ERROR_NONE) { _SERR("Failed to remove [%s] profile data", pkg.c_str()); } it = args.erase(it); diff --git a/NativeLauncher/tool/profile_common.cc b/NativeLauncher/tool/profile_common.cc index 91065f1..e052544 100644 --- a/NativeLauncher/tool/profile_common.cc +++ b/NativeLauncher/tool/profile_common.cc @@ -20,29 +20,35 @@ #include "launcher_env.h" #include +#include #include #include +// Gets the user's uid with a directory under the home directory. +// In order to reduce unnecessary operation, only uids related to installed app are obtained. static std::vector getUserIds() { - std::vector list; - - while (true) { - errno = 0; // so we can distinguish errors from no more entries - passwd* entry = getpwent(); - if (!entry) { - if (errno) { - _SERR("Error while getting userIDs"); - list.clear(); - return list; + DIR *dir; + struct dirent* entry; + struct passwd *p; + std::vector uids; + + dir = opendir("/home"); + if (dir == nullptr) { + return uids; + } + + while ((entry = readdir(dir)) != nullptr) { + if (entry->d_type == DT_DIR) { + if ((p = getpwnam(entry->d_name)) != NULL) { + uids.push_back(p->pw_uid); } - break; } - list.push_back(entry->pw_uid); } - endpwent(); - return list; + closedir(dir); + + return uids; } static std::string getAppDataPath(const std::string& pkgId, uid_t uid) @@ -61,16 +67,22 @@ static std::string getAppDataPath(const std::string& pkgId, uid_t uid) return pDataFile; } -profile_error_e removeAppProfileData(const std::string& pkgId) +profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data) { if (pkgId.empty()) { return PROFILE_ERROR_INVALID_PARAMETER; } - std::vector uidList = getUserIds(); - for (auto& uid : uidList) { - // get data path from pkgid - std::string dataPath = getAppDataPath(pkgId, uid); + std::vector uidList; + if (user_data != NULL) { + uidList = *(std::vector*)user_data; + } else { + uidList = getUserIds(); + } + + for (auto it = uidList.begin(); it != uidList.end(); ++it) { + // get data path from pkgid and uid + std::string dataPath = getAppDataPath(pkgId, *it); if (!dataPath.empty() && exist(dataPath)) { std::string pDataFile = dataPath + PROFILE_BASENAME; @@ -110,7 +122,7 @@ static int removeAppProfileListCb(pkgmgrinfo_appinfo_h handle, void *user_data) return 0; } - if (removeAppProfileData(pkgId) != PROFILE_ERROR_NONE) { + if (removeAppProfileData(pkgId, user_data) != PROFILE_ERROR_NONE) { _SERR("Failed to remove profile data for (%s)", pkgId); } @@ -119,7 +131,9 @@ static int removeAppProfileListCb(pkgmgrinfo_appinfo_h handle, void *user_data) void removeAllAppProfileData() { - int ret = pkgmgrinfo_appinfo_get_installed_list(removeAppProfileListCb, NULL); + // To reduce repeated getUserIds calls, get uids here. + std::vector uidList = getUserIds(); + int ret = pkgmgrinfo_appinfo_get_installed_list(removeAppProfileListCb, &uidList); if (ret != PMINFO_R_OK) { _SERR("Failed to get installed list"); } -- 2.7.4 From 4c5a2e19bbf73fc0475c01f6181f6cba87700ed2 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Thu, 9 Nov 2023 10:58:58 +0900 Subject: [PATCH 07/16] Set default value (NULL) for removeAllProfile --- NativeLauncher/inc/profile_common.h | 2 +- NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc | 2 +- NativeLauncher/tool/dotnettool.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/NativeLauncher/inc/profile_common.h b/NativeLauncher/inc/profile_common.h index 87329be..00be818 100644 --- a/NativeLauncher/inc/profile_common.h +++ b/NativeLauncher/inc/profile_common.h @@ -31,7 +31,7 @@ typedef enum { * @param[in] pkgId package id * @return profile_error_e */ -profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data); +profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data = NULL); /** * @brief remove all app profile data diff --git a/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc b/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc index 25d2c4e..48e0ed3 100644 --- a/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc +++ b/NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc @@ -57,7 +57,7 @@ extern "C" int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char* pkgId) return 0; } - if (removeAppProfileData(pkgId, NULL) != PROFILE_ERROR_NONE) { + if (removeAppProfileData(pkgId) != PROFILE_ERROR_NONE) { _ERR("Failed to remove [%s] profile data", pkgId); } diff --git a/NativeLauncher/tool/dotnettool.cc b/NativeLauncher/tool/dotnettool.cc index 0afa2ff..4343b49 100644 --- a/NativeLauncher/tool/dotnettool.cc +++ b/NativeLauncher/tool/dotnettool.cc @@ -394,7 +394,7 @@ int main(int argc, char* argv[]) } while (it != args.end()) { std::string pkg = std::string(*it); - if (removeAppProfileData(pkg, NULL) != PROFILE_ERROR_NONE) { + if (removeAppProfileData(pkg) != PROFILE_ERROR_NONE) { _SERR("Failed to remove [%s] profile data", pkg.c_str()); } it = args.erase(it); -- 2.7.4 From cefe45ea96b6761956be5f4298244f1804022662 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Thu, 9 Nov 2023 15:06:16 +0900 Subject: [PATCH 08/16] Get user app root dir for remove profile data To remove duplicated API call(changing user), get userAppRoot dir instead of uid. --- NativeLauncher/tool/profile_common.cc | 49 ++++++++++++++--------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/NativeLauncher/tool/profile_common.cc b/NativeLauncher/tool/profile_common.cc index e052544..80ae73d 100644 --- a/NativeLauncher/tool/profile_common.cc +++ b/NativeLauncher/tool/profile_common.cc @@ -24,47 +24,36 @@ #include #include -// Gets the user's uid with a directory under the home directory. -// In order to reduce unnecessary operation, only uids related to installed app are obtained. -static std::vector getUserIds() +// Gets app root directories of users. +// In order to reduce unnecessary operation, it is obtained only when an app root exists. +static std::vector getUserAppRoots() { DIR *dir; struct dirent* entry; struct passwd *p; - std::vector uids; + std::vector userAppRoots; dir = opendir("/home"); if (dir == nullptr) { - return uids; + return userAppRoots; } while ((entry = readdir(dir)) != nullptr) { if (entry->d_type == DT_DIR) { if ((p = getpwnam(entry->d_name)) != NULL) { - uids.push_back(p->pw_uid); + tzplatform_set_user(p->pw_uid); + const char* tzUserApp = tzplatform_getenv(TZ_USER_APP); + if (tzUserApp != NULL && exist(tzUserApp)) { + userAppRoots.push_back(tzUserApp); + } + tzplatform_reset_user(); } } } closedir(dir); - return uids; -} - -static std::string getAppDataPath(const std::string& pkgId, uid_t uid) -{ - std::string pDataFile; - - tzplatform_set_user(uid); - - const char* tzUserApp = tzplatform_getenv(TZ_USER_APP); - if (tzUserApp != NULL) { - pDataFile = std::string(tzUserApp) + "/" + pkgId + "/data/"; - } - - tzplatform_reset_user(); - - return pDataFile; + return userAppRoots; } profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data) @@ -73,16 +62,16 @@ profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data) return PROFILE_ERROR_INVALID_PARAMETER; } - std::vector uidList; + std::vector userAppRoots; if (user_data != NULL) { - uidList = *(std::vector*)user_data; + userAppRoots = *(std::vector*)user_data; } else { - uidList = getUserIds(); + userAppRoots = getUserAppRoots(); } - for (auto it = uidList.begin(); it != uidList.end(); ++it) { + for (auto it = userAppRoots.begin(); it != userAppRoots.end(); ++it) { // get data path from pkgid and uid - std::string dataPath = getAppDataPath(pkgId, *it); + std::string dataPath = *it + "/" + pkgId + "/data/"; if (!dataPath.empty() && exist(dataPath)) { std::string pDataFile = dataPath + PROFILE_BASENAME; @@ -132,8 +121,8 @@ static int removeAppProfileListCb(pkgmgrinfo_appinfo_h handle, void *user_data) void removeAllAppProfileData() { // To reduce repeated getUserIds calls, get uids here. - std::vector uidList = getUserIds(); - int ret = pkgmgrinfo_appinfo_get_installed_list(removeAppProfileListCb, &uidList); + std::vector userAppRoots = getUserAppRoots(); + int ret = pkgmgrinfo_appinfo_get_installed_list(removeAppProfileListCb, &userAppRoots); if (ret != PMINFO_R_OK) { _SERR("Failed to get installed list"); } -- 2.7.4 From 918168689f9987496b2f65fc1400212f85484579 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/MDE=20Lab=28SR=29/=EC=82=BC?= =?utf8?q?=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 13 Nov 2023 12:55:33 +0900 Subject: [PATCH 09/16] Refactoring the fallback graph of RID/TFM (#488) --- NativeLauncher/tool/multi_target_resolver.cc | 145 +++++++++------------------ 1 file changed, 48 insertions(+), 97 deletions(-) diff --git a/NativeLauncher/tool/multi_target_resolver.cc b/NativeLauncher/tool/multi_target_resolver.cc index 38416a6..674ef20 100644 --- a/NativeLauncher/tool/multi_target_resolver.cc +++ b/NativeLauncher/tool/multi_target_resolver.cc @@ -15,44 +15,30 @@ */ #include - #include -#include #include "log.h" #include "utils.h" #include "multi_target_resolver.h" -static const char* __TIZEN_RID_VERSION_KEY = "db/dotnet/tizen_rid_version"; -static const char* __TIZEN_TFM_SUPPORT_KEY = "db/dotnet/tizen_tfm_support"; -static const char* __DOTNET_RUNTIME_VERSION_KEY = "db/dotnet/runtime_version"; -static std::vector platform_version_list; +static const char* __TIZEN_RID_VERSION_KEY = "db/dotnet/tizen_rid_version"; //8.0.0:7.0.0:6.5.0:6.0.0:5.5.0:5.0.0:4.0.0 +static const char* __TIZEN_TFM_SUPPORT_KEY = "db/dotnet/tizen_tfm_support"; //net6.0-tizen8.0:net6.0-tizen:net6.0:tizen10.0:tizen90:tizen80:tizen70:tizen60:tizen50:tizen40 + /* Priority | RID | TFM ---------|---------------------|----------------------- 1 | tizen.X.Y.Z-{arch} | netX.Y-tizenX.Y ~ 6.5 2 | tizen.X.Y.Z | netX.Y-tizen 3 | tizen-{arch}, tizen | netX.Y -4 | linux-{arch}, linux | tizen90 ~ 40 +4 | linux-{arch}, linux | tizen10.0 ~ 40 5 | unix-{arch}, unix | net5.0 6 | any | netcoreapp3.1 ~ 1.0 7 | base | netstandard2.1 ~ 1.0 */ -static int convertStrVersionToInt(const std::string& version) -{ - int ret = 0; - for (unsigned int i = 0; i < version.length(); i++) { - if (std::isdigit(int(version[i]))) { - ret = ret * 10 + (int(version[i]) - '0'); - } - } - return ret; -} - // Guided by Appfw, vconf daemon does not run at mic stage. // So vconf_get_* api does not work normally. -// Therefore, it provides a second chance to read the file when vconf_get_* is null. +// Therefore, it is changed to manage as a file instead of using vconf API. // /usr/share/dotnet.tizen/lib/dotnet_resolving.info static std::string getDotnetResolvingInfo(const char* key) { @@ -64,31 +50,16 @@ static std::string getDotnetResolvingInfo(const char* key) return line.substr(line.rfind(" ") + 1); } } - _ERR("Faield to get vconf. %s is null", key); return ""; } static std::vector getRidFallbackGraph() { - std::string tizen_rid_version; - char* tizen_rid_version_value = vconf_get_str(__TIZEN_RID_VERSION_KEY); - if (!tizen_rid_version_value) { - _INFO("Faield to get vconf. So, Read the dotnet_resolving.info file"); - tizen_rid_version = getDotnetResolvingInfo(__TIZEN_RID_VERSION_KEY); - } else { - tizen_rid_version = std::string(tizen_rid_version_value); - free(tizen_rid_version_value); - } - + std::string tizen_rid_version = getDotnetResolvingInfo(__TIZEN_RID_VERSION_KEY); std::vector rid_version; std::vector RID_FALLBACK_GRAPH; splitPath(tizen_rid_version, rid_version); - std::reverse(std::begin(rid_version), std::end(rid_version)); for (auto& ridVersion : rid_version) { - //.NET 6.0 is supported from Tizen 6.5.0 - if (convertStrVersionToInt(ridVersion) >= 650) { - platform_version_list.push_back(ridVersion.substr(0, ridVersion.rfind('.'))); - } RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion + "-" + ARCHITECTURE_IDENTIFIER)); RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion)); } @@ -106,49 +77,21 @@ static std::vector getRidFallbackGraph() static std::vector getTfmFallbackGraph() { - std::string dotnet_runtime_version; - char* dotnet_runtime_version_value = vconf_get_str(__DOTNET_RUNTIME_VERSION_KEY); - if (!dotnet_runtime_version_value) { - _INFO("Faield to get vconf. So, Read the dotnet_resolving.info file"); - dotnet_runtime_version = getDotnetResolvingInfo(__DOTNET_RUNTIME_VERSION_KEY); - } else { - dotnet_runtime_version = std::string(dotnet_runtime_version_value); - free(dotnet_runtime_version_value); - } - - std::vector tfm_list; - std::vector dotnet_version; - splitPath(dotnet_runtime_version, dotnet_version); - for (auto& dotnetVersion : dotnet_version) { - for (auto& platformVersion : platform_version_list) { - tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen" + platformVersion)); - } - tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen")); - tfm_list.push_back(std::string("net" + dotnetVersion)); - } - - std::string tizen_tfm; - char* tizen_tfm_value = vconf_get_str(__TIZEN_TFM_SUPPORT_KEY); - if (!tizen_tfm_value) { - _INFO("Faield to get vconf. So, Read the dotnet_resolving.info file"); - tizen_tfm = getDotnetResolvingInfo(__TIZEN_TFM_SUPPORT_KEY); - } else { - tizen_tfm = std::string(tizen_tfm_value); - free(tizen_tfm_value); - } - splitPath(tizen_tfm, tfm_list); - tfm_list.push_back("net5.0"); + std::string tizen_tfm_support = getDotnetResolvingInfo(__TIZEN_TFM_SUPPORT_KEY); + std::vector TFM_FALLBACK_GRAPH; + splitPath(tizen_tfm_support, TFM_FALLBACK_GRAPH); + TFM_FALLBACK_GRAPH.push_back("net5.0"); std::vector netcoreapp_version = {"3.1", "3.0", "2.2", "2.1", "2.0", "1.1", "1.0"}; for (auto& version : netcoreapp_version) { - tfm_list.push_back(std::string("netcoreapp" + version)); + TFM_FALLBACK_GRAPH.push_back(std::string("netcoreapp" + version)); } std::vector netstandard_version = {"2.1", "2.0", "1.6", "1.5", "1.4", "1.3", "1.2", "1.1", "1.0"}; for (auto& version : netstandard_version) { - tfm_list.push_back(std::string("netstandard" + version)); + TFM_FALLBACK_GRAPH.push_back(std::string("netstandard" + version)); } - return tfm_list; + return TFM_FALLBACK_GRAPH; } // move all files under a certain directory to another directory @@ -189,37 +132,45 @@ int resolvePlatformSpecificFiles(const std::string& rootPath) // found best matched rid and tfm directory and copy all files to bin directory std::vector ridFallbackGraph = getRidFallbackGraph(); - for (auto& rid : ridFallbackGraph) { - std::string ridPath = concatPath(runtimesPath, rid); - if (isDirectory(ridPath)) { - _INFO("Found best matched rid (%s)", rid.c_str()); - // copy all files from /runtimes/${rid}/native to appBintPath if exist - std::string nativePath = concatPath(ridPath, "native"); - if (isDirectory(nativePath)) { - _INFO("Found best matched native path"); - if (!moveAllFilesTo(nativePath, appBinPath)) { - _ERR("Failed to copy files from native path"); - return -1; - } - } - - // found best matched tfm folder in the found rid folder - std::string libPath = concatPath(ridPath, "lib"); - std::vector tfmFallbackGraph = getTfmFallbackGraph(); - for (auto& tfm : tfmFallbackGraph) { - std::string tfmPath = concatPath(libPath, tfm); - if (isDirectory(tfmPath)) { - _INFO("Found best matched tfm (%s)", tfm .c_str()); - // copy all files from tfmPath to appBintPath - if (!moveAllFilesTo(tfmPath, appBinPath)) { - _ERR("Failed to copy files from tfm path"); - return -1; + try { + for (auto& rid : bf::recursive_directory_iterator(runtimesPath)) { + std::string ridPath = rid.path().string(); + if (bf::is_directory(ridPath) && strstr(ridPath.c_str(), ARCHITECTURE_IDENTIFIER) != NULL) { + for (auto& ridFG : ridFallbackGraph) { + if (!strcmp(ridPath.c_str(), ridFG.c_str())) { + std::string nativePath = concatPath(ridPath, "native"); + if (isDirectory(nativePath)) { + _INFO("Found best matched rid (%s)", ridFG.c_str()); + // copy all files from bin/runtimes/${rid}/native to appBintPath if exist + if (!moveAllFilesTo(nativePath, appBinPath)) { + _ERR("Failed to copy files from native path"); + return -1; + } + } + + // found best matched tfm folder in the found rid folder + std::string libPath = concatPath(ridPath, "lib"); + std::vector tfmFallbackGraph = getTfmFallbackGraph(); + for (auto& tfmFG : tfmFallbackGraph) { + std::string tfmPath = concatPath(libPath, tfmFG); + if (isDirectory(tfmPath)) { + _INFO("Found best matched tfm (%s)", tfmFG .c_str()); + // copy all files from bin/runtimes/${rid}/lib/${tfm} to appBintPath if exist + if (!moveAllFilesTo(tfmPath, appBinPath)) { + _ERR("Failed to copy files from tfm path"); + return -1; + } + break; + } + } + break; } - break; } + break; } - break; } + } catch (const bf::filesystem_error& error) { + _ERR("Failed to recursive directory: %s", error.what()); } // remove runtimes directory -- 2.7.4 From fe54a0874e638069e35c77e5545090c6d2c7ebf1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=B5=9C=EC=A2=85=ED=97=8C/MDE=20Lab=28SR=29/=EC=82=BC?= =?utf8?q?=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 13 Nov 2023 12:55:40 +0900 Subject: [PATCH 10/16] Add error log when using --rm-all-app-profile option (#493) --- NativeLauncher/tool/profile_common.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NativeLauncher/tool/profile_common.cc b/NativeLauncher/tool/profile_common.cc index 80ae73d..c06f5d0 100644 --- a/NativeLauncher/tool/profile_common.cc +++ b/NativeLauncher/tool/profile_common.cc @@ -74,7 +74,6 @@ profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data) std::string dataPath = *it + "/" + pkgId + "/data/"; if (!dataPath.empty() && exist(dataPath)) { std::string pDataFile = dataPath + PROFILE_BASENAME; - if (exist(pDataFile)) { if (!removeFile(pDataFile)) { _SERR("Failed to remove profile data file (%s).", pDataFile.c_str()); @@ -122,6 +121,10 @@ void removeAllAppProfileData() { // To reduce repeated getUserIds calls, get uids here. std::vector userAppRoots = getUserAppRoots(); + if (userAppRoots.empty()) { + _SERR("Failed to get app root directories of users"); + return; + } int ret = pkgmgrinfo_appinfo_get_installed_list(removeAppProfileListCb, &userAppRoots); if (ret != PMINFO_R_OK) { _SERR("Failed to get installed list"); -- 2.7.4 From 3aa6696f982518f9cc1c27d42592779648924952 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Tue, 28 Nov 2023 17:28:33 +0900 Subject: [PATCH 11/16] Bug-fix : native library resolving logic --- NativeLauncher/tool/multi_target_resolver.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NativeLauncher/tool/multi_target_resolver.cc b/NativeLauncher/tool/multi_target_resolver.cc index 674ef20..264dc6d 100644 --- a/NativeLauncher/tool/multi_target_resolver.cc +++ b/NativeLauncher/tool/multi_target_resolver.cc @@ -137,7 +137,7 @@ int resolvePlatformSpecificFiles(const std::string& rootPath) std::string ridPath = rid.path().string(); if (bf::is_directory(ridPath) && strstr(ridPath.c_str(), ARCHITECTURE_IDENTIFIER) != NULL) { for (auto& ridFG : ridFallbackGraph) { - if (!strcmp(ridPath.c_str(), ridFG.c_str())) { + if (!strcmp(getFileName(ridPath).c_str(), ridFG.c_str())) { std::string nativePath = concatPath(ridPath, "native"); if (isDirectory(nativePath)) { _INFO("Found best matched rid (%s)", ridFG.c_str()); -- 2.7.4 From d9e95c0546846567de6774e28ffc511a63abaf33 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Tue, 28 Nov 2023 20:42:47 +0900 Subject: [PATCH 12/16] Check library extension more To handle ".so.{number}" case, add more checking logic --- NativeLauncher/tool/tac_common.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NativeLauncher/tool/tac_common.cc b/NativeLauncher/tool/tac_common.cc index dcd5c1d..71623b3 100644 --- a/NativeLauncher/tool/tac_common.cc +++ b/NativeLauncher/tool/tac_common.cc @@ -439,7 +439,7 @@ std::vector getLibrariesInfo(const std::string& rootPath) return LibrariesInfo; auto convert = [&LibrariesInfo](const std::string& filepath, const std::string& filename) { - if (filename.find(".so", filename.size() - 3) != std::string::npos) { + if (filename.find(".so", filename.size() - 3) != std::string::npos || filepath.rfind(".so.") != std::string::npos) { std::string buffer = SHA256(filepath); LibrariesInfo.push_back(filepath + ":" + buffer); _INFO("Library : [%s] / SHA256 : [%s]", filename.c_str(), buffer.c_str()); -- 2.7.4 From 7a9e29f666e952f7ad36d67ea21bd5f3b6578981 Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Tue, 9 Apr 2024 18:14:17 +0900 Subject: [PATCH 13/16] Call DateTime.Now in the Candidate process To reduce the delay that occurs when DateTime.Now is first called, it is called in the candidate process. --- Managed/Tizen.Runtime/Preloader.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Managed/Tizen.Runtime/Preloader.cs b/Managed/Tizen.Runtime/Preloader.cs index 9ee11c7..65cd966 100644 --- a/Managed/Tizen.Runtime/Preloader.cs +++ b/Managed/Tizen.Runtime/Preloader.cs @@ -36,6 +36,8 @@ namespace Tizen.Runtime { _ = CultureInfo.CurrentCulture.CompareInfo.Compare("abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", CompareOptions.IgnoreCase); _ = "abc".ToUpper().ToLower(); + + Console.WriteLine($"Preload DateTime : {DateTime.Now}"); } public static void CoreclrPreload() -- 2.7.4 From 139561fcb89075cfa87082b6b02a51fade3d7f45 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=A1=B0=EC=9B=85=EC=84=9D/MDE=20Lab=28SR=29/=EC=82=BC?= =?utf8?q?=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Tue, 16 Apr 2024 10:21:00 +0900 Subject: [PATCH 14/16] Check all metadata for AOT in the installer plugin (#538) --- .../installer-plugin/prefer_dotnet_aot_plugin.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc index 91928a7..a2e3659 100644 --- a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc @@ -33,6 +33,11 @@ bool aotPluginInstalled = false; bool aotPluginFinished = false; +typedef struct metadata_s { + const char* key; + const char* value; +} metadata_t; + extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *appId, GList *list) { // Can be multiple apps in one package @@ -50,13 +55,20 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app } } - std::string metaValue = getMetadataValue(std::string(pkgId), AOT_METADATA_KEY); - if (metaValue.empty()) { - _ERR("Failed to get metadata from [%s]", pkgId); - return -1; + bool doAOT = false; + GList* iter = list; + while (iter) { + metadata_t* md = static_cast(iter->data); + if (strcmp(AOT_METADATA_KEY, md->key) == 0) { + if (strcmp(METADATA_VALUE_TRUE, md->value) == 0) { + doAOT = true; + } + break; + } + iter = g_list_next(iter); } - if (metaValue == METADATA_VALUE_TRUE) { + if (doAOT) { _DBG("Prefer dotnet application AOT set TRUE"); if (initNICommon() != NI_ERROR_NONE) { -- 2.7.4 From 7ba2c6848c2a92b5cafd2329f114dfe393c94ada Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=A1=B0=EC=9B=85=EC=84=9D/MDE=20Lab=28SR=29/=EC=82=BC?= =?utf8?q?=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Thu, 18 Jul 2024 08:41:16 +0900 Subject: [PATCH 15/16] Remove ni file before RO app AOTC (#570) * Remove ni file before RO app AOTC If AOTC is performed for a RO app, a native image file will be generated under /opt/usr/dotnet/apps. During OTN, pkg_upgrade may trigger AOTC again for the RO application. In this case, it is necessary to remove the previously created file and create a new one. * Remove RO app ni files under /opt/usr/dotnet/apps Recreated NI files of RO app, should be removed at FOTA/OTN --- NativeLauncher/tool/ni_common.cc | 4 ++++ packaging/715.dotnet_regen_app_ni.patch.sh | 3 +++ 2 files changed, 7 insertions(+) diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index ecfeee2..96247a8 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -1059,6 +1059,10 @@ ni_error_e createNIUnderPkgRoot(const std::string& pkgId, NIOption* opt) if (isReadOnlyArea(rootPath)) { opt->flags |= NI_FLAGS_APP_UNDER_RO_AREA; opt->flags |= NI_FLAGS_NO_PIPELINE; + std::string tmpPath = replaceAll(rootPath, getBaseName(rootPath), __READ_ONLY_APP_UPDATE_DIR); + if (!removeAll(tmpPath)){ + _SERR("Fail to remove RO App update path : %s", tmpPath.c_str()); + } _SERR("Only no-pipeline mode supported for RO app. Set no-pipeline option forcibly"); } else { opt->flags &= ~NI_FLAGS_APP_UNDER_RO_AREA; diff --git a/packaging/715.dotnet_regen_app_ni.patch.sh b/packaging/715.dotnet_regen_app_ni.patch.sh index c877058..12496a9 100644 --- a/packaging/715.dotnet_regen_app_ni.patch.sh +++ b/packaging/715.dotnet_regen_app_ni.patch.sh @@ -4,6 +4,9 @@ PATH=/usr/bin:/bin:/usr/sbin:/sbin +# remove application native image files of RO app +rm -rf /opt/usr/dotnet/apps/* + /usr/bin/dotnettool --tac-regen-all /usr/bin/dotnettool --ni-regen-all-app --skip-ro-app /usr/bin/dotnettool --resolve-all-app -- 2.7.4 From b1ca38576e49c0b66de7f52c3555860fc72c8f5c Mon Sep 17 00:00:00 2001 From: Woongsuk Cho Date: Thu, 18 Jul 2024 15:14:25 +0900 Subject: [PATCH 16/16] Skip AOT in plugin when pkg contains ni files --- NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc index a2e3659..68b3d91 100644 --- a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc @@ -68,6 +68,15 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app iter = g_list_next(iter); } + // if package contains native image, skip AOT. + std::string rootPath = getRootPath(pkgId); + if (!rootPath.empty()) { + if (exist(concatPath(rootPath, concatPath("bin", APP_NI_SUB_DIR)))) { + _INFO("Package already contains native images. Skip native image generation"); + doAOT = false; + } + } + if (doAOT) { _DBG("Prefer dotnet application AOT set TRUE"); -- 2.7.4