remove app profile data when app is updated
authorWoongsuk Cho <ws77.cho@samsung.com>
Thu, 19 Aug 2021 03:59:36 +0000 (12:59 +0900)
committer조웅석/Common Platform Lab(SR)/Principal Engineer/삼성전자 <ws77.cho@samsung.com>
Thu, 19 Aug 2021 21:17:25 +0000 (06:17 +0900)
- change implementation to remove profile data for all UIDs
- remove app profile data when app is updated
- add "--rm-all-app-profile" option to dotnettool
- change plugin name from delete_unsed_library_plugin to dotnet_apptype_plugin

NativeLauncher/CMakeLists.txt
NativeLauncher/dotnet-launcher.info
NativeLauncher/inc/ni_common.h
NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc [moved from NativeLauncher/installer-plugin/delete_unused_library_plugin.cc with 95% similarity]
NativeLauncher/tool/dotnettool.cc
NativeLauncher/tool/ni_common.cc
packaging/dotnet-launcher.spec

index 6caa0ce..58705d0 100644 (file)
@@ -4,7 +4,7 @@ PROJECT("dotnet-tools")
 MESSAGE("CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
 
 INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED aul pkgmgr-info pkgmgr-installer ecore bundle dlog liblaunchpad glib-2.0 libsmack capi-appfw-app-common storage jsoncpp openssl1.1 sqlite3)
+PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED aul pkgmgr-info pkgmgr-installer ecore bundle dlog liblaunchpad glib-2.0 libsmack capi-appfw-app-common storage jsoncpp openssl1.1 sqlite3 libtzplatform-config)
 
 FOREACH(flag ${${PROJECT_NAME}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -234,13 +234,13 @@ ADD_LIBRARY(${PREFER_NUGET_CACHE_PLUGIN} SHARED ${${PREFER_NUGET_CACHE_PLUGIN}_S
 SET_TARGET_PROPERTIES(${PREFER_NUGET_CACHE_PLUGIN} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB})
 TARGET_LINK_LIBRARIES(${PREFER_NUGET_CACHE_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL} ${TAC_COMMON})
 
-SET(DELETE_UNUSED_LIBRARY_PLUGIN "delete_unused_library_plugin")
-SET(${DELETE_UNUSED_LIBRARY_PLUGIN}_SOURCE_FILES
-    installer-plugin/delete_unused_library_plugin.cc
+SET(DOTNET_APPTYPE_PLUGIN "dotnet_apptype_plugin")
+SET(${DOTNET_APPTYPE_PLUGIN}_SOURCE_FILES
+    installer-plugin/dotnet_apptype_plugin.cc
 )
-ADD_LIBRARY(${DELETE_UNUSED_LIBRARY_PLUGIN} SHARED ${${DELETE_UNUSED_LIBRARY_PLUGIN}_SOURCE_FILES})
-SET_TARGET_PROPERTIES(${DELETE_UNUSED_LIBRARY_PLUGIN} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB})
-TARGET_LINK_LIBRARIES(${DELETE_UNUSED_LIBRARY_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL} ${MULTI_TARGET_RESOLVER})
+ADD_LIBRARY(${DOTNET_APPTYPE_PLUGIN} SHARED ${${DOTNET_APPTYPE_PLUGIN}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${DOTNET_APPTYPE_PLUGIN} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB})
+TARGET_LINK_LIBRARIES(${DOTNET_APPTYPE_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL} ${MULTI_TARGET_RESOLVER} ${NI_COMMON})
 
 # Build for test plugin library (libdotnet-plugin.so)
 IF(DEFINED BUILD_DOTNET_PLUGIN)
@@ -268,7 +268,7 @@ INSTALL(TARGETS ${TPATOOL} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${DOTNETTOOL} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
 INSTALL(TARGETS ${PREFER_NUGET_CACHE_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
-INSTALL(TARGETS ${DELETE_UNUSED_LIBRARY_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR})
+INSTALL(TARGETS ${DOTNET_APPTYPE_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR})
 INSTALL(FILES dotnet.loader DESTINATION ${LOADERDIR})
 INSTALL(FILES dotnet.launcher DESTINATION ${LOADERDIR})
 INSTALL(FILES dotnet.debugger DESTINATION ${LOADERDIR})
index 067a4b6..1fa1729 100644 (file)
@@ -1,6 +1,6 @@
-type="tag";name="ui-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so"
-type="tag";name="service-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so"
-type="tag";name="widget-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so"
-type="tag";name="watch-application";path="/etc/package-manager/parserlib/libdelete_unused_library_plugin.so"
+type="tag";name="ui-application";path="/etc/package-manager/parserlib/libdotnet_apptype_plugin.so"
+type="tag";name="service-application";path="/etc/package-manager/parserlib/libdotnet_apptype_plugin.so"
+type="tag";name="widget-application";path="/etc/package-manager/parserlib/libdotnet_apptype_plugin.so"
+type="tag";name="watch-application";path="/etc/package-manager/parserlib/libdotnet_apptype_plugin.so"
 type="metadata";name="http://tizen.org/metadata/prefer_nuget_cache";path="/etc/package-manager/parserlib/metadata/libprefer_nuget_cache_plugin.so"
 type="metadata";name="http://tizen.org/metadata/prefer_dotnet_aot";path="/etc/package-manager/parserlib/metadata/libprefer_dotnet_aot_plugin.so"
index 7970963..d12b4b2 100644 (file)
@@ -122,4 +122,16 @@ ni_error_e regenerateAppNI(DWORD flags);
  */
 ni_error_e regenerateTACNI(DWORD flags);
 
+/**
+ * @brief remove app profile data of a package
+ * @param[in] pkgId package ID
+ * @return ni_error_e
+ */
+ni_error_e removeAppProfileData(const std::string& pkgId);
+
+/**
+ * @brief remove all app profile data
+ */
+void removeAllAppProfileData();
+
 #endif /* __NI_COMMON_H__ */
@@ -17,6 +17,7 @@
 #include "log.h"
 #include "utils.h"
 #include "multi_target_resolver.h"
+#include "ni_common.h"
 
 #include <vector>
 
@@ -55,6 +56,10 @@ extern "C" int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char* pkgId)
                return 0;
        }
 
+       if (removeAppProfileData(pkgId) != NI_ERROR_NONE) {
+               _ERR("Failed to remove [%s] profile data", pkgId);
+       }
+
        if (resolvePlatformSpecificFiles(rootPath) != 0) {
                _ERR("Failed to resolve platform specific resources of nuget");
        }
index 38db4cd..dc3cfcf 100644 (file)
@@ -50,7 +50,9 @@ void DisplayUsage() {
                "       --ibc-dir                 - Specify a directory containing IBC files\n"
                "       --resolve-all-app         - Remove unused multi-targeting files of all apps\n"
                "                                   (this option is used for FOTA script or test)\n"
-               "       --rm-app-profile          - Remove application profile for all users\n"
+               "       --rm-app-profile          - Remove application profile of given packages for all users\n"
+               "                                   (this option should be run as root)\n"
+               "       --rm-all-app-profile      - Remove application profile of all packages for all users\n"
                "                                   (this option should be run as root)\n"
                "\n"
                "Options:\n"
@@ -290,29 +292,18 @@ int main(int argc, char* argv[])
                if (args.size() < 1) {
                        _SERR("Package name is missing");
                }
-               char *home = getenv("HOME"); // /root
-               if (home == NULL) {
-                       _SERR("Fail to get Home path from env");
-               } else {
-                       while (it != args.end()) {
-                               std::string pkg = std::string(*it);
-                               setenv("AUL_APPID", pkg.c_str(), 1);
-                               char *localDataPath = app_get_data_path(); // /root/apps_rw/<app_id>/data/
-                               if (localDataPath != NULL) {
-                                       std::string pDataFile = "/home/*";
-                                       pDataFile.append(localDataPath + strlen(home)); // /home/*/apps_rw/<app_id>/data/
-                                       pDataFile.append(PROFILE_BASENAME); // /home/*/apps_rw/<app_id>/data/.__tizen_specific_profile_data
-                                       if (!removeFile(pDataFile)) {
-                                               _SERR("Fail to remove file (%s)", pDataFile.c_str());
-                                       }
-                                       free(localDataPath);
-                               } else {
-                                       _SERR("Application not found [%s], skip to remove profile", pkg.c_str());
-                               }
-                               it = args.erase(it);
+               while (it != args.end()) {
+                       std::string pkg = std::string(*it);
+                       if (removeAppProfileData(pkg) != NI_ERROR_NONE) {
+                               _SERR("Failed to remove [%s] profile data", pkg.c_str());
                        }
+                       it = args.erase(it);
                }
        }
+       //sh-3.2# dotnettool --rm-all-app-profile
+       else if (cmd == "--rm-all-app-profile") {
+               removeAllAppProfileData();
+       }
        else {
                _SERR("Unknown option [%s]", cmd.c_str());
                DisplayUsage();
index 80af20e..e2e9f4d 100644 (file)
@@ -17,6 +17,7 @@
 #include <pkgmgr-info.h>
 #include <pkgmgr_installer_info.h>
 #include <aul.h>
+#include <tzplatform_config.h>
 
 #include "log.h"
 #include "utils.h"
@@ -850,3 +851,125 @@ ni_error_e regenerateTACNI(DWORD flags)
 
        return NI_ERROR_NONE;
 }
+
+static std::vector<uid_t> getUserIds()
+{
+       std::vector<uid_t> 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;
+                       }
+                       break;
+               }
+               list.push_back(entry->pw_uid);
+       }
+       endpwent();
+
+       return list;
+}
+
+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;
+}
+
+ni_error_e removeAppProfileData(const std::string& pkgId)
+{
+       if (pkgId.empty()) {
+               return NI_ERROR_INVALID_PARAMETER;
+       }
+
+       std::vector<uid_t> uidList = getUserIds();
+       for (auto& uid : uidList) {
+               // get data path from pkgid
+               std::string dataPath = getAppDataPath(pkgId, uid);
+               if (!dataPath.empty() && exist(dataPath)) {
+                       std::string pDataFile = dataPath + PROFILE_BASENAME;
+
+                       if (exist(pDataFile)) {
+                               if (!removeFile(pDataFile)) {
+                                       _SERR("Fail to remove profile data file (%s).", pDataFile.c_str());
+                                       return NI_ERROR_UNKNOWN;
+                               }
+                               _SOUT("Profile data (%s) is removed successfully", pDataFile.c_str());
+                       }
+               }
+       }
+
+       return NI_ERROR_NONE;
+}
+
+static int appTypeListCb(pkgmgrinfo_appinfo_h handle, void *user_data)
+{
+       char *pkgId = NULL;
+       int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
+       if (ret != PMINFO_R_OK || pkgId == NULL) {
+               _SERR("Fail to get pkgid");
+               return 0;
+       }
+
+       if (removeAppProfileData(pkgId) != NI_ERROR_NONE) {
+               _SERR("Fail to remove profile data for (%s)", pkgId);
+       }
+
+       return 0;
+}
+
+static ni_error_e removeAppProfileByAppType(const char* type)
+{
+       int ret;
+
+       pkgmgrinfo_appinfo_filter_h filter;
+
+       ret = pkgmgrinfo_appinfo_filter_create(&filter);
+       if (ret != PMINFO_R_OK) {
+               _SERR("Fail to create appinfo filter");
+               return NI_ERROR_UNKNOWN;
+       }
+
+       ret = pkgmgrinfo_appinfo_filter_add_string(filter, PMINFO_APPINFO_PROP_APP_TYPE, type);
+       if (ret != PMINFO_R_OK) {
+               pkgmgrinfo_appinfo_filter_destroy(filter);
+               _SERR("Fail to add appinfo filter (%s)", type);
+               return NI_ERROR_UNKNOWN;
+       }
+
+       ret = pkgmgrinfo_appinfo_filter_foreach_appinfo(filter, appTypeListCb, NULL);
+       if (ret != PMINFO_R_OK) {
+               _SERR("Fail to pkgmgrinfo_pkginfo_filter_foreach_pkginfo");
+               pkgmgrinfo_appinfo_filter_destroy(filter);
+               return NI_ERROR_UNKNOWN;
+       }
+
+       pkgmgrinfo_appinfo_filter_destroy(filter);
+
+       return NI_ERROR_NONE;
+}
+
+void removeAllAppProfileData()
+{
+       std::vector<const char*> appTypeList = {"dotnet", "dotnet-nui", "dotnet-inhouse"};
+
+       for (auto& type : appTypeList) {
+               if (removeAppProfileByAppType(type) != NI_ERROR_NONE) {
+                       _SERR("Fail to removeAppProfileByAppType for type (%s)", type);
+               }
+       }
+}
index 2445646..e4dd257 100644 (file)
@@ -24,6 +24,7 @@ BuildRequires: pkgconfig(storage)
 BuildRequires: pkgconfig(jsoncpp)
 BuildRequires: pkgconfig(openssl1.1)
 BuildRequires: pkgconfig(libsystemd)
+BuildRequires: pkgconfig(libtzplatform-config)
 BuildRequires: sqlite-devel
 BuildRequires: boost-devel
 BuildRequires: aul-devel
@@ -195,7 +196,7 @@ chsmack -a User /usr/bin/dotnet-nui-loader
 %{_bindir}/dotnettool
 %{_install_mdplugin_dir}/libprefer_nuget_cache_plugin.so
 %{_install_mdplugin_dir}/libprefer_dotnet_aot_plugin.so
-%{_install_plugin_dir}/libdelete_unused_library_plugin.so
+%{_install_plugin_dir}/libdotnet_apptype_plugin.so
 %{_bindir}/dotnet-launcher
 %{_bindir}/dotnet-loader
 %{_bindir}/dotnet