• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "bundle_exception_handler.h"
17 
18 #include "installd_client.h"
19 
20 namespace OHOS {
21 namespace AppExecFwk {
BundleExceptionHandler(const std::shared_ptr<IBundleDataStorage> & dataStorage)22 BundleExceptionHandler::BundleExceptionHandler(const std::shared_ptr<IBundleDataStorage> &dataStorage)
23     : dataStorage_(dataStorage)
24 {
25     APP_LOGD("create bundle excepetion handler instance");
26 }
27 
~BundleExceptionHandler()28 BundleExceptionHandler::~BundleExceptionHandler()
29 {
30     APP_LOGD("destroy bundle excepetion handler instance");
31 }
32 
33 
HandleInvalidBundle(InnerBundleInfo & info,bool & isBundleValid)34 void BundleExceptionHandler::HandleInvalidBundle(InnerBundleInfo &info, bool &isBundleValid)
35 {
36     InnerHandleInvalidBundle(info, isBundleValid);
37     if (isBundleValid && (info.GetApplicationBundleType() == BundleType::APP_SERVICE_FWK)) {
38         InnerCheckSystemHspPath(info);
39     }
40 }
41 
InnerCheckSystemHspPath(const InnerBundleInfo & info)42 void BundleExceptionHandler::InnerCheckSystemHspPath(const InnerBundleInfo &info)
43 {
44     auto innerModuleInfos = info.GetInnerModuleInfos();
45     for (const auto &item : innerModuleInfos) {
46         if (access(item.second.hapPath.c_str(), F_OK) != 0) {
47             APP_LOGE("-n %{public}s system hsp path %{public}s not exist", info.GetBundleName().c_str(),
48                 item.second.hapPath.c_str());
49         }
50     }
51 }
52 
RemoveBundleAndDataDir(const std::string & bundleDir,const std::string & bundleOrMoudleDir,int32_t userId) const53 bool BundleExceptionHandler::RemoveBundleAndDataDir(const std::string &bundleDir,
54     const std::string &bundleOrMoudleDir, int32_t userId) const
55 {
56     ErrCode result = InstalldClient::GetInstance()->RemoveDir(bundleDir);
57     if (result != ERR_OK) {
58         APP_LOGE("fail to remove bundle dir %{public}s, error is %{public}d", bundleDir.c_str(), result);
59         return false;
60     }
61 
62     if (bundleOrMoudleDir.find(ServiceConstants::HAPS) != std::string::npos) {
63         result = InstalldClient::GetInstance()->RemoveModuleDataDir(bundleOrMoudleDir, userId);
64         if (result != ERR_OK) {
65             APP_LOGE("fail to remove module data dir %{public}s, error is %{public}d", bundleOrMoudleDir.c_str(),
66                 result);
67             return false;
68         }
69     } else {
70         result = InstalldClient::GetInstance()->RemoveBundleDataDir(bundleOrMoudleDir, userId);
71         if (result != ERR_OK) {
72             APP_LOGE("fail to remove bundle data dir %{public}s, error is %{public}d", bundleOrMoudleDir.c_str(),
73                 result);
74             return false;
75         }
76     }
77     return true;
78 }
79 
DeleteBundleInfoFromStorage(const InnerBundleInfo & info)80 void BundleExceptionHandler::DeleteBundleInfoFromStorage(const InnerBundleInfo &info)
81 {
82     auto storage = dataStorage_.lock();
83     if (storage) {
84         APP_LOGD("remove bundle info of %{public}s from the storage", info.GetBundleName().c_str());
85         storage->DeleteStorageBundleInfo(info);
86     } else {
87         APP_LOGE(" fail to remove bundle info of %{public}s from the storage", info.GetBundleName().c_str());
88     }
89 }
90 
InnerHandleInvalidBundle(InnerBundleInfo & info,bool & isBundleValid)91 void BundleExceptionHandler::InnerHandleInvalidBundle(InnerBundleInfo &info, bool &isBundleValid)
92 {
93     auto mark = info.GetInstallMark();
94     if (mark.status == InstallExceptionStatus::INSTALL_FINISH) {
95         return;
96     }
97     APP_LOGW_NOFUNC("handle -n %{public}s status is %{public}d", info.GetBundleName().c_str(), mark.status);
98     std::string appCodePath = std::string(Constants::BUNDLE_CODE_DIR) +
99         ServiceConstants::PATH_SEPARATOR + info.GetBundleName();
100     auto moduleDir = appCodePath + ServiceConstants::PATH_SEPARATOR + mark.packageName;
101     auto moduleDataDir = info.GetBundleName() + ServiceConstants::HAPS + mark.packageName;
102 
103     // install and update failed before service restart
104     if (mark.status == InstallExceptionStatus::INSTALL_START) {
105         // unable to distinguish which user failed the installation
106         (void)RemoveBundleAndDataDir(appCodePath, info.GetBundleName(), info.GetUserId());
107         DeleteBundleInfoFromStorage(info);
108         isBundleValid = false;
109     } else if (mark.status == InstallExceptionStatus::UPDATING_EXISTED_START) {
110         if (InstalldClient::GetInstance()->RemoveDir(moduleDir + ServiceConstants::TMP_SUFFIX) == ERR_OK) {
111             info.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
112         }
113     } else if (mark.status == InstallExceptionStatus::UPDATING_NEW_START &&
114         RemoveBundleAndDataDir(moduleDir, moduleDataDir, info.GetUserId())) {
115         info.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
116     } else if (mark.status == InstallExceptionStatus::UNINSTALL_BUNDLE_START &&
117         RemoveBundleAndDataDir(appCodePath, info.GetBundleName(), info.GetUserId())) {  // continue to uninstall
118         DeleteBundleInfoFromStorage(info);
119         isBundleValid = false;
120     } else if (mark.status == InstallExceptionStatus::UNINSTALL_PACKAGE_START) {
121         if (info.IsOnlyModule(mark.packageName) &&
122             RemoveBundleAndDataDir(appCodePath, info.GetBundleName(), info.GetUserId())) {
123             DeleteBundleInfoFromStorage(info);
124             isBundleValid = false;
125             return;
126         }
127         if (RemoveBundleAndDataDir(moduleDir, moduleDataDir, info.GetUserId())) {
128             info.RemoveModuleInfo(mark.packageName);
129             info.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
130         }
131     } else if (mark.status == InstallExceptionStatus::UPDATING_FINISH) {
132         if (InstalldClient::GetInstance()->RenameModuleDir(moduleDir + ServiceConstants::TMP_SUFFIX, moduleDir) !=
133             ERR_OK) {
134             APP_LOGI_NOFUNC("%{public}s rename module failed, may not exist", info.GetBundleName().c_str());
135         }
136     }
137 }
138 }  // namespace AppExecFwkConstants
139 }  // namespace OHOS