• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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