From dd3b8ac0801d854f4fa896453a4f8afb7de9f978 Mon Sep 17 00:00:00 2001 From: "j-h.choi" Date: Mon, 22 Jul 2019 13:20:13 +0900 Subject: [PATCH] Code refactoring --- NativeLauncher/CMakeLists.txt | 13 +- NativeLauncher/inc/launcher_env.h | 1 + NativeLauncher/inc/utils.h | 22 ++++ .../installer-plugin/prefer_dotnet_aot_plugin.cc | 2 +- .../installer-plugin/prefer_nuget_cache_plugin.cc | 118 ++++------------- NativeLauncher/installer-plugin/ui-application.cc | 103 --------------- NativeLauncher/tool/ni_common.cc | 19 ++- NativeLauncher/tool/tac_common.cc | 93 +++----------- NativeLauncher/tool/tpatool.cc | 28 ++-- NativeLauncher/util/path_manager.cc | 69 +++++----- NativeLauncher/util/plugin_manager.cc | 48 ++++--- NativeLauncher/util/utils.cc | 143 +++++++++++++++++++++ 12 files changed, 296 insertions(+), 363 deletions(-) delete mode 100644 NativeLauncher/installer-plugin/ui-application.cc diff --git a/NativeLauncher/CMakeLists.txt b/NativeLauncher/CMakeLists.txt index fbf61f5..4474d51 100644 --- a/NativeLauncher/CMakeLists.txt +++ b/NativeLauncher/CMakeLists.txt @@ -144,16 +144,6 @@ ADD_EXECUTABLE(${DOTNETTOOL} ${${DOTNETTOOL}_SOURCE_FILES}) SET_TARGET_PROPERTIES(${DOTNETTOOL} PROPERTIES COMPILE_FLAGS "-fPIE") TARGET_LINK_LIBRARIES(${DOTNETTOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON}) -#SET(INSTALLER_PLUGIN "ui-application") -#SET(${INSTALLER_PLUGIN}_SOURCE_FILES -# util/utils.cc -# installer-plugin/common.cc -# installer-plugin/ui-application.cc -#) -#ADD_LIBRARY(${INSTALLER_PLUGIN} SHARED ${${INSTALLER_PLUGIN}_SOURCE_FILES}) -#SET_TARGET_PROPERTIES(${INSTALLER_PLUGIN} PROPERTIES COMPILE_FLAGS "-fPIC") -#TARGET_LINK_LIBRARIES(${INSTALLER_PLUGIN} ${${PROJECT_NAME}_LDFLAGS}) - SET(PREFER_DOTNET_AOT_PLUGIN "prefer_dotnet_aot_plugin") SET(${PREFER_DOTNET_AOT_PLUGIN}_SOURCE_FILES installer-plugin/prefer_dotnet_aot_plugin.cc @@ -168,7 +158,7 @@ SET(${PREFER_NUGET_CACHE_PLUGIN}_SOURCE_FILES ) ADD_LIBRARY(${PREFER_NUGET_CACHE_PLUGIN} SHARED ${${PREFER_NUGET_CACHE_PLUGIN}_SOURCE_FILES}) SET_TARGET_PROPERTIES(${PREFER_NUGET_CACHE_PLUGIN} PROPERTIES COMPILE_FLAGS "-fPIC") -TARGET_LINK_LIBRARIES(${PREFER_NUGET_CACHE_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON}) +TARGET_LINK_LIBRARIES(${PREFER_NUGET_CACHE_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL}) CONFIGURE_FILE(dotnet-launcher.pc.in dotnet-launcher.pc @ONLY) @@ -178,7 +168,6 @@ INSTALL(TARGETS ${NI_COMMON} DESTINATION ${LIBDIR}) INSTALL(TARGETS ${NITOOL} DESTINATION ${BINDIR}) INSTALL(TARGETS ${TPATOOL} DESTINATION ${BINDIR}) INSTALL(TARGETS ${DOTNETTOOL} DESTINATION ${BINDIR}) -#INSTALL(TARGETS ${INSTALLER_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR}) INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR}) INSTALL(TARGETS ${PREFER_NUGET_CACHE_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR}) INSTALL(FILES dotnet.loader DESTINATION ${LOADERDIR}) diff --git a/NativeLauncher/inc/launcher_env.h b/NativeLauncher/inc/launcher_env.h index dca5a30..c295f2c 100644 --- a/NativeLauncher/inc/launcher_env.h +++ b/NativeLauncher/inc/launcher_env.h @@ -30,5 +30,6 @@ #define TIZEN_DOTNET_NUGET "Tizen.NET" #define TIZEN_DOTNET_SDK_NUGET "Tizen.NET.Sdk" #define NET_STANDARD_LIBRARY_NUGET "NETStandard.Library" +#define PLATFORM_TPA_CACHE "/usr/share/dotnet.tizen/lib/platform_tpa_cache" #endif //__LAUNCHER_ENV_H_ \ No newline at end of file diff --git a/NativeLauncher/inc/utils.h b/NativeLauncher/inc/utils.h index d0bb588..6baf0ad 100644 --- a/NativeLauncher/inc/utils.h +++ b/NativeLauncher/inc/utils.h @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -76,6 +77,15 @@ std::string absolutePath(const std::string& path); std::string baseName(const std::string& path); /** + * @brief replaces all matching substrings of the regular expression with a given replacement + * @param[in] original string + * @param[in] pattern to match + * @param[in] replacement string + * return the modified string + */ +std::string replaceAll(const std::string &str, const std::string &pattern, const std::string &replace); + +/** * @brief get root path * @param[in] package id * @param[out] root path @@ -207,4 +217,16 @@ bool removeFile(const bf::path& path); */ bool removeAll(const bf::path& path); +/** + * @brief .deps.json file parser + * @param[in] package id + * @param[in] root path + * @param[in] exec name + * @param[in] tpa list + * @param[in] dotnettool + * @param[in] sqlite3 + * return std::vector parser data + */ +std::vector depsJsonParser(std::string pkgId, std::string rootPath, std::string execName, std::string tpaList, bool isTool = false, sqlite3 *tac_db = NULL); + #endif /* __UTILS_H__ */ diff --git a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc index af9c323..470468e 100644 --- a/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc @@ -91,7 +91,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app std::string setNiPath = symPath.substr(0, symPath.rfind(".dll")) + ".ni.dll"; if (!bf::exists(setNiPath)) { bf::create_symlink(originNiPath, setNiPath); - _ERR("%s symbolic link file generated successfully.", setNiPath.c_str()); + _INFO("%s symbolic link file generated successfully.", setNiPath.c_str()); if (lchown(setNiPath.c_str(), uid, 0)) { _ERR("Failed to change owner of: %s", setNiPath.c_str()); return -1; diff --git a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc index 9879683..1d2f985 100644 --- a/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc +++ b/NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc @@ -15,9 +15,10 @@ */ #include "log.h" -#include "ni_common.h" #include "utils.h" #include "db_manager.h" +#include "path_manager.h" +#include "plugin_manager.h" #include #include @@ -28,7 +29,6 @@ #include #include #include -#include #ifdef LOG_TAG #undef LOG_TAG @@ -65,9 +65,12 @@ bool metadataCheck(GList *list) mdInfo = (Metadata*)tag->data; if (strcmp(mdInfo->key, TAC_METADATA_KEY) == 0 && strcmp(mdInfo->value, METADATA_VALUE) == 0) { _DBG("Prefer nuget cache set TRUE"); - NiCommonOption option = {std::string(), std::string(), std::string()}; - if (initNICommon(&option) < 0) { - _ERR("Fail to initialize NI Common"); + if (initializePluginManager("normal")) { + _ERR("Fail to initialize PluginManager"); + return false; + } + if (initializePathManager(std::string(), std::string(), std::string())) { + _ERR("Fail to initialize PathManger"); return false; } return true; @@ -114,93 +117,6 @@ bool appTypeCheck(std::string pkgId) return isDotnetAppType; } -void SHA256(std::string path, char outputBuffer[65]) -{ - FILE *file = fopen(path.c_str(), "rb"); - if (!file) { - return; - } - - unsigned char hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha256; - SHA256_Init(&sha256); - int bytesRead = 0; - const int bufSize = 32768; - char *buffer = (char*)malloc(bufSize); - if (!buffer) { - fclose(file); - return; - } - - while ((bytesRead = fread(buffer, 1, bufSize, file))) { - SHA256_Update(&sha256, buffer, bytesRead); - } - SHA256_Final(hash, &sha256); - for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { - sprintf(outputBuffer + (i * 2), "%02x", hash[i]); - } - outputBuffer[64] = 0; - - fclose(file); - free(buffer); -} - -int depsJsonParser() -{ - std::string deps_json_name = execName.substr(0, execName.rfind(".dll")) + ".deps.json"; - std::string deps_json_path = concatPath(rootPath, deps_json_name); - if (bf::exists(deps_json_path)) { - std::ifstream ifs(deps_json_path); - Json::CharReaderBuilder reader; - Json::Value root; - std::string error; - if (ifs.is_open()) { - if (!Json::parseFromStream(reader, ifs, &root, &error)) { - _ERR("Failed to parse of deps.json"); - ifs.close(); - return -1; - } - const Json::Value runtimeTargetName = root["runtimeTarget"]["name"]; - const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()]; - for (auto& nuget : nugetPackages.getMemberNames()) { - if (strstr(nuget.c_str(), TIZEN_DOTNET_NUGET) != NULL || - strstr(nuget.c_str(), TIZEN_DOTNET_SDK_NUGET) != NULL || - strstr(nuget.c_str(), (execName.substr(0, execName.find(".Tizen."))).c_str()) != NULL || - strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) != NULL) { - continue; - } else { - const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"]; - if (assemblies != Json::nullValue) { - const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"]; - bool isDependency = false; - for (auto& dependency : dependencies.getMemberNames()) { - if (strstr(dependency.c_str(), TIZEN_DOTNET_NUGET) != NULL || - strstr(dependency.c_str(), NET_STANDARD_LIBRARY_NUGET) != NULL) { - continue; - } else { - isDependency = true; - } - } - if (!isDependency) { - tacDB.push_back(nuget); - _INFO("Nuget package : %s", nuget.c_str()); - for (auto& assembly : assemblies.getMemberNames()) { - std::string assembly_name = assembly.substr(assembly.rfind('/') + 1); - char buffer[65] = {0}; - SHA256(concatPath(binPath, assembly_name), buffer); - nugetPackagesAssembliesSha.push_back(nuget + "/" + assembly_name + "/" + buffer); - _INFO("Assembly / SHA256 : %s / %s", assembly_name.c_str(), buffer); - } - } - } - } - } - ifs.close(); - } - } - return 0; -} - int createSymlink(std::string tac_version_dir, std::string np) { uid_t uid = 0; @@ -259,9 +175,14 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app binPath = concatPath(rootPath, "bin"); } if (metadataCheck(list)) { - if (depsJsonParser() < 0) { - return 0; + nugetPackagesAssembliesSha = depsJsonParser(pkgId, rootPath, execName, getTPA()); + for (auto& npAssemblySha : nugetPackagesAssembliesSha) { + std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind('/')); + std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/')); + tacDB.push_back(nuget_package); } + std::sort(tacDB.begin(), tacDB.end()); + tacDB.erase(unique(tacDB.begin(), tacDB.end()), tacDB.end()); } status = "install"; @@ -430,9 +351,14 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app _INFO("Skipped to parse of deps.json"); } else { if (metadataCheck(list)) { - if (depsJsonParser() < 0) { - return 0; + nugetPackagesAssembliesSha = depsJsonParser(pkgId, rootPath, execName, getTPA()); + for (auto& npAssemblySha : nugetPackagesAssembliesSha) { + std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind('/')); + std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/')); + tacDB.push_back(nuget_package); } + std::sort(tacDB.begin(), tacDB.end()); + tacDB.erase(unique(tacDB.begin(), tacDB.end()), tacDB.end()); } } diff --git a/NativeLauncher/installer-plugin/ui-application.cc b/NativeLauncher/installer-plugin/ui-application.cc deleted file mode 100644 index a4affd4..0000000 --- a/NativeLauncher/installer-plugin/ui-application.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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. - */ - -#include "ni_common.h" -#include "log.h" - -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "DOTNET_INSTALLER_PLUGIN" - -#include -#include -#include - -/* - * forked crossgen from installer is not working. - * because crossgen's capability is not enough. - * following command is needed - * - * setcap cap_dac_override=eip /opt/usr/share/dotnet.tizen/framework/crossgen - * - */ - -extern "C" int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char *pkgId) -{ - _INFO("pkg : %s", pkgId); - - uid_t uid = 0; - - if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { - _ERR("Failed to get UID"); - return 0; - } - - pkgmgrinfo_pkginfo_h handle; - int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId, uid, &handle); - if (ret != PMINFO_R_OK) { - _ERR("Failed to get pkg info"); - return 0; - } - - _INFO("success to get pkg info"); - - bool dotnetExist = false; - - auto dotnetAppCounter = [] (pkgmgrinfo_appinfo_h handle, void *userData) -> int { - char* appId = nullptr; - char* type = nullptr; - bool* dotnet = static_cast(userData); - - if (pkgmgrinfo_appinfo_get_appid(handle, &appId) != PMINFO_R_OK) { - _ERR("Failed to get app id"); - return 0; - } - - _INFO("App id : %s", appId); - - if (pkgmgrinfo_appinfo_get_apptype(handle, &type) != PMINFO_R_OK) { - _ERR("Failed to get app type : %s", appId); - return 0; - } - - _INFO("App type : %s", type); - - if (strcmp(type, "dotnet") == 0) - *dotnet = true; - - return 0; - }; - - if (pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, dotnetAppCounter, &dotnetExist, uid) != PMINFO_R_OK) { - _ERR("Failed to get list of app in pkg : %s", pkgId); - return -1; - } - - _INFO("Finish to get pkg list"); - - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - if (dotnetExist) { - _INFO("dotnet app is exist"); - return createNiUnderPkgRoot(pkgId) == 0 ? 0 : -1; - } - - return 0; -} -extern "C" int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char *pkgId) -{ - return PKGMGR_PARSER_PLUGIN_POST_INSTALL(pkgId); -} diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index 5c29aa9..ce2cff1 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -392,11 +392,11 @@ ni_error_e initNICommon(NiCommonOption* option) } if (initializePluginManager("normal")) { - fprintf(stderr, "Fail to initialize plugin manager\n"); + fprintf(stderr, "Fail to initialize PluginManager\n"); return NI_ERROR_UNKNOWN; } if (initializePathManager(option->runtimeDir, option->tizenFXDir, option->extraDirs)) { - fprintf(stderr, "Fail to initialize path manager\n"); + fprintf(stderr, "Fail to initialize PathManager\n"); return NI_ERROR_UNKNOWN; } @@ -454,6 +454,13 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R, appPaths.pop_back(); auto convert = [&appPaths, enableR2R, isAppNI](const std::string& path, const char* name) { + if (isAppNI) { + std::string assembly = path.substr(path.rfind('/') + 1); + if (strstr(replaceAll(__tpa, ".ni.dll", ".dll").c_str(), assembly.c_str()) != NULL) { + fprintf(stderr, "%s present in the TPA list skips generation of NI file.\n", path.c_str()); + return; + } + } if (!crossgen(path, appPaths.c_str(), enableR2R, isAppNI)) { waitInterval(); } @@ -514,7 +521,13 @@ ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& } return NI_ERROR_NONE; } else { - return crossgen(dllPath, paths, enableR2R, true); + std::string assembly = dllPath.substr(dllPath.rfind('/') + 1); + if (strstr(replaceAll(__tpa, ".ni.dll", ".dll").c_str(), assembly.c_str()) != NULL) { + fprintf(stderr, "%s present in the TPA list skips generation of NI file.\n", dllPath.c_str()); + return NI_ERROR_NONE; + } else { + return crossgen(dllPath, paths, enableR2R, true); + } } } diff --git a/NativeLauncher/tool/tac_common.cc b/NativeLauncher/tool/tac_common.cc index 2927857..7b3dfeb 100644 --- a/NativeLauncher/tool/tac_common.cc +++ b/NativeLauncher/tool/tac_common.cc @@ -24,6 +24,7 @@ #include "ni_common.h" #include "tac_common.h" #include "db_manager.h" +#include "path_manager.h" #ifdef LOG_TAG #undef LOG_TAG @@ -67,70 +68,6 @@ void cleanupDirectory() removeNuget.clear(); } -void depsJsonParser(std::string pkgId, std::string depsJsonPath, std::string execName, bool isRestore) -{ - std::ifstream ifs(depsJsonPath); - Json::CharReaderBuilder reader; - Json::Value root; - std::string error; - if (ifs.is_open()) { - if (!Json::parseFromStream(reader, ifs, &root, &error)) { - _INFO("Failed to parse of deps.json"); - ifs.close(); - return; - } - const Json::Value runtimeTargetName = root["runtimeTarget"]["name"]; - const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()]; - for (auto& nuget : nugetPackages.getMemberNames()) { - if (strstr(nuget.c_str(), TIZEN_DOTNET_NUGET) != NULL || - strstr(nuget.c_str(), TIZEN_DOTNET_SDK_NUGET) != NULL || - strstr(nuget.c_str(), (execName.substr(0, execName.find(".Tizen."))).c_str()) != NULL || - strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) != NULL) { - continue; - } else { - const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"]; - if (assemblies != Json::nullValue) { - const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"]; - bool isDependency = false; - for (auto& dependency : dependencies.getMemberNames()) { - if (strstr(dependency.c_str(), TIZEN_DOTNET_NUGET) != NULL || - strstr(dependency.c_str(), NET_STANDARD_LIBRARY_NUGET) != NULL) { - continue; - } else { - isDependency = true; - } - } - if (!isDependency) { - _INFO("PackageId : [%s] / Nuget package : [%s]", pkgId.c_str(), nuget.c_str()); - std::string name = nuget.substr(0, nuget.find('/')); - std::string version = nuget.substr(nuget.rfind('/') + 1); - std::string sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ - "VALUES ('" + pkgId + "', '" + nuget + "', '" + name + "', '" + version + "');"; - if (isRestore) { - if (tac_db) { - dbInsert(tac_db, TAC_APP_LIST_RESTORE_DB, sql); - restoreNuget.push_back(concatPath(__TAC_DIR, name)); - } - } else { - std::string nugetPath = concatPath(__TAC_DIR, nuget); - if (bf::exists(nugetPath)) { - for (auto& assembly : assemblies.getMemberNames()) { - std::string assemblyName = assembly.substr(assembly.rfind('/') + 1); - std::string originPath = concatPath(nugetPath, assemblyName); - if (bf::exists(originPath)) { - enableNuget.push_back(originPath); - } - } - } - } - } - } - } - } - ifs.close(); - } -} - // callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach" static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) { @@ -160,11 +97,7 @@ static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) } execName = std::string(exec).substr(std::string(exec).rfind('/') + 1); - std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json"; - std::string depsJsonPath = concatPath(rootPath, depsJsonName); - if (bf::exists(depsJsonPath)) { - depsJsonParser(pkgId, depsJsonPath, execName, true); - } + restoreNuget = depsJsonParser(pkgId, rootPath, execName, getTPA(), true, tac_db); return 0; } @@ -181,6 +114,11 @@ tac_error_e restoreTACDB() return TAC_ERROR_UNKNOWN; } + if (initializePathManager(std::string(), std::string(), std::string())) { + fprintf(stderr, "Fail to initialize PathManger"); + return TAC_ERROR_UNKNOWN; + } + tac_db = dbCreate(TAC_APP_LIST_RESTORE_DB); if (tac_db) { if (!dbOpen(tac_db, TAC_APP_LIST_RESTORE_DB)) { @@ -372,8 +310,8 @@ tac_error_e disableTACPackage(const std::string& pkgId) tac_error_e enableTACPackage(const std::string& pkgId) { - std::string pkgRoot; - if (getRootPath(pkgId, pkgRoot) < 0) { + std::string rootPath; + if (getRootPath(pkgId, rootPath) < 0) { return TAC_ERROR_INVALID_PACKAGE; } @@ -387,8 +325,13 @@ tac_error_e enableTACPackage(const std::string& pkgId) return TAC_ERROR_INVALID_PACKAGE; } + if (initializePathManager(std::string(), std::string(), std::string())) { + fprintf(stderr, "Fail to initialize PathManger"); + return TAC_ERROR_UNKNOWN; + } + if (!strcmp(metaValue.c_str(), "true")) { - std::string binDir = concatPath(pkgRoot, "bin"); + std::string binDir = concatPath(rootPath, "bin"); std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR); if (!bf::exists(tacDir)) { @@ -398,11 +341,7 @@ tac_error_e enableTACPackage(const std::string& pkgId) } updateAssemblyInfo(binDir.c_str(), tacDir.c_str()); - std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json"; - std::string depsJsonPath = concatPath(pkgRoot, depsJsonName); - if (bf::exists(depsJsonPath)) { - depsJsonParser(pkgId, depsJsonPath, execName, false); - } + enableNuget = depsJsonParser(pkgId, rootPath, execName, getTPA(), true); for (auto& originPath : enableNuget) { if (bf::exists(originPath)) { diff --git a/NativeLauncher/tool/tpatool.cc b/NativeLauncher/tool/tpatool.cc index fd0e2bb..195bfa4 100644 --- a/NativeLauncher/tool/tpatool.cc +++ b/NativeLauncher/tool/tpatool.cc @@ -19,27 +19,19 @@ #include #include "utils.h" - -const char* __RUNTIME_DIR = "/usr/share/dotnet.tizen/netcoreapp"; -const char* __TIZENFX_DIR = "/usr/share/dotnet.tizen/framework"; -const char* __TIZENFX_REF_DIR = "/usr/share/dotnet.tizen/framework/ref"; -const char* __PLATFORM_TPA_CACHE = "/usr/share/dotnet.tizen/lib/platform_tpa_cache"; +#include "path_manager.h" int main(int argc, char* argv[]) { - std::string tpaList; - std::vector tpaDir; - - tpaDir.push_back(__RUNTIME_DIR); - tpaDir.push_back(__TIZENFX_DIR); - tpaDir.push_back(__TIZENFX_REF_DIR); + if (initializePathManager(std::string(), std::string(), std::string())) { + fprintf(stderr, "Fail to initialize PathManager"); + return -1; + } - assembliesInDirectory(tpaDir, tpaList); + std::string tpaList = getTPA(); + std::ofstream out(PLATFORM_TPA_CACHE); + out << tpaList; + out.close(); - std::ofstream out(__PLATFORM_TPA_CACHE); - out << tpaList; - out.close(); - - return 0; + return 0; } - diff --git a/NativeLauncher/util/path_manager.cc b/NativeLauncher/util/path_manager.cc index daa8f34..b10372f 100644 --- a/NativeLauncher/util/path_manager.cc +++ b/NativeLauncher/util/path_manager.cc @@ -25,7 +25,6 @@ #include "log.h" static const char* __TIZEN_API_PATH_KEY = "db/dotnet/tizen_api_path"; -static const char* PLATFORM_TPA_CACHE = "/usr/share/dotnet.tizen/lib/platform_tpa_cache"; #define __XSTR(x) #x #define __STR(x) __XSTR(x) @@ -43,48 +42,53 @@ typedef struct DllPath { static DllPath* __dllPath = nullptr; static std::string __tpa; +bool initializedPathManager = false; // on success, return 0. otherwise return -1. int initializePathManager(const std::string& runtimeDir, const std::string& tizenFXDir, const std::string& extraDir) { - __dllPath = new DllPath(); - if (!__dllPath) { - _ERR("fail to allocate memory for dll path structure\n"); - return -1; - } + if (!initializedPathManager) { + __dllPath = new DllPath(); + if (!__dllPath) { + _ERR("fail to allocate memory for dll path structure\n"); + return -1; + } - if (!runtimeDir.empty()) { - __dllPath->runtime_dir = absolutePath(runtimeDir); - } else { - __dllPath->runtime_dir = absolutePath(__RUNTIME_DIR); - } + if (!runtimeDir.empty()) { + __dllPath->runtime_dir = absolutePath(runtimeDir); + } else { + __dllPath->runtime_dir = absolutePath(__RUNTIME_DIR); + } - if (!tizenFXDir.empty()) { - __dllPath->tizenfx_dir = absolutePath(tizenFXDir); - } else { - char* tmp = vconf_get_str(__TIZEN_API_PATH_KEY); - if (tmp) { - __dllPath->tizenfx_dir = std::string(tmp); - _DBG("Device API Directory is set by vconf : %s", tmp); + if (!tizenFXDir.empty()) { + __dllPath->tizenfx_dir = absolutePath(tizenFXDir); } else { - __dllPath->tizenfx_dir = absolutePath(__DEVICE_API_DIR); + char* tmp = vconf_get_str(__TIZEN_API_PATH_KEY); + if (tmp) { + __dllPath->tizenfx_dir = std::string(tmp); + _DBG("Device API Directory is set by vconf : %s", tmp); + } else { + __dllPath->tizenfx_dir = absolutePath(__DEVICE_API_DIR); + } } - } - __dllPath->tizenfx_ref_dir = __dllPath->tizenfx_dir + "/ref"; + __dllPath->tizenfx_ref_dir = __dllPath->tizenfx_dir + "/ref"; - // ":" seperated extra directories - if (!extraDir.empty()) { - splitPath(extraDir, __dllPath->extra_dirs); - } else { - char* extraPath = pluginGetDllPath(); - if (extraPath) { - splitPath(extraPath, __dllPath->extra_dirs); + // ":" seperated extra directories + if (!extraDir.empty()) { + splitPath(extraDir, __dllPath->extra_dirs); + } else { + char* extraPath = pluginGetDllPath(); + if (extraPath) { + splitPath(extraPath, __dllPath->extra_dirs); + } } - } - - _INFO("Path manager initialize success"); + _INFO("Path manager initialize success"); + } else { + _INFO("Skip to initialize Path manager"); + } + initializedPathManager = true; return 0; } @@ -94,6 +98,7 @@ void finalizePathManager() delete __dllPath; __dllPath = NULL; } + initializedPathManager = false; } std::string getRuntimeDir() @@ -121,7 +126,7 @@ static std::string getPlatformTPA() std::string platform_tpa; if (isFileExist(PLATFORM_TPA_CACHE)) { - _INFO("platform tpa cache found.\n"); + _INFO("platform tpa cache found."); std::ifstream cacheFile; cacheFile.open(PLATFORM_TPA_CACHE); std::getline(cacheFile, platform_tpa); diff --git a/NativeLauncher/util/plugin_manager.cc b/NativeLauncher/util/plugin_manager.cc index f8f008b..91529e4 100644 --- a/NativeLauncher/util/plugin_manager.cc +++ b/NativeLauncher/util/plugin_manager.cc @@ -21,34 +21,39 @@ static PluginFunc* __pluginFunc = NULL; static void* __pluginLib; +bool initializedPluginManager = false; int initializePluginManager(const char* mode) { - if (isFileExist(PLUGIN_PATH)) { - __pluginLib = dlopen(PLUGIN_PATH, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE); - if (__pluginLib) { - __pluginFunc = (PluginFunc*)calloc(sizeof(PluginFunc), 1); - if (!__pluginFunc) { - _ERR("fail to allocate memory for plugin function structure"); - return -1; + if (!initializedPluginManager) { + if (isFileExist(PLUGIN_PATH)) { + __pluginLib = dlopen(PLUGIN_PATH, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE); + if (__pluginLib) { + __pluginFunc = (PluginFunc*)calloc(sizeof(PluginFunc), 1); + if (!__pluginFunc) { + _ERR("fail to allocate memory for plugin function structure"); + return -1; + } + __pluginFunc->initialize = (plugin_initialize_ptr)dlsym(__pluginLib, "plugin_initialize"); + __pluginFunc->preload = (plugin_preload_ptr)dlsym(__pluginLib, "plugin_preload"); + __pluginFunc->has_log_control = (plugin_has_log_control_ptr)dlsym(__pluginLib, "plugin_has_log_control"); + __pluginFunc->set_app_info = (plugin_set_app_info_ptr)dlsym(__pluginLib, "plugin_set_app_info"); + __pluginFunc->set_coreclr_info = (plugin_set_coreclr_info_ptr)dlsym(__pluginLib, "plugin_set_coreclr_info"); + __pluginFunc->get_dll_path = (plugin_get_dll_path_ptr)dlsym(__pluginLib, "plugin_get_dll_path"); + __pluginFunc->get_tpa = (plugin_get_tpa_ptr)dlsym(__pluginLib, "plugin_get_tpa"); + __pluginFunc->before_execute = (plugin_before_execute_ptr)dlsym(__pluginLib, "plugin_before_execute"); + __pluginFunc->finalize = (plugin_finalize_ptr)dlsym(__pluginLib, "plugin_finalize"); } - __pluginFunc->initialize = (plugin_initialize_ptr)dlsym(__pluginLib, "plugin_initialize"); - __pluginFunc->preload = (plugin_preload_ptr)dlsym(__pluginLib, "plugin_preload"); - __pluginFunc->has_log_control = (plugin_has_log_control_ptr)dlsym(__pluginLib, "plugin_has_log_control"); - __pluginFunc->set_app_info = (plugin_set_app_info_ptr)dlsym(__pluginLib, "plugin_set_app_info"); - __pluginFunc->set_coreclr_info = (plugin_set_coreclr_info_ptr)dlsym(__pluginLib, "plugin_set_coreclr_info"); - __pluginFunc->get_dll_path = (plugin_get_dll_path_ptr)dlsym(__pluginLib, "plugin_get_dll_path"); - __pluginFunc->get_tpa = (plugin_get_tpa_ptr)dlsym(__pluginLib, "plugin_get_tpa"); - __pluginFunc->before_execute = (plugin_before_execute_ptr)dlsym(__pluginLib, "plugin_before_execute"); - __pluginFunc->finalize = (plugin_finalize_ptr)dlsym(__pluginLib, "plugin_finalize"); + + if (__pluginFunc->initialize) + __pluginFunc->initialize(mode); } - if (__pluginFunc->initialize) - __pluginFunc->initialize(mode); + _INFO("Plugin manager initialize success"); + } else { + _INFO("Skip to initialize Plugin manager"); } - - _INFO("Plugin manager initialize success"); - + initializedPluginManager = true; return 0; } @@ -64,6 +69,7 @@ void finalizePluginManager() dlclose(__pluginLib); __pluginLib = NULL; } + initializedPluginManager = false; } void pluginPreload() diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc index 92075bb..b265ae8 100644 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -36,6 +38,13 @@ #include "log.h" #include "utils.h" #include "path_manager.h" +#include "db_manager.h" + +#define __XSTR(x) #x +#define __STR(x) __XSTR(x) +static const char* __TAC_DIR = __STR(TAC_DIR); +#undef __STR +#undef __XSTR static bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length) { @@ -223,6 +232,20 @@ std::string baseName(const std::string& path) return path; } +std::string replaceAll(const std::string &str, const std::string &pattern, const std::string &replace) +{ + std::string result = str; + std::string::size_type pos = 0; + std::string::size_type offset = 0; + + while ((pos = result.find(pattern, offset)) != std::string::npos) { + result.replace(result.begin() + pos, result.begin() + pos + pattern.size(), replace); + offset = pos + replace.size(); + } + + return result; +} + bool isFileExist(const std::string& path) { struct stat sb; @@ -579,3 +602,123 @@ bool removeAll(const bf::path& path) { } return true; } + +static void SHA256(std::string path, char outputBuffer[65]) +{ + FILE *file = fopen(path.c_str(), "rb"); + if (!file) { + return; + } + + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha256; + SHA256_Init(&sha256); + int bytesRead = 0; + const int bufSize = 32768; + char *buffer = (char*)malloc(bufSize); + if (!buffer) { + fclose(file); + return; + } + + while ((bytesRead = fread(buffer, 1, bufSize, file))) { + SHA256_Update(&sha256, buffer, bytesRead); + } + SHA256_Final(hash, &sha256); + for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { + sprintf(outputBuffer + (i * 2), "%02x", hash[i]); + } + outputBuffer[64] = 0; + + fclose(file); + free(buffer); +} + +std::vector depsJsonParser(std::string pkgId, std::string rootPath, std::string execName, std::string tpaList, bool isTool, sqlite3 *tac_db) +{ + std::vector parserData; + std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json"; + std::string depsJsonPath = concatPath(rootPath, depsJsonName); + std::string binPath = concatPath(rootPath, "bin"); + if (bf::exists(depsJsonPath)) { + std::ifstream ifs(depsJsonPath); + Json::CharReaderBuilder reader; + Json::Value root; + std::string error; + if (ifs.is_open()) { + if (!Json::parseFromStream(reader, ifs, &root, &error)) { + _ERR("Failed to parse of deps.json"); + ifs.close(); + return parserData; + } + const Json::Value runtimeTargetName = root["runtimeTarget"]["name"]; + const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()]; + for (auto& nuget : nugetPackages.getMemberNames()) { + if (strstr(nuget.c_str(), TIZEN_DOTNET_NUGET) != NULL || + strstr(nuget.c_str(), TIZEN_DOTNET_SDK_NUGET) != NULL || + strstr(nuget.c_str(), (execName.substr(0, execName.find(".Tizen."))).c_str()) != NULL || + strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) != NULL) { + continue; + } else { + const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"]; + if (assemblies != Json::nullValue) { + const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"]; + bool isDependency = false; + for (auto& dependency : dependencies.getMemberNames()) { + if (strstr(dependency.c_str(), TIZEN_DOTNET_NUGET) != NULL || + strstr(dependency.c_str(), NET_STANDARD_LIBRARY_NUGET) != NULL) { + continue; + } else { + isDependency = true; + } + } + if (!isDependency) { + bool isExistTpaAssembly = false; + for (auto& assembly : assemblies.getMemberNames()) { + std::string assembly_name = assembly.substr(assembly.rfind('/') + 1); + if (strstr(replaceAll(tpaList, ".ni.dll", ".dll").c_str(), assembly_name.c_str()) != NULL) { + isExistTpaAssembly = true; + break; + } + } + if (!isExistTpaAssembly) { + _INFO("Nuget : %s", nuget.c_str()); + if (isTool) { + if (tac_db) { + std::string name = nuget.substr(0, nuget.find('/')); + std::string version = nuget.substr(nuget.rfind('/') + 1); + std::string sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ + "VALUES ('" + pkgId + "', '" + nuget + "', '" + name + "', '" + version + "');"; + dbInsert(tac_db, TAC_APP_LIST_RESTORE_DB, sql); + parserData.push_back(concatPath(__TAC_DIR, name)); + } else { + std::string nugetPath = concatPath(__TAC_DIR, nuget); + if (bf::exists(nugetPath)) { + for (auto& assembly : assemblies.getMemberNames()) { + std::string assemblyName = assembly.substr(assembly.rfind('/') + 1); + std::string originPath = concatPath(nugetPath, assemblyName); + if (bf::exists(originPath)) { + parserData.push_back(originPath); + } + } + } + } + } else { + for (auto& assembly : assemblies.getMemberNames()) { + std::string assembly_name = assembly.substr(assembly.rfind('/') + 1); + char buffer[65] = {0}; + SHA256(concatPath(binPath, assembly_name), buffer); + parserData.push_back(nuget + "/" + assembly_name + "/" + buffer); + _INFO("Assembly / SHA256 : %s / %s", assembly_name.c_str(), buffer); + } + } + } + } + } + } + } + ifs.close(); + } + } + return parserData; +} \ No newline at end of file -- 2.7.4