Gets the user's uid related to installed app only.
authorWoongsuk Cho <ws77.cho@samsung.com>
Thu, 9 Nov 2023 01:05:34 +0000 (10:05 +0900)
committerWoongsuk Cho <ws77.cho@samsung.com>
Thu, 9 Nov 2023 01:05:34 +0000 (10:05 +0900)
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
NativeLauncher/installer-plugin/dotnet_apptype_plugin.cc
NativeLauncher/tool/dotnettool.cc
NativeLauncher/tool/profile_common.cc

index 7495a2384d06fcc434909de669fbb4705eb4d257..87329be7f424bd2c75897ebd668d47fbf694c38e 100644 (file)
@@ -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
index 48e0ed30ead61c259f626887b73768b37074b43f..25d2c4e2b9648aa07374c740b3106641f0f20947 100644 (file)
@@ -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);
        }
 
index 4343b49ae5df73f2d790b4133509228bffd1f7f5..0afa2ff4d5ce2cc162e75a628c701fef326ac5d9 100644 (file)
@@ -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);
index 91065f1a925c0cd5b21562b68da3fc14a9b6962b..e052544fb9a0d112d5b67d9b0b981d0b4b224139 100644 (file)
 #include "launcher_env.h"
 
 #include <sys/types.h>
+#include <dirent.h>
 #include <pwd.h>
 #include <tzplatform_config.h>
 
+// 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<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;
+       DIR *dir;
+       struct dirent* entry;
+       struct passwd *p;
+       std::vector<uid_t> 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<uid_t> uidList = getUserIds();
-       for (auto& uid : uidList) {
-               // get data path from pkgid
-               std::string dataPath = getAppDataPath(pkgId, uid);
+       std::vector<uid_t> uidList;
+       if (user_data != NULL) {
+               uidList = *(std::vector<uid_t>*)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<uid_t> uidList = getUserIds();
+       int ret = pkgmgrinfo_appinfo_get_installed_list(removeAppProfileListCb, &uidList);
        if (ret != PMINFO_R_OK) {
                _SERR("Failed to get installed list");
        }