• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "quick_fix_deleter.h"
17 
18 #include "app_log_wrapper.h"
19 #include "bundle_constants.h"
20 #include "bundle_mgr_service.h"
21 #include "installd_client.h"
22 #include "scope_guard.h"
23 
24 namespace OHOS {
25 namespace AppExecFwk {
QuickFixDeleter(const std::string & bundleName)26 QuickFixDeleter::QuickFixDeleter(const std::string &bundleName) : bundleName_(bundleName)
27 {
28     APP_LOGI("enter QuickFixDeleter");
29 }
30 
Execute()31 ErrCode QuickFixDeleter::Execute()
32 {
33     APP_LOGI("start execute");
34     auto ret = DeleteQuickFix();
35     if (ret != ERR_OK) {
36         APP_LOGE("DeleteQuickFix is failed");
37     }
38     return ret;
39 }
40 
DeleteQuickFix()41 ErrCode QuickFixDeleter::DeleteQuickFix()
42 {
43     APP_LOGI("DeleteQuickFix start");
44     if (bundleName_.empty()) {
45         APP_LOGE("InnerDeleteQuickFix failed due to empty bundleName");
46         return ERR_BUNDLEMANAGER_QUICK_FIX_PARAM_ERROR;
47     }
48     if (GetQuickFixDataMgr() != ERR_OK) {
49         APP_LOGE("quickFixDataMgr is nullptr");
50         return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
51     }
52     InnerAppQuickFix innerAppQuickFix;
53     // 1. query quick fix info form db
54     if (!quickFixDataMgr_->QueryInnerAppQuickFix(bundleName_, innerAppQuickFix)) {
55         APP_LOGI("no patch in the db");
56         return ERR_OK;
57     }
58     // 2. update quick fix status
59     if (!quickFixDataMgr_->UpdateQuickFixStatus(QuickFixStatus::DELETE_START, innerAppQuickFix)) {
60         APP_LOGE("update quickfix status %{public}d failed", QuickFixStatus::DELETE_START);
61         return ERR_BUNDLEMANAGER_QUICK_FIX_INVALID_PATCH_STATUS;
62     }
63     // 3. utilize stateGuard to rollback quick fix info status in db
64     ScopeGuard stateGuard([&] {
65         quickFixDataMgr_->UpdateQuickFixStatus(QuickFixStatus::SWITCH_END, innerAppQuickFix);
66     });
67 
68     // 4. to delete patch path
69     ErrCode errCode = ToDeletePatchDir(innerAppQuickFix);
70     if (errCode != ERR_OK) {
71         APP_LOGE("ToDeletePatchDir failed");
72         return errCode;
73     }
74     // 5. to remove deployingAppqfInfo from cache
75     errCode = RemoveDeployingInfo(bundleName_);
76     if (errCode != ERR_OK) {
77         APP_LOGE("RemoveDeployingInfo failed");
78         return errCode;
79     }
80     // 6. to remove old patch info from db
81     if (!quickFixDataMgr_->DeleteInnerAppQuickFix(bundleName_)) {
82         APP_LOGE("InnerDeleteQuickFix failed");
83         return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
84     }
85     stateGuard.Dismiss();
86     return ERR_OK;
87 }
88 
ToDeletePatchDir(const InnerAppQuickFix & innerAppQuickFix)89 ErrCode QuickFixDeleter::ToDeletePatchDir(const InnerAppQuickFix &innerAppQuickFix)
90 {
91     APP_LOGI("start to delete patch dir");
92     std::string bundleName = innerAppQuickFix.GetAppQuickFix().bundleName;
93     auto res = InnerDeletePatchDir(innerAppQuickFix.GetAppQuickFix().deployedAppqfInfo, bundleName);
94     if (res != ERR_OK) {
95         APP_LOGE("delete patch dir of deployedAppqfInfo failed");
96         return res;
97     }
98     res = InnerDeletePatchDir(innerAppQuickFix.GetAppQuickFix().deployingAppqfInfo, bundleName);
99     if (res != ERR_OK) {
100         APP_LOGE("delete patch dir of deployingAppqfInfo failed");
101         return res;
102     }
103     return ERR_OK;
104 }
105 
InnerDeletePatchDir(const AppqfInfo & appqfInfo,const std::string & bundleName)106 ErrCode QuickFixDeleter::InnerDeletePatchDir(const AppqfInfo &appqfInfo, const std::string &bundleName)
107 {
108     if (appqfInfo.hqfInfos.empty()) {
109         APP_LOGD("no patch info in bundleInfo");
110         return ERR_OK;
111     }
112 
113     if (appqfInfo.type == QuickFixType::UNKNOWN) {
114         APP_LOGE("unknown quick fix type");
115         return ERR_BUNDLEMANAGER_QUICK_FIX_UNKNOWN_QUICK_FIX_TYPE;
116     }
117 
118     std::string patchPath = Constants::BUNDLE_CODE_DIR;
119     if (appqfInfo.type == QuickFixType::PATCH) {
120         patchPath += Constants::PATH_SEPARATOR + bundleName + Constants::PATH_SEPARATOR + Constants::PATCH_PATH +
121             std::to_string(appqfInfo.versionCode);
122     }
123     if (appqfInfo.type == QuickFixType::HOT_RELOAD) {
124         patchPath += Constants::PATH_SEPARATOR + bundleName + Constants::PATH_SEPARATOR + Constants::HOT_RELOAD_PATH +
125             std::to_string(appqfInfo.versionCode);
126     }
127 
128     APP_LOGD("patch path is %{public}s", patchPath.c_str());
129     if (InstalldClient::GetInstance()->RemoveDir(patchPath) != ERR_OK) {
130         APP_LOGE("RemoveDir patch path or hot reload path failed");
131         return ERR_BUNDLEMANAGER_QUICK_FIX_REMOVE_PATCH_PATH_FAILED;
132     }
133 
134     return ERR_OK;
135 }
136 
GetQuickFixDataMgr()137 ErrCode QuickFixDeleter::GetQuickFixDataMgr()
138 {
139     if (quickFixDataMgr_ == nullptr) {
140         quickFixDataMgr_ = DelayedSingleton<QuickFixDataMgr>::GetInstance();
141         if (quickFixDataMgr_ == nullptr) {
142             APP_LOGE("quickFix dataMgr is nullptr");
143             return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
144         }
145     }
146     return ERR_OK;
147 }
148 
GetDataMgr()149 ErrCode QuickFixDeleter::GetDataMgr()
150 {
151     if (dataMgr_ == nullptr) {
152         dataMgr_ = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
153         if (dataMgr_ == nullptr) {
154             APP_LOGE("dataMgr_ is nullptr");
155             return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
156         }
157     }
158     return ERR_OK;
159 }
160 
RemoveDeployingInfo(const std::string & bundleName)161 ErrCode QuickFixDeleter::RemoveDeployingInfo(const std::string &bundleName)
162 {
163     if (GetDataMgr() != ERR_OK) {
164         return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
165     }
166     InnerBundleInfo innerBundleInfo;
167     auto isExisted = dataMgr_->GetInnerBundleInfo(bundleName, innerBundleInfo);
168     if (isExisted) {
169         AppQuickFix appQuickFix = innerBundleInfo.GetAppQuickFix();
170         if (appQuickFix.deployingAppqfInfo.hqfInfos.empty()) {
171             dataMgr_->EnableBundle(bundleName_);
172             return ERR_OK;
173         }
174         appQuickFix.deployingAppqfInfo = AppqfInfo();
175         innerBundleInfo.SetAppQuickFix(appQuickFix);
176         innerBundleInfo.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
177         if (!dataMgr_->UpdateQuickFixInnerBundleInfo(bundleName, innerBundleInfo)) {
178             APP_LOGE("update quickfix innerbundleInfo failed");
179             return ERR_BUNDLEMANAGER_QUICK_FIX_INTERNAL_ERROR;
180         }
181     }
182     return ERR_OK;
183 }
184 } // AppExecFwk
185 } // OHOS