1 /*
2  * Copyright (c) 2022-2024 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 "ext_backup.h"
17 
18 #include <algorithm>
19 #include <cstdio>
20 #include <sstream>
21 
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 
25 #include "bundle_mgr_client.h"
26 #include "unique_fd.h"
27 
28 #include "b_anony/b_anony.h"
29 #include "b_error/b_error.h"
30 #include "b_error/b_excep_utils.h"
31 #include "b_json/b_json_cached_entity.h"
32 #include "b_json/b_json_entity_extension_config.h"
33 #include "b_resources/b_constants.h"
34 #include "ext_backup_js.h"
35 #include "ext_extension.h"
36 #include "filemgmt_libhilog.h"
37 #include "i_service.h"
38 
39 namespace OHOS::FileManagement::Backup {
40 using namespace std;
41 
42 CreatorFunc ExtBackup::creator_ = nullptr;
SetCreator(const CreatorFunc & creator)43 void ExtBackup::SetCreator(const CreatorFunc &creator)
44 {
45     creator_ = creator;
46 }
47 
SetBackupExtExtension(const wptr<BackupExtExtension> & extExtension)48 void ExtBackup::SetBackupExtExtension(const wptr<BackupExtExtension> &extExtension)
49 {
50     bakExtExtension_ = extExtension;
51 }
52 
Init(const shared_ptr<AbilityRuntime::AbilityLocalRecord> & record,const shared_ptr<AbilityRuntime::OHOSApplication> & application,shared_ptr<AbilityRuntime::AbilityHandler> & handler,const sptr<IRemoteObject> & token)53 void ExtBackup::Init(const shared_ptr<AbilityRuntime::AbilityLocalRecord> &record,
54                      const shared_ptr<AbilityRuntime::OHOSApplication> &application,
55                      shared_ptr<AbilityRuntime::AbilityHandler> &handler,
56                      const sptr<IRemoteObject> &token)
57 {
58     HILOGI("Init the BackupExtensionAbility(Base)");
59     AbilityRuntime::ExtensionBase<ExtBackupContext>::Init(record, application, handler, token);
60 }
61 
Create(const unique_ptr<AbilityRuntime::Runtime> & runtime)62 ExtBackup *ExtBackup::Create(const unique_ptr<AbilityRuntime::Runtime> &runtime)
63 {
64     if (!runtime) {
65         HILOGD("Create as BackupExtensionAbility(base)");
66         return new ExtBackup();
67     }
68 
69     if (creator_) {
70         HILOGD("Create as BackupExtensionAbility(creater)");
71         return creator_(runtime);
72     }
73 
74     switch (runtime->GetLanguage()) {
75         case AbilityRuntime::Runtime::Language::JS:
76             HILOGD("Create as BackupExtensionAbility(JS)");
77             return ExtBackupJs::Create(runtime);
78 
79         default:
80             HILOGD("Create as BackupExtensionAbility(base)");
81             return new ExtBackup();
82     }
83 }
84 
OnStart(const AAFwk::Want & want)85 void ExtBackup::OnStart(const AAFwk::Want &want)
86 {
87     HILOGI("BackupExtensionAbility was started");
88     Extension::OnStart(want);
89 }
90 
OnCommand(const AAFwk::Want & want,bool restart,int startId)91 void ExtBackup::OnCommand(const AAFwk::Want &want, bool restart, int startId)
92 {
93     HILOGI("BackupExtensionAbility was invoked. restart=%{public}d, startId=%{public}d", restart, startId);
94 
95     // REM: 处理返回结果 ret
96     // REM: 通过杀死进程实现 Stop
97 }
98 
GetUsrConfig() const99 string ExtBackup::GetUsrConfig() const
100 {
101     vector<string> config;
102     AppExecFwk::BundleMgrClient client;
103     BExcepUltils::BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_");
104     const AppExecFwk::AbilityInfo &info = *abilityInfo_;
105     if (!client.GetProfileFromAbility(info, "ohos.extension.backup", config)) {
106         throw BError(BError::Codes::EXT_INVAL_ARG, "Failed to invoke the GetProfileFromAbility method.");
107     }
108     if (config.empty()) {
109         HILOGE("GetUsrConfig empty.");
110     } else {
111         HILOGI("GetUsrConfig:%{public}s", config[0].c_str());
112     }
113 
114     return config.empty() ? "" : config[0];
115 }
116 
AllowToBackupRestore()117 bool ExtBackup::AllowToBackupRestore()
118 {
119     string usrConfig = GetUsrConfig();
120     BJsonCachedEntity<BJsonEntityExtensionConfig> cachedEntity(usrConfig);
121     auto cache = cachedEntity.Structuralize();
122     if (cache.GetAllowToBackupRestore() || WasFromSpecialVersion() || SpecialVersionForCloneAndCloud()) {
123         return true;
124     }
125     return false;
126 }
127 
UseFullBackupOnly(void) const128 bool ExtBackup::UseFullBackupOnly(void) const
129 {
130     string usrConfig = GetUsrConfig();
131     BJsonCachedEntity<BJsonEntityExtensionConfig> cachedEntity(usrConfig);
132     auto cache = cachedEntity.Structuralize();
133     if (cache.GetFullBackupOnly()) {
134         HILOGI("backup use fullBackupOnly.");
135         return true;
136     }
137     HILOGI("backup not use fullBackupOnly.");
138     return false;
139 }
140 
GetExtensionAction() const141 BConstants::ExtensionAction ExtBackup::GetExtensionAction() const
142 {
143     return extAction_;
144 }
145 
VerifyAndGetAction(const AAFwk::Want & want,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)146 BConstants::ExtensionAction ExtBackup::VerifyAndGetAction(const AAFwk::Want &want,
147                                                           std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
148 {
149     string pendingMsg = "Received an empty ability. You must missed the init proc";
150     BExcepUltils::BAssert(abilityInfo, BError::Codes::EXT_INVAL_ARG, pendingMsg);
151     using namespace BConstants;
152     ExtensionAction extAction {want.GetIntParam(EXTENSION_ACTION_PARA, static_cast<int>(ExtensionAction::INVALID))};
153     if (extAction == ExtensionAction::INVALID) {
154         int extActionInt = static_cast<int>(extAction);
155         pendingMsg = string("Want must specify a valid action instead of ").append(to_string(extActionInt));
156         throw BError(BError::Codes::EXT_INVAL_ARG, pendingMsg);
157     }
158     return extAction;
159 }
160 
GetParament(const AAFwk::Want & want)161 ErrCode ExtBackup::GetParament(const AAFwk::Want &want)
162 {
163     if (extAction_ == BConstants::ExtensionAction::RESTORE) {
164         appVersionStr_ = want.GetStringParam(BConstants::EXTENSION_VERSION_NAME_PARA);
165         appVersionCode_ = want.GetLongParam(BConstants::EXTENSION_VERSION_CODE_PARA, 0);
166         restoreType_ = want.GetIntParam(BConstants::EXTENSION_RESTORE_TYPE_PARA, 0);
167         restoreExtInfo_ = want.GetStringParam(BConstants::EXTENSION_RESTORE_EXT_INFO_PARA);
168         HILOGI("restoreExtInfo_ is %{public}s", GetAnonyString(restoreExtInfo_).c_str());
169         HILOGI("Get version %{public}s type %{public}d from want when restore.", appVersionStr_.c_str(), restoreType_);
170     } else if (extAction_ == BConstants::ExtensionAction::BACKUP) {
171         backupExtInfo_ = want.GetStringParam(BConstants::EXTENSION_BACKUP_EXT_INFO_PARA);
172         HILOGI("backupExtInfo_ is %{public}s", backupExtInfo_.c_str());
173     }
174     /* backup don't need parament. */
175     return ERR_OK;
176 }
177 
OnConnect(const AAFwk::Want & want)178 sptr<IRemoteObject> ExtBackup::OnConnect(const AAFwk::Want &want)
179 {
180     try {
181         HILOGI("begin connect");
182         BExcepUltils::BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_");
183         // 发起者必须是备份服务
184         auto extAction = VerifyAndGetAction(want, abilityInfo_);
185         if (extAction_ != BConstants::ExtensionAction::INVALID && extAction == BConstants::ExtensionAction::INVALID &&
186             extAction_ != extAction) {
187             HILOGE("Verification action failed.");
188             return nullptr;
189         }
190         extAction_ = extAction;
191         GetParament(want);
192         // 应用必须配置支持备份恢复
193         if (!AllowToBackupRestore()) {
194             HILOGE("The application does not allow to backup and restore.");
195             return nullptr;
196         }
197 
198         Extension::OnConnect(want);
199 
200         auto remoteObject =
201             sptr<BackupExtExtension>(new BackupExtExtension(std::static_pointer_cast<ExtBackup>(shared_from_this()),
202             want.GetBundle()));
203         return remoteObject->AsObject();
204     } catch (const BError &e) {
205         return nullptr;
206     } catch (const exception &e) {
207         HILOGE("%{public}s", e.what());
208         return nullptr;
209     } catch (...) {
210         HILOGE("");
211         return nullptr;
212     }
213 }
214 
OnDisconnect(const AAFwk::Want & want)215 void ExtBackup::OnDisconnect(const AAFwk::Want &want)
216 {
217     try {
218         HILOGI("begin disconnect");
219         sptr<BackupExtExtension> extExtension = bakExtExtension_.promote();
220         if (extExtension != nullptr) {
221             extExtension->ExtClear();
222         }
223         Extension::OnDisconnect(want);
224         extAction_ = BConstants::ExtensionAction::INVALID;
225         HILOGI("end");
226     } catch (const BError &e) {
227         return;
228     } catch (const exception &e) {
229         HILOGE("%{public}s", e.what());
230         return;
231     } catch (...) {
232         HILOGE("");
233         return;
234     }
235 }
236 
WasFromSpecialVersion(void)237 bool ExtBackup::WasFromSpecialVersion(void)
238 {
239     std::string appVersionFlag_ =
240         appVersionStr_.substr(0, appVersionStr_.find_first_of(BConstants::VERSION_NAME_SEPARATOR_CHAR));
241     if (appVersionFlag_ == BConstants::DEFAULT_VERSION_NAME) {
242         return true;
243     }
244     return false;
245 }
246 
SpecialVersionForCloneAndCloud(void)247 bool ExtBackup::SpecialVersionForCloneAndCloud(void)
248 {
249     std::string appVersionFlag_ =
250         appVersionStr_.substr(0, appVersionStr_.find_first_of(BConstants::VERSION_NAME_SEPARATOR_CHAR));
251     auto iter =
252         find_if(BConstants::DEFAULT_VERSION_NAMES_VEC.begin(), BConstants::DEFAULT_VERSION_NAMES_VEC.end(),
253                 [appVersionFlag {appVersionFlag_}](const auto &versionName) { return versionName == appVersionFlag; });
254     if (iter != BConstants::DEFAULT_VERSION_NAMES_VEC.end()) {
255         return true;
256     }
257     return false;
258 }
259 
RestoreDataReady()260 bool ExtBackup::RestoreDataReady()
261 {
262     return restoreType_ == RestoreTypeEnum::RESTORE_DATA_READDY;
263 }
264 
OnBackup(function<void (ErrCode,std::string)> callback)265 ErrCode ExtBackup::OnBackup(function<void(ErrCode, std::string)> callback)
266 {
267     HILOGI("BackupExtensionAbility(base) OnBackup.");
268     return ERR_OK;
269 }
270 
OnBackup(std::function<void (ErrCode,std::string)> callback,std::function<void (ErrCode,const std::string)> callbackEx)271 ErrCode ExtBackup::OnBackup(std::function<void(ErrCode, std::string)> callback,
272     std::function<void(ErrCode, const std::string)> callbackEx)
273 {
274     HILOGI("BackupExtensionAbility(base) OnBackup with Ex");
275     return ERR_OK;
276 }
277 
OnRestore(function<void (ErrCode,std::string)> callback,std::function<void (ErrCode,const std::string)> callbackEx)278 ErrCode ExtBackup::OnRestore(function<void(ErrCode, std::string)> callback,
279     std::function<void(ErrCode, const std::string)> callbackEx)
280 {
281     HILOGI("BackupExtensionAbility(base) OnRestore with Ex.");
282     return ERR_OK;
283 }
284 
OnRestore(function<void (ErrCode,std::string)> callback)285 ErrCode ExtBackup::OnRestore(function<void(ErrCode, std::string)> callback)
286 {
287     HILOGI("BackupExtensionAbility(base) OnRestore.");
288     return ERR_OK;
289 }
290 
GetBackupInfo(function<void (ErrCode,std::string)> callback)291 ErrCode ExtBackup::GetBackupInfo(function<void(ErrCode, std::string)> callback)
292 {
293     HILOGI("BackupExtensionAbility(base) GetBackupInfo.");
294     return ERR_OK;
295 }
296 
InvokeAppExtMethod(ErrCode errCode,const std::string result)297 ErrCode ExtBackup::InvokeAppExtMethod(ErrCode errCode, const std::string result)
298 {
299     HILOGI("BackupExtensionAbility(base) InvokeAppExtMethod.");
300     return ERR_OK;
301 }
302 
OnProcess(std::function<void (ErrCode,std::string)> callback)303 ErrCode ExtBackup::OnProcess(std::function<void(ErrCode, std::string)> callback)
304 {
305     HILOGI("BackupExtensionAbility(base) OnProcess.");
306     return ERR_OK;
307 }
308 
309 } // namespace OHOS::FileManagement::Backup
310