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 oldBackupVersion_ = want.GetStringParam(BConstants::EXTENSION_OLD_BACKUP_VERSION_PARA);
169 HILOGI("restoreExtInfo_ is %{public}s", GetAnonyString(restoreExtInfo_).c_str());
170 HILOGI("Get version %{public}s type %{public}d from want when restore.", appVersionStr_.c_str(), restoreType_);
171 HILOGI("oldBackupVersion_ is %{public}s", oldBackupVersion_.c_str());
172 } else if (extAction_ == BConstants::ExtensionAction::BACKUP) {
173 backupExtInfo_ = want.GetStringParam(BConstants::EXTENSION_BACKUP_EXT_INFO_PARA);
174 HILOGI("backupExtInfo_ is %{public}s", backupExtInfo_.c_str());
175 }
176 /* backup don't need parament. */
177 return ERR_OK;
178 }
179
OnConnect(const AAFwk::Want & want)180 sptr<IRemoteObject> ExtBackup::OnConnect(const AAFwk::Want &want)
181 {
182 try {
183 HILOGI("begin connect");
184 BExcepUltils::BAssert(abilityInfo_, BError::Codes::EXT_BROKEN_FRAMEWORK, "Invalid abilityInfo_");
185 // 发起者必须是备份服务
186 auto extAction = VerifyAndGetAction(want, abilityInfo_);
187 if (extAction_ != BConstants::ExtensionAction::INVALID && extAction == BConstants::ExtensionAction::INVALID &&
188 extAction_ != extAction) {
189 HILOGE("Verification action failed.");
190 return nullptr;
191 }
192 extAction_ = extAction;
193 GetParament(want);
194 // 应用必须配置支持备份恢复
195 if (!AllowToBackupRestore()) {
196 HILOGE("The application does not allow to backup and restore.");
197 return nullptr;
198 }
199
200 Extension::OnConnect(want);
201
202 auto remoteObject =
203 sptr<BackupExtExtension>(new BackupExtExtension(std::static_pointer_cast<ExtBackup>(shared_from_this()),
204 want.GetBundle()));
205 return remoteObject->AsObject();
206 } catch (const BError &e) {
207 return nullptr;
208 } catch (const exception &e) {
209 HILOGE("%{public}s", e.what());
210 return nullptr;
211 } catch (...) {
212 HILOGE("");
213 return nullptr;
214 }
215 }
216
OnDisconnect(const AAFwk::Want & want)217 void ExtBackup::OnDisconnect(const AAFwk::Want &want)
218 {
219 try {
220 HILOGI("begin disconnect");
221 sptr<BackupExtExtension> extExtension = bakExtExtension_.promote();
222 if (extExtension != nullptr) {
223 extExtension->ExtClear();
224 }
225 Extension::OnDisconnect(want);
226 extAction_ = BConstants::ExtensionAction::INVALID;
227 HILOGI("end");
228 } catch (const BError &e) {
229 return;
230 } catch (const exception &e) {
231 HILOGE("%{public}s", e.what());
232 return;
233 } catch (...) {
234 HILOGE("");
235 return;
236 }
237 }
238
WasFromSpecialVersion(void)239 bool ExtBackup::WasFromSpecialVersion(void)
240 {
241 if (appVersionStr_.empty()) {
242 HILOGE("App version name is empty");
243 return false;
244 }
245 std::string appVersionFlag_ =
246 appVersionStr_.substr(0, appVersionStr_.find_first_of(BConstants::VERSION_NAME_SEPARATOR_CHAR));
247 if (appVersionFlag_ == BConstants::DEFAULT_VERSION_NAME) {
248 return true;
249 }
250 return false;
251 }
252
SpecialVersionForCloneAndCloud(void)253 bool ExtBackup::SpecialVersionForCloneAndCloud(void)
254 {
255 if (appVersionStr_.empty()) {
256 HILOGE("App version name is empty");
257 return false;
258 }
259 std::string appVersionFlag_ =
260 appVersionStr_.substr(0, appVersionStr_.find_first_of(BConstants::VERSION_NAME_SEPARATOR_CHAR));
261 auto iter =
262 find_if(BConstants::DEFAULT_VERSION_NAMES_VEC.begin(), BConstants::DEFAULT_VERSION_NAMES_VEC.end(),
263 [appVersionFlag {appVersionFlag_}](const auto &versionName) { return versionName == appVersionFlag; });
264 if (iter != BConstants::DEFAULT_VERSION_NAMES_VEC.end()) {
265 return true;
266 }
267 return false;
268 }
269
RestoreDataReady()270 bool ExtBackup::RestoreDataReady()
271 {
272 return restoreType_ == RestoreTypeEnum::RESTORE_DATA_READDY;
273 }
274
OnBackup(function<void (ErrCode,std::string)> callback)275 ErrCode ExtBackup::OnBackup(function<void(ErrCode, std::string)> callback)
276 {
277 HILOGI("BackupExtensionAbility(base) OnBackup.");
278 return ERR_OK;
279 }
280
OnBackup(std::function<void (ErrCode,std::string)> callback,std::function<void (ErrCode,const std::string)> callbackEx)281 ErrCode ExtBackup::OnBackup(std::function<void(ErrCode, std::string)> callback,
282 std::function<void(ErrCode, const std::string)> callbackEx)
283 {
284 HILOGI("BackupExtensionAbility(base) OnBackup with Ex");
285 return ERR_OK;
286 }
287
OnRestore(function<void (ErrCode,std::string)> callback,std::function<void (ErrCode,const std::string)> callbackEx)288 ErrCode ExtBackup::OnRestore(function<void(ErrCode, std::string)> callback,
289 std::function<void(ErrCode, const std::string)> callbackEx)
290 {
291 HILOGI("BackupExtensionAbility(base) OnRestore with Ex.");
292 return ERR_OK;
293 }
294
OnRestore(function<void (ErrCode,std::string)> callback)295 ErrCode ExtBackup::OnRestore(function<void(ErrCode, std::string)> callback)
296 {
297 HILOGI("BackupExtensionAbility(base) OnRestore.");
298 return ERR_OK;
299 }
300
GetBackupInfo(function<void (ErrCode,std::string)> callback)301 ErrCode ExtBackup::GetBackupInfo(function<void(ErrCode, std::string)> callback)
302 {
303 HILOGI("BackupExtensionAbility(base) GetBackupInfo.");
304 return ERR_OK;
305 }
306
InvokeAppExtMethod(ErrCode errCode,const std::string result)307 ErrCode ExtBackup::InvokeAppExtMethod(ErrCode errCode, const std::string result)
308 {
309 HILOGI("BackupExtensionAbility(base) InvokeAppExtMethod.");
310 return ERR_OK;
311 }
312
OnProcess(std::function<void (ErrCode,std::string)> callback)313 ErrCode ExtBackup::OnProcess(std::function<void(ErrCode, std::string)> callback)
314 {
315 HILOGI("BackupExtensionAbility(base) OnProcess.");
316 return ERR_OK;
317 }
318
319 } // namespace OHOS::FileManagement::Backup
320