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 7495a23..87329be 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 48e0ed3..25d2c4e 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 4343b49..0afa2ff 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 91065f1..e052544 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");
        }