[Refactoring] Improve SAM score through DC and GV improvement
[platform/core/dotnet/launcher.git] / NativeLauncher / tool / tac_common.cc
index 0cce217..f7fb9ef 100644 (file)
@@ -23,7 +23,6 @@
 #include "utils.h"
 #include "tac_common.h"
 #include "db_manager.h"
-#include "path_manager.h"
 
 #ifdef  LOG_TAG
 #undef  LOG_TAG
 
 #define __XSTR(x) #x
 #define __STR(x) __XSTR(x)
-static const char* __TAC_DIR = __STR(TAC_DIR);
+static const char* __DOTNET_DIR = __STR(DOTNET_DIR);
+static const char* __READ_ONLY_APP_UPDATE_DIR = __STR(READ_ONLY_APP_UPDATE_DIR);
 #undef __STR
 #undef __XSTR
 
 static sqlite3 *tac_db = NULL;
-std::vector<std::string> restore_nuget;
+static sqlite3 *tlc_db = NULL;
+static std::vector<std::string> restore_nuget;
+static std::vector<std::string> restore_library;
 
 static void cleanupDirectory()
 {
        std::vector<std::string> removeNuget;
        try {
-               for (auto& nuget : bf::recursive_directory_iterator(__TAC_DIR)) {
-                       bool isExist = false;
+               for (auto& nuget : bf::recursive_directory_iterator(__DOTNET_DIR)) {
                        std::string nugetPath = nuget.path().string();
+                       if (!bf::is_directory(nugetPath) ||
+                               nugetPath.find(TLC_LIBRARIES_DIR) != std::string::npos ||
+                               nugetPath.find(__READ_ONLY_APP_UPDATE_DIR) != std::string::npos) {
+                               continue;
+                       }
+
+                       bool isExist = false;
                        for (auto& restore : restore_nuget) {
-                               if (!bf::is_directory(nugetPath)) {
-                                       isExist = true;
-                               }
-                               if (!strcmp(nugetPath.c_str(), restore.c_str()) ||
-                                       !strcmp(nugetPath.c_str(), restore.substr(0, restore.rfind('/')).c_str())) {
+                               if (nugetPath == restore || nugetPath == getBaseName(restore)) {
                                        isExist = true;
                                        break;
                                }
@@ -63,54 +67,52 @@ static void cleanupDirectory()
 
                for (auto& rm : removeNuget) {
                        if (!removeAll(rm)) {
-                               fprintf(stderr, "Failed to remove of %s\n", rm.c_str());
+                               _SERR("Failed to remove of %s", rm.c_str());
                        }
                }
                removeNuget.clear();
        } catch (const bf::filesystem_error& error) {
-               fprintf(stderr, "Failed to recursive directory: %s\n", error.what());
+               _SERR("Failed to recursive directory: %s", error.what());
                return;
        }
 }
 
 // callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
-static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
+static int tac_restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
 {
        char *pkgId = NULL;
        char *root = NULL;
        char *exec = NULL;
-       std::string rootPath;
-       std::string execName;
 
        int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
        if (ret != PMINFO_R_OK) {
-               fprintf(stderr, "Failed to get pkgid\n");
+               _SERR("Failed to get pkgid");
                return -1;
        }
 
-       enableTACPackage(std::string(pkgId));
-
        ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
        if (ret != PMINFO_R_OK) {
-               fprintf(stderr, "Failed to get root path\n");
+               _SERR("Failed to get root path");
                return -1;
        }
-       rootPath = root;
+       std::string rootPath = std::string(root);
 
        ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
        if (ret != PMINFO_R_OK) {
-               fprintf(stderr, "Failed to get exec name\n");
+               _SERR("Failed to get exec name");
                return -1;
        }
-       execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
+       std::string execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
+
+       enableTACPackage(std::string(pkgId));
 
        std::vector<std::string> parserData;
        std::string binDir = concatPath(rootPath, "bin");
        std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-       for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) {
+       for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
                std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':'));
                std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1);
-               if (bf::exists(tacDir) && bf::exists(concatPath(tacDir, assemblyName))) {
+               if (exist(tacDir) && exist(concatPath(tacDir, assemblyName))) {
                        parserData.push_back(nugetPackage);
                }
        }
@@ -121,39 +123,38 @@ static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
                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 ('" + std::string(pkgId) + "', '" + nuget + "', '" + name + "', '" + version + "');";
-                       dbInsert(tac_db, TAC_APP_LIST_RESTORE_DB, sql);
-                       restore_nuget.push_back(concatPath(__TAC_DIR, nuget));
+                       char *sql = sqlite3_mprintf(
+                               "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
+                               "VALUES (%Q, %Q, %Q, %Q);",     pkgId, nuget.c_str(), name.c_str(), version.c_str());
+                       insertDB(tac_db, sql);
+                       restore_nuget.push_back(concatPath(__DOTNET_DIR, nuget));
+                       sqlite3_free(sql);
                }
        }
        parserData.clear();
+
        return 0;
 }
 
-tac_error_e restoreTACDB()
+tac_error_e tac_restoreDB()
 {
        if (!removeFile(TAC_APP_LIST_RESTORE_DB)) {
-               fprintf(stderr, "Failed to remove of %s\n", TAC_APP_LIST_RESTORE_DB);
+               _SERR("Failed to remove of %s", TAC_APP_LIST_RESTORE_DB);
                return TAC_ERROR_UNKNOWN;
        }
 
        std::string dbRestoreJournal = TAC_APP_LIST_RESTORE_DB + std::string("-journal");
        if (!removeFile(dbRestoreJournal)) {
-               fprintf(stderr, "Failed to remove of %s\n", dbRestoreJournal.c_str());
+               _SERR("Failed to remove of %s", dbRestoreJournal.c_str());
                return TAC_ERROR_UNKNOWN;
        }
 
-       if (initializePathManager(std::string(), std::string(), std::string())) {
-               fprintf(stderr, "Fail to initialize PathManger\n");
-               return TAC_ERROR_UNKNOWN;
-       }
-
-       tac_db = dbCreate(TAC_APP_LIST_RESTORE_DB);
+       tac_db = createDB(TAC_APP_LIST_RESTORE_DB, CREATE_TAC_DB_TABLE);
        if (!tac_db) {
-               fprintf(stderr, "Sqlite create error\n");
+               _SERR("Sqlite create error");
                return TAC_ERROR_UNKNOWN;
        }
+       sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
 
        pkgmgrinfo_appinfo_metadata_filter_h handle;
        int ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
@@ -161,238 +162,206 @@ tac_error_e restoreTACDB()
                return TAC_ERROR_UNKNOWN;
        }
 
-       ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, TAC_METADATA_KEY, METADATA_VALUE);
+       ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, TAC_METADATA_KEY, METADATA_VALUE_TRUE);
        if (ret != PMINFO_R_OK) {
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
                return TAC_ERROR_UNKNOWN;
        }
 
-       ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, restoreDBCb, NULL);
-       if (ret != PMINFO_R_OK) {
-               fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
+       ret = pkgmgrMDFilterForeach(handle, tac_restoreDBCb, NULL);
+       if (ret != 0) {
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
                return TAC_ERROR_UNKNOWN;
        }
-       fprintf(stderr, "Success pkgmgrinfo_appinfo_metadata_filter_foreach\n");
 
        pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
 
        if (tac_db) {
-               dbClose(tac_db);
+               closeDB(tac_db);
                tac_db = NULL;
        }
 
-       uid_t g_uid = 301; // app_fw
-       gid_t g_gid = 301; // app_fw
-
        if (!copyFile(TAC_APP_LIST_RESTORE_DB, TAC_APP_LIST_DB)) {
-               fprintf(stderr, "Failed to copy of %s\n", TAC_APP_LIST_DB);
+               _SERR("Failed to copy of %s", TAC_APP_LIST_DB);
                return TAC_ERROR_UNKNOWN;
        }
        if (!removeFile(TAC_APP_LIST_RESTORE_DB)) {
-               fprintf(stderr, "Failed to remove of %s\n", TAC_APP_LIST_RESTORE_DB);
+               _SERR("Failed to remove of %s", TAC_APP_LIST_RESTORE_DB);
                return TAC_ERROR_UNKNOWN;
        }
-       if (chown(TAC_APP_LIST_DB, g_uid, g_gid) == -1) {
-               fprintf(stderr, "Failed to change owner and group name\n");
-       }
 
        std::string dbJournal = TAC_APP_LIST_DB + std::string("-journal");
        if (!copyFile(dbRestoreJournal, dbJournal)) {
-               fprintf(stderr, "Failed to copy of %s\n", dbJournal.c_str());
+               _SERR("Failed to copy of %s", dbJournal.c_str());
                return TAC_ERROR_UNKNOWN;
        }
        if (!removeFile(dbRestoreJournal)) {
-               fprintf(stderr, "Failed to remove of %s\n", dbRestoreJournal.c_str());
+               _SERR("Failed to remove of %s", dbRestoreJournal.c_str());
                return TAC_ERROR_UNKNOWN;
        }
-       if (chown(dbJournal.c_str(), g_uid, g_gid) == -1) {
-               fprintf(stderr, "Failed to change owner and group name\n");
-       }
 
        cleanupDirectory();
 
        return TAC_ERROR_NONE;
 }
 
-tac_error_e resetTACPackage(const std::string& pkgId)
-{
-       std::string pkgRoot;
-       if (getRootPath(pkgId, pkgRoot) < 0) {
-               return TAC_ERROR_INVALID_PACKAGE;
-       }
-
-       std::vector<std::string> tacNativeImage;
-       std::string binDir = concatPath(pkgRoot, "bin");
-       std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-       if (bf::exists(tacDir)) {
-               try {
-                       for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
-                               std::string symPath = symlinkAssembly.path().string();
-                               if (bf::is_symlink(symPath)) {
-                                       if (isNativeImage(symPath)) {
-                                               tacNativeImage.push_back(symPath);
-                                       }
-                               }
-                       }
-                       for (auto& path : tacNativeImage) {
-                               if (!removeFile(path)) {
-                                       fprintf(stderr, "Failed to remove of %s\n", path.c_str());
-                                       return TAC_ERROR_UNKNOWN;
-                               }
-                       }
-                       tacNativeImage.clear();
-               } catch (const bf::filesystem_error& error) {
-                       fprintf(stderr, "Failed to recursive directory: %s\n", error.what());
-                       return TAC_ERROR_UNKNOWN;
-               }
-       }
-       return TAC_ERROR_NONE;
-}
-
 tac_error_e disableTACPackage(const std::string& pkgId)
 {
-       std::string pkgRoot;
-       if (getRootPath(pkgId, pkgRoot) < 0) {
+       std::string rootPath = getRootPath(pkgId);
+       if (rootPath.empty()) {
+               _SERR("Failed to get root path from [%s]", pkgId.c_str());
                return TAC_ERROR_INVALID_PACKAGE;
        }
 
-       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)) {
+       if (exist(tacDir)) {
                try {
                        for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
                                std::string symPath = symlinkAssembly.path().string();
                                std::string fileName = symlinkAssembly.path().filename().string();
-                               if (bf::is_symlink(symPath)) {
+                               if (isSymlinkFile(symPath)) {
                                        std::string originPath = bf::read_symlink(symPath).string();
                                        if (!isNativeImage(symPath)) {
                                                std::string dllPath = concatPath(binDir, fileName);
                                                if (!copyFile(originPath, dllPath)) {
-                                                       fprintf(stderr, "Failed to copy of %s\n", dllPath.c_str());
+                                                       _SERR("Failed to copy of %s", dllPath.c_str());
                                                        return TAC_ERROR_UNKNOWN;
                                                }
-                                               updateAssemblyInfo(binDir.c_str(), concatPath(binDir, fileName).c_str());
+                                               copySmackAndOwnership(binDir.c_str(), concatPath(binDir, fileName).c_str());
                                        } else {
                                                std::string niPath = concatPath(binNIDir, fileName);
                                                if (!copyFile(originPath, niPath)) {
-                                                       fprintf(stderr, "Failed to copy of %s\n", niPath.c_str());
+                                                       _SERR("Failed to copy of %s", niPath.c_str());
                                                        return TAC_ERROR_UNKNOWN;
                                                }
-                                               updateAssemblyInfo(binDir.c_str(), niPath.c_str());
+                                               copySmackAndOwnership(binDir.c_str(), niPath.c_str());
                                        }
                                }
                        }
                        if (!removeAll(tacDir)) {
-                               fprintf(stderr, "Failed to remove of %s\n", tacDir.c_str());
+                               _SERR("Failed to remove of %s", tacDir.c_str());
                                return TAC_ERROR_UNKNOWN;
                        }
                } catch (const bf::filesystem_error& error) {
-                       fprintf(stderr, "Failed to recursive directory: %s\n", error.what());
+                       _SERR("Failed to recursive directory: %s", error.what());
                        return TAC_ERROR_UNKNOWN;
                }
        }
        return TAC_ERROR_NONE;
 }
 
+static tac_error_e createSymlinkFile(const std::string& tacDir, const std::string& binDir, const std::string& from, const std::string& to)
+{
+       bs::error_code error;
+       bf::create_symlink(from, concatPath(tacDir, to), error);
+       if (error) {
+               _SERR("Failed to create symlink %s file", concatPath(tacDir, to).c_str());
+               return TAC_ERROR_UNKNOWN;
+       }
+       _SOUT("%s symbolic link file generated successfully.", concatPath(tacDir, to).c_str());
+       copySmackAndOwnership(tacDir.c_str(), concatPath(tacDir, to).c_str(), true);
+
+       if (!removeFile(concatPath(binDir, to))) {
+               _SERR("Failed to remove of %s", concatPath(binDir, to).c_str());
+               return TAC_ERROR_UNKNOWN;
+       }
+       return TAC_ERROR_NONE;
+}
+
 tac_error_e enableTACPackage(const std::string& pkgId)
 {
-       std::string rootPath;
-       if (getRootPath(pkgId, rootPath) < 0) {
+       std::string rootPath = getRootPath(pkgId);
+       if (rootPath.empty()) {
+               _SERR("Failed to get root path from [%s]", pkgId.c_str());
                return TAC_ERROR_INVALID_PACKAGE;
        }
 
-       std::string execName;
-       if (getExecName(pkgId, execName) < 0) {
+       std::string binDir = concatPath(rootPath, "bin");
+       if (exist(concatPath(binDir, PRE_COMPILED_PACKAGE_FILE))) {
+               _INFO("The %s is a Pre-Compiled package. So, skip the TAC", pkgId.c_str());
+               return TAC_ERROR_NONE;
+       }
+
+       std::string execName = getExecName(pkgId);
+       if (execName.empty()) {
+               _SERR("Failed to get exec name from [%s]", pkgId.c_str());
                return TAC_ERROR_INVALID_PACKAGE;
        }
 
-       std::string metaValue;
-       if (getMetadataValue(pkgId, TAC_METADATA_KEY, metaValue) < 0) {
+       std::string metaValue = getMetadataValue(pkgId, TAC_METADATA_KEY);
+       if (metaValue.empty()) {
+               _SERR("Failed to get metadata from [%s]", pkgId.c_str());
                return TAC_ERROR_INVALID_PACKAGE;
        }
 
-       if (initializePathManager(std::string(), std::string(), std::string())) {
-               fprintf(stderr, "Fail to initialize PathManger\n");
+       if (strcmp(metaValue.c_str(), METADATA_VALUE_TRUE)) {
+               _SERR("The metadata key is missing or the metadata value is false of [%s]", pkgId.c_str());
+               return TAC_ERROR_NONE;
+       }
+
+       std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
+       std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR);
+       if (exist(tacDir)) {
+               return TAC_ERROR_NONE;
+       }
+
+       if (!createDir(tacDir)) {
+               _SERR("Cannot create directory: %s", tacDir.c_str());
                return TAC_ERROR_UNKNOWN;
        }
+       copySmackAndOwnership(binDir.c_str(), tacDir.c_str());
 
-       if (!strcmp(metaValue.c_str(), "true")) {
-               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)) {
-                       if (!createDir(tacDir)) {
-                               fprintf(stderr, "Cannot create directory: %s\n", tacDir.c_str());
-                               return TAC_ERROR_UNKNOWN;
-                       }
-                       updateAssemblyInfo(binDir.c_str(), tacDir.c_str());
-
-                       std::vector<std::string> enableNuget;
-                       for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) {
-                               std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':'));
-                               std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1);
-                               std::string nugetPath = concatPath(__TAC_DIR, nugetPackage);
-                               if (bf::exists(nugetPath)) {
-                                       std::string originPath = concatPath(nugetPath, assemblyName);
-                                       if (bf::exists(originPath)) {
-                                               enableNuget.push_back(originPath);
-                                       }
-                               }
+       std::vector<std::string> enableNuget;
+       for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
+               std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':'));
+               std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1);
+               std::string nugetPath = concatPath(__DOTNET_DIR, nugetPackage);
+               if (exist(nugetPath)) {
+                       std::string originPath = concatPath(nugetPath, assemblyName);
+                       if (exist(originPath)) {
+                               enableNuget.push_back(originPath);
                        }
+               }
+       }
 
-                       for (auto& originPath : enableNuget) {
-                               if (bf::exists(originPath)) {
-                                       std::string fileName = originPath.substr(originPath.rfind('/') + 1);
-                                       std::string NIFileName = fileName.substr(0, fileName.rfind(".dll")) + ".ni.dll";
-                                       if (bf::exists(binNIDir)) {
-                                               std::string originNIPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
-                                               if (bf::exists(originNIPath)) {
-                                                       bf::create_symlink(originNIPath, concatPath(tacDir, NIFileName));
-                                                       fprintf(stderr, "%s symbolic link file generated successfully.\n", concatPath(tacDir, NIFileName).c_str());
-                                                       updateAssemblyInfo(tacDir.c_str(), concatPath(tacDir, NIFileName).c_str(), true);
-
-                                                       if (!removeFile(concatPath(binNIDir, NIFileName))) {
-                                                               fprintf(stderr, "Failed to remove of %s\n", concatPath(binNIDir, NIFileName).c_str());
-                                                               return TAC_ERROR_UNKNOWN;
-                                                       }
-                                               }
-                                       }
-                                       bf::create_symlink(originPath, concatPath(tacDir, fileName));
-                                       fprintf(stderr, "%s symbolic link file generated successfully.\n", concatPath(tacDir, fileName).c_str());
-                                       updateAssemblyInfo(tacDir.c_str(), concatPath(tacDir, fileName).c_str(), true);
+       if (enableNuget.empty()) {
+               if (!removeAll(tacDir)) {
+                       _SERR("Failed to remove of %s", tacDir.c_str());
+               }
+               return TAC_ERROR_NONE;
+       }
 
-                                       if (!removeFile(concatPath(binDir, fileName))) {
-                                               fprintf(stderr, "Failed to remove of %s\n", concatPath(binDir, fileName).c_str());
+       for (auto& originPath : enableNuget) {
+               if (exist(originPath)) {
+                       std::string fileName = originPath.substr(originPath.rfind('/') + 1);
+                       if (exist(binNIDir)) {
+                               std::string originNIPath = changeExtension(originPath, "dll", "ni.dll");
+                               if (exist(originNIPath)) {
+                                       if (createSymlinkFile(tacDir, binNIDir, originNIPath, changeExtension(fileName, "dll", "ni.dll")) != TAC_ERROR_NONE) {
                                                return TAC_ERROR_UNKNOWN;
                                        }
                                }
                        }
-                       if (enableNuget.empty()) {
-                               if (!removeAll(tacDir)) {
-                                       fprintf(stderr, "Failed to remove of %s\n", tacDir.c_str());
-                               }
+                       if (createSymlinkFile(tacDir, binDir, originPath, fileName) != TAC_ERROR_NONE) {
+                               return TAC_ERROR_UNKNOWN;
                        }
-                       enableNuget.clear();
                }
-       } else {
-               fprintf(stderr, "The metadata key is missing or the metadata value is false of [%s]\n", pkgId.c_str());
        }
+       enableNuget.clear();
+
        return TAC_ERROR_NONE;
 }
 
 //Parser the .deps.json file to get nuget information.
-std::vector<std::string> depsJsonParser(std::string rootPath, std::string execName, std::string tpaList)
+std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::string& execName)
 {
-       std::vector<std::string> tpaAssemblies;
-       splitPath(tpaList, tpaAssemblies);
-
        std::vector<std::string> parserData;
-       std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json";
+       std::string depsJsonName = changeExtension(execName, "dll", "deps.json");
        std::string depsJsonPath = concatPath(rootPath, depsJsonName);
        try {
-               if (bf::exists(depsJsonPath)) {
+               if (exist(depsJsonPath)) {
                        std::ifstream ifs(depsJsonPath);
                        Json::CharReaderBuilder reader;
                        Json::Value root;
@@ -401,24 +370,10 @@ std::vector<std::string> depsJsonParser(std::string rootPath, std::string execNa
                                if (!Json::parseFromStream(reader, ifs, &root, &error)) {
                                        _ERR("Failed to parse of deps.json");
                                        ifs.close();
-                                       tpaAssemblies.clear();
                                        return parserData;
                                }
                                const Json::Value runtimeTargetName = root["runtimeTarget"]["name"];
                                const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()];
-                               std::vector<std::string> appDependencies;
-                               for (auto& nuget : nugetPackages.getMemberNames()) {
-                                       if (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) {
-                                               const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"];
-                                               if (assemblies != Json::nullValue) {
-                                                       const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"];
-                                                       for (auto& dependency : dependencies.getMemberNames()) {
-                                                               appDependencies.push_back(dependency);
-                                                       }
-                                               }
-                                       }
-                               }
                                for (auto& nuget : nugetPackages.getMemberNames()) {
                                        //Skip the nuget package related to Tizen
                                        if (strstr(nuget.c_str(), TIZEN_DOTNET_NUGET) == NULL &&
@@ -427,55 +382,156 @@ std::vector<std::string> depsJsonParser(std::string rootPath, std::string execNa
                                                strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) == NULL) {
                                                const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"];
                                                if (assemblies != Json::nullValue) {
-                                                       const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"];
-                                                       bool hasDependency = false;
-                                                       for (auto& dependency : dependencies.getMemberNames()) {
-                                                               //Skip the nugget package that is dependent on another nuget package
-                                                               if (strstr(dependency.c_str(), TIZEN_DOTNET_NUGET) == NULL &&
-                                                                       strstr(dependency.c_str(), NET_STANDARD_LIBRARY_NUGET) == NULL) {
-                                                                       hasDependency = true;
-                                                                       for (auto& ad : appDependencies) {
-                                                                               if (!strcmp(ad.c_str(), dependency.c_str())) {
-                                                                                       hasDependency = true;
-                                                                                       break;
-                                                                               } else {
-                                                                                       hasDependency = false;
-                                                                               }
-                                                                       }
-                                                                       if (hasDependency) break;
-                                                               }
-                                                       }
-                                                       if (!hasDependency) {
-                                                               bool isExistTpaAssembly = false;
-                                                               for (auto& assembly : assemblies.getMemberNames()) {
-                                                                       std::string assemblyName = assembly.substr(assembly.rfind('/') + 1);
-                                                                       //Skip the assembly present in the TPA list
-                                                                       for (auto& tpa : tpaAssemblies) {
-                                                                               if (!strcmp(replaceAll(tpa, ".ni.dll", ".dll").c_str(), assembly.c_str())) {
-                                                                                       isExistTpaAssembly = true;
-                                                                                       break;
-                                                                               }
-                                                                       }
-                                                                       if (isExistTpaAssembly) break;
-                                                               }
-                                                               if (!isExistTpaAssembly) {
-                                                                       for (auto& assembly : assemblies.getMemberNames()) {
-                                                                               std::string assemblyName = assembly.substr(assembly.rfind('/') + 1);
-                                                                               parserData.push_back(nuget + ":" + assemblyName);
-                                                                               _INFO("Nuget : [%s] / Assembly : [%s]", nuget.c_str(), assemblyName.c_str());
-                                                                       }
-                                                               }
+                                                       // handle assembly even though that is included in the TPA.
+                                                       for (auto& assembly : assemblies.getMemberNames()) {
+                                                               std::string assemblyName = assembly.substr(assembly.rfind('/') + 1);
+                                                               parserData.push_back(nuget + ":" + assemblyName);
+                                                               _INFO("Nuget : [%s] / Assembly : [%s]", nuget.c_str(), assemblyName.c_str());
                                                        }
                                                }
                                        }
                                }
-                               appDependencies.clear();
                                ifs.close();
                        }
                }
-       } catch (const Json::LogicError& error) {
+       } catch (const Json::Exception& error) {
                _ERR("Failed to parse Json: %s", error.what());
        }
-       tpaAssemblies.clear();
        return parserData;
 }
+
+std::vector<std::string> getLibrariesInfo(const std::string& rootPath)
+{
+       std::vector<std::string> LibrariesInfo;
+       std::string binDir = concatPath(rootPath, "bin");
+       if (!exist(binDir))
+               return LibrariesInfo;
+
+       auto convert = [&LibrariesInfo](const std::string& filepath, const std::string& filename) {
+               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());
+               }
+       };
+       scanFilesInDirectory(binDir, convert, -1);
+
+       return LibrariesInfo;
+}
+
+// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
+static int tlc_restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
+{
+       char *pkgId = NULL;
+       char *root = NULL;
+       std::string rootPath;
+
+       int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
+       if (ret != PMINFO_R_OK) {
+               _SERR("Failed to get pkgid");
+               return -1;
+       }
+
+       ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
+       if (ret != PMINFO_R_OK) {
+               _SERR("Failed to get root path");
+               return -1;
+       }
+       rootPath = std::string(root);
+
+       for (auto& librarySha : getLibrariesInfo(rootPath)) {
+               std::string library = librarySha.substr(0, librarySha.find(':'));
+               if (exist(library)) {
+                       std::string fileSha = library.substr(library.rfind('/') + 1) + ".." + librarySha.substr(librarySha.find(':') + 1);
+                       char *sql = sqlite3_mprintf("INSERT INTO TLC (PKGID, LIBRARY) VALUES (%Q, %Q);", pkgId, fileSha.c_str());
+                       insertDB(tlc_db, sql);
+                       restore_library.push_back(fileSha);
+                       sqlite3_free(sql);
+               }
+       }
+       return 0;
+}
+
+tac_error_e tlc_restoreDB()
+{
+       if (!removeFile(TLC_APP_LIST_RESTORE_DB)) {
+               _SERR("Failed to remove of %s", TLC_APP_LIST_RESTORE_DB);
+               return TAC_ERROR_UNKNOWN;
+       }
+
+       std::string dbRestoreJournal = TLC_APP_LIST_RESTORE_DB + std::string("-journal");
+       if (!removeFile(dbRestoreJournal)) {
+               _SERR("Failed to remove of %s", dbRestoreJournal.c_str());
+               return TAC_ERROR_UNKNOWN;
+       }
+
+       tlc_db = createDB(TLC_APP_LIST_RESTORE_DB, CREATE_TLC_DB_TABLE);
+       if (!tlc_db) {
+               _SERR("Sqlite create error");
+               return TAC_ERROR_UNKNOWN;
+       }
+       sqlite3_exec(tlc_db, "BEGIN;", NULL, NULL, NULL);
+
+       pkgmgrinfo_appinfo_metadata_filter_h handle;
+       int ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
+       if (ret != PMINFO_R_OK) {
+               return TAC_ERROR_UNKNOWN;
+       }
+
+       ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, TAC_METADATA_KEY, METADATA_VALUE_TRUE);
+       if (ret != PMINFO_R_OK) {
+               pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+               return TAC_ERROR_UNKNOWN;
+       }
+
+       ret = pkgmgrMDFilterForeach(handle, tlc_restoreDBCb, NULL);
+       if (ret != 0) {
+               pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+               return TAC_ERROR_UNKNOWN;
+       }
+
+       pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+
+       if (tlc_db) {
+               closeDB(tlc_db);
+               tlc_db = NULL;
+       }
+
+       if (!copyFile(TLC_APP_LIST_RESTORE_DB, TLC_APP_LIST_DB)) {
+               _SERR("Failed to copy of %s", TLC_APP_LIST_DB);
+               return TAC_ERROR_UNKNOWN;
+       }
+       if (!removeFile(TLC_APP_LIST_RESTORE_DB)) {
+               _SERR("Failed to remove of %s", TLC_APP_LIST_RESTORE_DB);
+               return TAC_ERROR_UNKNOWN;
+       }
+
+       std::string dbJournal = TLC_APP_LIST_DB + std::string("-journal");
+       if (!copyFile(dbRestoreJournal, dbJournal)) {
+               _SERR("Failed to copy of %s", dbJournal.c_str());
+               return TAC_ERROR_UNKNOWN;
+       }
+       if (!removeFile(dbRestoreJournal)) {
+               _SERR("Failed to remove of %s", dbRestoreJournal.c_str());
+               return TAC_ERROR_UNKNOWN;
+       }
+
+       auto convert = [](const std::string& path, const std::string& filename) {
+               bool isExist = false;
+               for (auto& library : restore_library) {
+                       if (!strcmp(filename.c_str(), library.c_str())) {
+                               isExist = true;
+                               break;
+                       }
+               }
+               if (!isExist) {
+                       if (!removeFile(path)) {
+                               _ERR("Failed to remove of %s", path.c_str());
+                       }
+               }
+       };
+
+       scanFilesInDirectory(TLC_LIBRARIES_DIR, convert, 0);
+
+       return TAC_ERROR_NONE;
+}