e052544fb9a0d112d5b67d9b0b981d0b4b224139
[platform/core/dotnet/launcher.git] / NativeLauncher / tool / profile_common.cc
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "log.h"
18 #include "utils.h"
19 #include "profile_common.h"
20 #include "launcher_env.h"
21
22 #include <sys/types.h>
23 #include <dirent.h>
24 #include <pwd.h>
25 #include <tzplatform_config.h>
26
27 // Gets the user's uid with a directory under the home directory.
28 // In order to reduce unnecessary operation, only uids related to installed app are obtained.
29 static std::vector<uid_t> getUserIds()
30 {
31         DIR *dir;
32         struct dirent* entry;
33         struct passwd *p;
34         std::vector<uid_t> uids;
35
36         dir = opendir("/home");
37         if (dir == nullptr) {
38                 return uids;
39         }
40
41         while ((entry = readdir(dir)) != nullptr) {
42                 if (entry->d_type == DT_DIR) {
43                         if ((p = getpwnam(entry->d_name)) != NULL) {
44                                 uids.push_back(p->pw_uid);
45                         }
46                 }
47         }
48
49         closedir(dir);
50
51         return uids;
52 }
53
54 static std::string getAppDataPath(const std::string& pkgId, uid_t uid)
55 {
56         std::string pDataFile;
57
58         tzplatform_set_user(uid);
59
60         const char* tzUserApp = tzplatform_getenv(TZ_USER_APP);
61         if (tzUserApp != NULL) {
62                 pDataFile = std::string(tzUserApp) + "/" + pkgId + "/data/";
63         }
64
65         tzplatform_reset_user();
66
67         return pDataFile;
68 }
69
70 profile_error_e removeAppProfileData(const std::string& pkgId, void *user_data)
71 {
72         if (pkgId.empty()) {
73                 return PROFILE_ERROR_INVALID_PARAMETER;
74         }
75
76         std::vector<uid_t> uidList;
77         if (user_data != NULL) {
78                 uidList = *(std::vector<uid_t>*)user_data;
79         } else {
80                 uidList = getUserIds();
81         }
82
83         for (auto it = uidList.begin(); it != uidList.end(); ++it) {
84                 // get data path from pkgid and uid
85                 std::string dataPath = getAppDataPath(pkgId, *it);
86                 if (!dataPath.empty() && exist(dataPath)) {
87                         std::string pDataFile = dataPath + PROFILE_BASENAME;
88
89                         if (exist(pDataFile)) {
90                                 if (!removeFile(pDataFile)) {
91                                         _SERR("Failed to remove profile data file (%s).", pDataFile.c_str());
92                                         return PROFILE_ERROR_UNKNOWN;
93                                 }
94                                 _SOUT("Profile data (%s) is removed successfully", pDataFile.c_str());
95                         }
96                 }
97         }
98
99         return PROFILE_ERROR_NONE;
100 }
101
102 static int removeAppProfileListCb(pkgmgrinfo_appinfo_h handle, void *user_data)
103 {
104         int ret = 0;
105         char* appType = NULL;
106
107         ret = pkgmgrinfo_appinfo_get_apptype(handle, &appType);
108         if (ret != PMINFO_R_OK) {
109                 _SERR("Failed to get apptype");
110                 return 0;
111         }
112
113         // skip if appType is NULL or appType does not contains "dotnet",
114         if (appType == NULL || (appType != NULL && strstr(appType, "dotnet") == NULL)) {
115                 return 0;
116         }
117
118         char *pkgId = NULL;
119         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
120         if (ret != PMINFO_R_OK || pkgId == NULL) {
121                 _SERR("Failed to get package id");
122                 return 0;
123         }
124
125         if (removeAppProfileData(pkgId, user_data) != PROFILE_ERROR_NONE) {
126                 _SERR("Failed to remove profile data for (%s)", pkgId);
127         }
128
129         return 0;
130 }
131
132 void removeAllAppProfileData()
133 {
134         // To reduce repeated getUserIds calls, get uids here.
135         std::vector<uid_t> uidList = getUserIds();
136         int ret = pkgmgrinfo_appinfo_get_installed_list(removeAppProfileListCb, &uidList);
137         if (ret != PMINFO_R_OK) {
138                 _SERR("Failed to get installed list");
139         }
140 }