1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "user_unlocked_event_subscriber.h"
17
18 #include <filesystem>
19 #include <sys/stat.h>
20
21 #include "account_helper.h"
22 #include "app_log_tag_wrapper.h"
23 #include "bundle_mgr_service.h"
24 #if defined (BUNDLE_FRAMEWORK_SANDBOX_APP) && defined (DLP_PERMISSION_ENABLE)
25 #include "dlp_permission_kit.h"
26 #endif
27 #include "installd_client.h"
28
29 namespace OHOS {
30 namespace AppExecFwk {
31 namespace {
32 static constexpr int16_t MODE_BASE = 07777;
33 constexpr const char* BUNDLE_BACKUP_HOME_PATH_EL1_NEW = "/data/app/el1/%/base/";
34 constexpr const char* BUNDLE_BACKUP_HOME_PATH_EL2_NEW = "/data/app/el2/%/base/";
35 constexpr const char* BUNDLE_BACKUP_INNER_DIR = "/.backup";
36 const std::vector<std::string> BUNDLE_DATA_DIR = {
37 "/cache",
38 "/files",
39 "/temp",
40 "/preferences",
41 "/haps"
42 };
43 static std::mutex TASK_MUTEX;
44 static std::atomic<uint32_t> CURRENT_TASK_NUM = 0;
45
46 template<typename Func, typename...Args>
ReturnIfNewTask(Func func,uint32_t tempTask,Args &&...args)47 inline void ReturnIfNewTask(Func func, uint32_t tempTask, Args&&... args)
48 {
49 if (CURRENT_TASK_NUM != tempTask) {
50 APP_LOGI("need stop current task, new first");
51 return;
52 }
53 func(std::forward<Args>(args)...);
54 }
55 }
UserUnlockedEventSubscriber(const EventFwk::CommonEventSubscribeInfo & subscribeInfo)56 UserUnlockedEventSubscriber::UserUnlockedEventSubscriber(
57 const EventFwk::CommonEventSubscribeInfo &subscribeInfo) : EventFwk::CommonEventSubscriber(subscribeInfo)
58 {}
59
~UserUnlockedEventSubscriber()60 UserUnlockedEventSubscriber::~UserUnlockedEventSubscriber()
61 {}
62
OnReceiveEvent(const EventFwk::CommonEventData & data)63 void UserUnlockedEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
64 {
65 std::string action = data.GetWant().GetAction();
66 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_UNLOCKED) {
67 int32_t userId = data.GetCode();
68 APP_LOGI_NOFUNC("UserUnlockedEventSubscriber -u %{public}d unlocked", userId);
69 std::lock_guard<std::mutex> lock(mutex_);
70 if ((userId_ != userId)) {
71 userId_ = userId;
72 std::thread updateDataDirThread(UpdateAppDataMgr::UpdateAppDataDirSelinuxLabel, userId);
73 updateDataDirThread.detach();
74 std::thread(UpdateAppDataMgr::DeleteUninstallTmpDirs, userId).detach();
75 #ifdef BUNDLE_FRAMEWORK_APP_CONTROL
76 DelayedSingleton<AppControlManager>::GetInstance()->SetAppInstallControlStatus();
77 #endif
78 }
79 }
80 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
81 int32_t userId = data.GetCode();
82 APP_LOGI_NOFUNC("UserUnlockedEventSubscriber -u %{public}d switched", userId);
83 std::lock_guard<std::mutex> lock(mutex_);
84 if (AccountHelper::IsOsAccountVerified(userId) && (userId_ != userId)) {
85 APP_LOGI_NOFUNC("UserUnlockedEventSubscriber -u %{public}d unlocked", userId);
86 userId_ = userId;
87 std::thread updateDataDirThread(UpdateAppDataMgr::UpdateAppDataDirSelinuxLabel, userId);
88 updateDataDirThread.detach();
89 std::thread(UpdateAppDataMgr::DeleteUninstallTmpDirs, userId).detach();
90 }
91 #if defined (BUNDLE_FRAMEWORK_SANDBOX_APP) && defined (DLP_PERMISSION_ENABLE)
92 APP_LOGI("RemoveUnreservedSandbox call ClearUnreservedSandbox");
93 Security::DlpPermission::DlpPermissionKit::ClearUnreservedSandbox();
94 #endif
95 #ifdef BUNDLE_FRAMEWORK_APP_CONTROL
96 DelayedSingleton<AppControlManager>::GetInstance()->SetAppInstallControlStatus();
97 #endif
98 }
99 }
100
CheckPathAttribute(const std::string & path,const BundleInfo & bundleInfo,bool & isExist)101 void UpdateAppDataMgr::CheckPathAttribute(const std::string &path, const BundleInfo &bundleInfo, bool &isExist)
102 {
103 if (!isExist) {
104 return;
105 }
106 FileStat fileStat;
107 if (InstalldClient::GetInstance()->GetFileStat(path, fileStat) != ERR_OK) {
108 APP_LOGE("GetFileStat path(%{public}s) failed", path.c_str());
109 return;
110 }
111 if (fileStat.uid != bundleInfo.uid) {
112 APP_LOGW("path: %{public}s uid is not same, fileStat.uid:%{public}d, bundleInfo.uid:%{public}d",
113 path.c_str(), static_cast<int32_t>(fileStat.uid), bundleInfo.uid);
114 isExist = false;
115 }
116 if (fileStat.gid != ServiceConstants::DATABASE_DIR_GID) {
117 APP_LOGW("path: %{public}s gid is not same, fileStat.gid:%{public}d, gid:%{public}d",
118 path.c_str(), static_cast<int32_t>(fileStat.gid), ServiceConstants::DATABASE_DIR_GID);
119 isExist = false;
120 }
121 uint32_t fileMode = static_cast<uint32_t>(fileStat.mode);
122 if ((fileMode & MODE_BASE) != (S_IRWXU | S_IRWXG | S_ISGID)) {
123 APP_LOGW("path: %{public}s mode is not same, fileStat.mode:%{public}d, mode:%{public}d",
124 path.c_str(), static_cast<int32_t>(fileStat.mode), static_cast<int32_t>((S_IRWXU | S_IRWXG | S_ISGID)));
125 }
126 }
127
CreateBundleDataDir(const BundleInfo & bundleInfo,int32_t userId,const std::string & elDir)128 bool UpdateAppDataMgr::CreateBundleDataDir(
129 const BundleInfo &bundleInfo, int32_t userId, const std::string &elDir)
130 {
131 std::string baseBundleDataDir = ServiceConstants::BUNDLE_APP_DATA_BASE_DIR + elDir +
132 ServiceConstants::PATH_SEPARATOR + std::to_string(userId) + ServiceConstants::DATABASE + bundleInfo.name;
133 bool isExist = false;
134 if (InstalldClient::GetInstance()->IsExistDir(baseBundleDataDir, isExist) != ERR_OK) {
135 APP_LOGE("path: %{public}s IsExistDir failed", baseBundleDataDir.c_str());
136 return false;
137 }
138 CheckPathAttribute(baseBundleDataDir, bundleInfo, isExist);
139 if (!isExist) {
140 APP_LOGI_NOFUNC("path: %{public}s need CreateBundleDataDir", baseBundleDataDir.c_str());
141 CreateDirParam createDirParam;
142 createDirParam.userId = userId;
143 createDirParam.bundleName = bundleInfo.name;
144 createDirParam.uid = bundleInfo.uid;
145 createDirParam.gid = bundleInfo.gid;
146 createDirParam.apl = bundleInfo.applicationInfo.appPrivilegeLevel;
147 createDirParam.isPreInstallApp = bundleInfo.isPreInstallApp;
148 createDirParam.debug = bundleInfo.applicationInfo.appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG;
149 if (elDir != ServiceConstants::BUNDLE_EL[0]) {
150 createDirParam.createDirFlag = CreateDirFlag::CREATE_DIR_UNLOCKED;
151 }
152 if (elDir == ServiceConstants::DIR_EL5) {
153 return CreateEl5Dir(createDirParam);
154 }
155 ProcessExtensionDir(bundleInfo, createDirParam.extensionDirs);
156 if (InstalldClient::GetInstance()->CreateBundleDataDir(createDirParam) != ERR_OK) {
157 APP_LOGW("failed to CreateBundleDataDir");
158 }
159 }
160 if (elDir == ServiceConstants::BUNDLE_EL[1]) {
161 CreateDataGroupDir(bundleInfo, userId);
162 }
163 return true;
164 }
165
CreateEl5Dir(const CreateDirParam & createDirParam)166 bool UpdateAppDataMgr::CreateEl5Dir(const CreateDirParam &createDirParam)
167 {
168 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
169 if (dataMgr == nullptr) {
170 APP_LOGE("CreateEl5Dir failed for DataMgr is nullptr");
171 return false;
172 }
173 std::vector<CreateDirParam> params;
174 params.emplace_back(createDirParam);
175 InnerBundleInfo info;
176 if (dataMgr->FetchInnerBundleInfo(createDirParam.bundleName, info)) {
177 InnerBundleUserInfo userInfo;
178 if (info.GetInnerBundleUserInfo(createDirParam.userId, userInfo)) {
179 for (const auto &cloneInfo : userInfo.cloneInfos) {
180 CreateDirParam cloneParam = createDirParam;
181 cloneParam.uid = cloneInfo.second.uid;
182 cloneParam.gid = cloneInfo.second.uid;
183 cloneParam.appIndex = cloneInfo.second.appIndex;
184 params.emplace_back(cloneParam);
185 }
186 }
187 }
188 dataMgr->CreateEl5Dir(params, true);
189 dataMgr->CreateAppEl5GroupDir(createDirParam.bundleName, createDirParam.userId);
190 return true;
191 }
192
DeleteUninstallTmpDirs(const int32_t userId)193 void UpdateAppDataMgr::DeleteUninstallTmpDirs(const int32_t userId)
194 {
195 std::vector<std::string> dirs = GetBundleDataDirs(userId);
196 if (dirs.empty()) {
197 LOG_I(BMS_TAG_DEFAULT, "dirs empty");
198 return;
199 }
200 ErrCode ret = InstalldClient::GetInstance()->DeleteUninstallTmpDirs(dirs);
201 if (ret != ERR_OK) {
202 LOG_W(BMS_TAG_DEFAULT, "delete tmp dirs failed:%{public}d", ret);
203 }
204 }
205
GetBundleDataDirs(const int32_t userId)206 std::vector<std::string> UpdateAppDataMgr::GetBundleDataDirs(const int32_t userId)
207 {
208 std::vector<std::string> dirs;
209 std::vector<std::string> dataVector = { "base", "database" };
210 for (const std::string &el : ServiceConstants::BUNDLE_EL) {
211 std::filesystem::path userPath =
212 std::filesystem::path(ServiceConstants::BUNDLE_APP_DATA_BASE_DIR) / el / std::to_string(userId);
213 for (const std::string &data : dataVector) {
214 std::filesystem::path dataPath = userPath / data;
215 dirs.emplace_back(dataPath.string());
216 }
217 }
218 return dirs;
219 }
220
CreateDataGroupDir(const BundleInfo & bundleInfo,int32_t userId)221 void UpdateAppDataMgr::CreateDataGroupDir(const BundleInfo &bundleInfo, int32_t userId)
222 {
223 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
224 if (dataMgr == nullptr) {
225 APP_LOGE("CreateDataGroupDir failed for DataMgr is nullptr");
226 return;
227 }
228 if (!dataMgr->CreateAppGroupDir(bundleInfo.name, userId)) {
229 APP_LOGE("CreateAppGroupDir %{public}s in %{public}d failed", bundleInfo.name.c_str(), userId);
230 return;
231 }
232 }
233
UpdateAppDataDirSelinuxLabel(int32_t userId)234 void UpdateAppDataMgr::UpdateAppDataDirSelinuxLabel(int32_t userId)
235 {
236 uint32_t tempTaskNum = CURRENT_TASK_NUM.fetch_add(1) + 1;
237 std::lock_guard<std::mutex> guard(TASK_MUTEX);
238 APP_LOGI("UpdateAppDataDirSelinuxLabel hold task_mutex_");
239 if (tempTaskNum != CURRENT_TASK_NUM) {
240 APP_LOGI("need stop current task, new first, -u %{public}d", userId);
241 return;
242 }
243 APP_LOGI("UpdateAppDataDirSelinuxLabel userId:%{public}d start", userId);
244 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
245 if (dataMgr == nullptr) {
246 APP_LOGE("UpdateAppDataDirSelinuxLabel DataMgr is nullptr");
247 return;
248 }
249 std::vector<BundleInfo> bundleInfos;
250 if (!dataMgr->GetBundleInfos(BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO |
251 BundleFlag::GET_BUNDLE_WITH_REQUESTED_PERMISSION, bundleInfos, userId)) {
252 APP_LOGE("UpdateAppDataDirSelinuxLabel GetAllBundleInfos failed");
253 return;
254 }
255
256 ReturnIfNewTask(ProcessUpdateAppDataDir, tempTaskNum, userId, bundleInfos, ServiceConstants::BUNDLE_EL[1]);
257 #ifdef CHECK_ELDIR_ENABLED
258 ReturnIfNewTask(ProcessUpdateAppDataDir, tempTaskNum, userId, bundleInfos, ServiceConstants::DIR_EL3);
259 ReturnIfNewTask(ProcessUpdateAppDataDir, tempTaskNum, userId, bundleInfos, ServiceConstants::DIR_EL4);
260 #endif
261 ReturnIfNewTask(ProcessUpdateAppDataDir, tempTaskNum, userId, bundleInfos, ServiceConstants::DIR_EL5);
262 ReturnIfNewTask(ProcessUpdateAppLogDir, tempTaskNum, bundleInfos, userId);
263 ReturnIfNewTask(ProcessFileManagerDir, tempTaskNum, bundleInfos, userId);
264 ReturnIfNewTask(ProcessNewBackupDir, tempTaskNum, bundleInfos, userId);
265 ReturnIfNewTask(CreateSharefilesSubDataDirs, tempTaskNum, bundleInfos, userId);
266 APP_LOGI("UpdateAppDataDirSelinuxLabel userId:%{public}d end", userId);
267 }
268
ProcessUpdateAppDataDir(int32_t userId,const std::vector<BundleInfo> & bundleInfos,const std::string & elDir)269 void UpdateAppDataMgr::ProcessUpdateAppDataDir(
270 int32_t userId, const std::vector<BundleInfo> &bundleInfos, const std::string &elDir)
271 {
272 std::string baseBundleDataDir = ServiceConstants::BUNDLE_APP_DATA_BASE_DIR + elDir +
273 ServiceConstants::PATH_SEPARATOR + std::to_string(userId);
274 for (const auto &bundleInfo : bundleInfos) {
275 if (bundleInfo.appIndex > 0) {
276 APP_LOGI("bundleName:%{public}s appIndex:%{public}d clone app no need to change",
277 bundleInfo.name.c_str(), bundleInfo.appIndex);
278 continue;
279 }
280 if (elDir == ServiceConstants::DIR_EL5) {
281 std::vector<std::string> reqPermissions = bundleInfo.reqPermissions;
282 auto it = std::find_if(reqPermissions.begin(), reqPermissions.end(), [](const std::string &permission) {
283 return permission == ServiceConstants::PERMISSION_PROTECT_SCREEN_LOCK_DATA;
284 });
285 if (it == reqPermissions.end()) {
286 continue;
287 }
288 }
289 if ((userId != Constants::DEFAULT_USERID && bundleInfo.singleton) ||
290 !CreateBundleDataDir(bundleInfo, userId, elDir)) {
291 continue;
292 }
293 std::string baseDir = baseBundleDataDir + ServiceConstants::BASE + bundleInfo.name;
294 if (InstalldClient::GetInstance()->SetDirApl(baseDir, bundleInfo.name,
295 bundleInfo.applicationInfo.appPrivilegeLevel, bundleInfo.isPreInstallApp,
296 bundleInfo.applicationInfo.appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG) != ERR_OK) {
297 APP_LOGW_NOFUNC("failed to SetDirApl baseDir dir");
298 continue;
299 }
300 std::string baseDataDir = baseBundleDataDir + ServiceConstants::DATABASE + bundleInfo.name;
301 if (InstalldClient::GetInstance()->SetDirApl(baseDataDir, bundleInfo.name,
302 bundleInfo.applicationInfo.appPrivilegeLevel, bundleInfo.isPreInstallApp,
303 bundleInfo.applicationInfo.appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG) != ERR_OK) {
304 APP_LOGW_NOFUNC("failed to SetDirApl baseDataDir dir");
305 }
306 }
307 }
308
ProcessExtensionDir(const BundleInfo & bundleInfo,std::vector<std::string> & dirs)309 void UpdateAppDataMgr::ProcessExtensionDir(const BundleInfo &bundleInfo, std::vector<std::string> &dirs)
310 {
311 for (const ExtensionAbilityInfo &info : bundleInfo.extensionInfos) {
312 if (!info.needCreateSandbox) {
313 continue;
314 }
315 std::string extensionDir = ServiceConstants::EXTENSION_DIR + info.moduleName +
316 ServiceConstants::FILE_SEPARATOR_LINE + info.name +
317 ServiceConstants::FILE_SEPARATOR_PLUS + info.bundleName;
318 dirs.emplace_back(extensionDir);
319 }
320 }
321
ProcessUpdateAppLogDir(const std::vector<BundleInfo> & bundleInfos,int32_t userId)322 void UpdateAppDataMgr::ProcessUpdateAppLogDir(const std::vector<BundleInfo> &bundleInfos, int32_t userId)
323 {
324 for (const auto &bundleInfo : bundleInfos) {
325 if (userId != Constants::DEFAULT_USERID && bundleInfo.singleton) {
326 continue;
327 }
328 if (!CreateBundleLogDir(bundleInfo, userId)) {
329 APP_LOGD("log dir create failed or already exists");
330 }
331 }
332 }
333
ProcessNewBackupDir(const std::vector<BundleInfo> & bundleInfos,int32_t userId)334 void UpdateAppDataMgr::ProcessNewBackupDir(const std::vector<BundleInfo> &bundleInfos, int32_t userId)
335 {
336 APP_LOGI_NOFUNC("process new back up dir, start");
337 for (const auto &bundleInfo : bundleInfos) {
338 if (bundleInfo.appIndex > 0) {
339 APP_LOGI("bundleName:%{public}s appIndex %{public}d clone app no need to create",
340 bundleInfo.name.c_str(), bundleInfo.appIndex);
341 continue;
342 }
343 if (bundleInfo.singleton) {
344 CreateNewBackupDir(bundleInfo, Constants::DEFAULT_USERID);
345 continue;
346 }
347 if (userId != Constants::DEFAULT_USERID) {
348 CreateNewBackupDir(bundleInfo, userId);
349 }
350 }
351 APP_LOGI_NOFUNC("process new back up dir, end");
352 }
353
CreateNewBackupDir(const BundleInfo & bundleInfo,int32_t userId)354 void UpdateAppDataMgr::CreateNewBackupDir(const BundleInfo &bundleInfo, int32_t userId)
355 {
356 std::string parentEl1Dir = BUNDLE_BACKUP_HOME_PATH_EL1_NEW;
357 parentEl1Dir = parentEl1Dir.replace(parentEl1Dir.find("%"), 1, std::to_string(userId)) + bundleInfo.name;
358 std::string parentEl2Dir = BUNDLE_BACKUP_HOME_PATH_EL2_NEW;
359 parentEl2Dir = parentEl2Dir.replace(parentEl2Dir.find("%"), 1, std::to_string(userId)) + bundleInfo.name;
360 bool isEl1Existed = false;
361 auto result = InstalldClient::GetInstance()->IsExistDir(parentEl1Dir, isEl1Existed);
362 if (result == ERR_OK && !isEl1Existed) {
363 APP_LOGE("parent dir(%{public}s) missing: backup", parentEl1Dir.c_str());
364 return;
365 }
366 bool isEl2Existed = false;
367 result = InstalldClient::GetInstance()->IsExistDir(parentEl2Dir, isEl2Existed);
368 if (result == ERR_OK && !isEl2Existed) {
369 APP_LOGE("parent dir(%{public}s) missing: backup", parentEl2Dir.c_str());
370 return;
371 }
372 std::string backupDirEl1 = parentEl1Dir + BUNDLE_BACKUP_INNER_DIR;
373 std::string backupDirEl2 = parentEl2Dir + BUNDLE_BACKUP_INNER_DIR;
374 std::vector<std::string> backupDirList;
375 backupDirList.emplace_back(backupDirEl1);
376 backupDirList.emplace_back(backupDirEl2);
377
378 for (const std::string &dir : backupDirList) {
379 bool isDirExisted = false;
380 auto result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExisted);
381 if (result != ERR_OK || isDirExisted) {
382 continue;
383 }
384 APP_LOGI("bundle %{public}s not exist backup dir", bundleInfo.name.c_str());
385 result = InstalldClient::GetInstance()->Mkdir(dir, S_IRWXU | S_IRWXG | S_ISGID,
386 bundleInfo.uid, ServiceConstants::BACKU_HOME_GID);
387 if (result != ERR_OK) {
388 APP_LOGW("bundle %{public}s create backup dir for user %{public}d failed",
389 bundleInfo.name.c_str(), userId);
390 }
391 }
392 }
393
CreateBundleLogDir(const BundleInfo & bundleInfo,int32_t userId)394 bool UpdateAppDataMgr::CreateBundleLogDir(const BundleInfo &bundleInfo, int32_t userId)
395 {
396 std::string parentDir = ServiceConstants::BUNDLE_APP_DATA_BASE_DIR + ServiceConstants::BUNDLE_EL[1] +
397 ServiceConstants::PATH_SEPARATOR + std::to_string(userId) + ServiceConstants::LOG;
398 if (!BundleUtil::IsExistDir(parentDir)) {
399 APP_LOGE("parent dir(%{public}s) missing: log", parentDir.c_str());
400 return false;
401 }
402 std::string bundleLogDir = parentDir + bundleInfo.name;
403 bool isExist = false;
404 if (InstalldClient::GetInstance()->IsExistDir(bundleLogDir, isExist) != ERR_OK) {
405 APP_LOGE("path: %{public}s IsExistDir failed", bundleLogDir.c_str());
406 return false;
407 }
408 if (isExist) {
409 APP_LOGD("path: %{public}s is exist", bundleLogDir.c_str());
410 return false;
411 }
412 if (InstalldClient::GetInstance()->Mkdir(
413 bundleLogDir, S_IRWXU | S_IRWXG, bundleInfo.uid, ServiceConstants::LOG_DIR_GID) != ERR_OK) {
414 APP_LOGE("CreateBundleLogDir failed");
415 return false;
416 }
417 return true;
418 }
419
ProcessFileManagerDir(const std::vector<BundleInfo> & bundleInfos,int32_t userId)420 void UpdateAppDataMgr::ProcessFileManagerDir(const std::vector<BundleInfo> &bundleInfos, int32_t userId)
421 {
422 for (const auto &bundleInfo : bundleInfos) {
423 if (userId != Constants::DEFAULT_USERID && bundleInfo.singleton) {
424 continue;
425 }
426 CreateBundleCloudDir(bundleInfo, userId);
427 }
428 }
429
CreateBundleCloudDir(const BundleInfo & bundleInfo,int32_t userId)430 bool UpdateAppDataMgr::CreateBundleCloudDir(const BundleInfo &bundleInfo, int32_t userId)
431 {
432 std::string parentDir = "/data/service/el2/%/hmdfs/cloud/data/";
433 parentDir = parentDir.replace(parentDir.find("%"), 1, std::to_string(userId));
434 if (!BundleUtil::IsExistDir(parentDir)) {
435 APP_LOGE("parent dir(%{public}s) missing: cloud", parentDir.c_str());
436 return false;
437 }
438 std::string bundleCloudDir = parentDir + bundleInfo.name;
439 bool isExist = false;
440 if (InstalldClient::GetInstance()->IsExistDir(bundleCloudDir, isExist) != ERR_OK) {
441 APP_LOGE("path: %{private}s IsExistDir failed", bundleCloudDir.c_str());
442 return false;
443 }
444 if (isExist) {
445 APP_LOGD("path: %{private}s is exist", bundleCloudDir.c_str());
446 return false;
447 }
448 if (!InstalldClient::GetInstance()->Mkdir(bundleCloudDir, S_IRWXU | S_IRWXG | S_ISGID,
449 bundleInfo.uid, ServiceConstants::DFS_GID)) {
450 static std::once_flag cloudOnce;
451 std::call_once(cloudOnce, [bundleInfo]() {
452 APP_LOGW("CreateCloudDir failed for bundle %{private}s errno:%{public}d",
453 bundleInfo.name.c_str(), errno);
454 });
455 }
456 return true;
457 }
458
CreateSharefilesSubDataDirs(const std::vector<BundleInfo> & bundleInfos,int32_t userId)459 void UpdateAppDataMgr::CreateSharefilesSubDataDirs(const std::vector<BundleInfo> &bundleInfos, int32_t userId)
460 {
461 APP_LOGD("begin for userid: [%{public}d]", userId);
462 std::string parentDir = ServiceConstants::BUNDLE_APP_DATA_BASE_DIR + ServiceConstants::BUNDLE_EL[1] +
463 ServiceConstants::PATH_SEPARATOR + std::to_string(userId) + ServiceConstants::SHAREFILES;
464 for (const auto &bundleInfo : bundleInfos) {
465 std::string sharefilesDataDir = parentDir + bundleInfo.name;
466 bool isExist = false;
467 if (InstalldClient::GetInstance()->IsExistDir(sharefilesDataDir, isExist) != ERR_OK) {
468 APP_LOGW("path: %{public}s IsExistDir failed",
469 sharefilesDataDir.c_str());
470 continue;
471 }
472 if (InstalldClient::GetInstance()->Mkdir(sharefilesDataDir,
473 S_IRWXU, bundleInfo.uid, bundleInfo.gid) != ERR_OK) {
474 APP_LOGW("MkOwnerDir %{public}s failed: %{public}d",
475 sharefilesDataDir.c_str(), errno);
476 continue;
477 }
478 for (const auto &dir : BUNDLE_DATA_DIR) {
479 std::string childBundleDataDir = sharefilesDataDir + dir;
480 if (InstalldClient::GetInstance()->Mkdir(childBundleDataDir,
481 S_IRWXU, bundleInfo.uid, bundleInfo.gid) != ERR_OK) {
482 APP_LOGW("MkOwnerDir [%{public}s] failed: %{public}d",
483 childBundleDataDir.c_str(), errno);
484 }
485 }
486 if (InstalldClient::GetInstance()->SetDirApl(sharefilesDataDir, bundleInfo.name,
487 bundleInfo.applicationInfo.appPrivilegeLevel, bundleInfo.isPreInstallApp,
488 bundleInfo.applicationInfo.appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG) != ERR_OK) {
489 APP_LOGW("SetDirApl failed: %{public}s", sharefilesDataDir.c_str());
490 continue;
491 }
492 APP_LOGD("succeed for %{public}s", bundleInfo.name.c_str());
493 }
494 APP_LOGD("end for userid: [%{public}d]", userId);
495 }
496 } // namespace AppExecFwk
497 } // namespace OHOS