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 "module_ipc/svc_session_manager.h"
17
18 #include <algorithm>
19 #include <cstdint>
20 #include <memory>
21 #include <regex>
22 #include <sstream>
23 #include <string>
24
25 #include "b_error/b_error.h"
26 #include "b_file_info.h"
27 #include "b_json/b_json_entity_caps.h"
28 #include "b_json/b_json_entity_ext_manage.h"
29 #include "b_radar/b_radar.h"
30 #include "b_resources/b_constants.h"
31 #include "b_sa/b_sa_utils.h"
32 #include "b_utils/b_time.h"
33 #include "filemgmt_libhilog.h"
34 #include "module_ipc/service.h"
35 #include "module_ipc/svc_restore_deps_manager.h"
36 #include "unique_fd.h"
37
38 namespace OHOS::FileManagement::Backup {
39 using namespace std;
40
VerifyCallerAndScenario(uint32_t clientToken,IServiceReverse::Scenario scenario) const41 void SvcSessionManager::VerifyCallerAndScenario(uint32_t clientToken, IServiceReverse::Scenario scenario) const
42 {
43 shared_lock<shared_mutex> lock(lock_);
44 if (impl_.scenario != scenario) {
45 HILOGE("Inconsistent scenario, impl scenario:%{public}d", impl_.scenario);
46 AppRadar::Info info("", "", "Inconsistent scenario");
47 AppRadar::GetInstance().RecordDefaultFuncRes(info, "SvcSessionManager::VerifyCallerAndScenario", impl_.userId,
48 BizStageBackup::BIZ_STAGE_PERMISSION_CHECK_FAIL,
49 BError(BError::Codes::SDK_MIXED_SCENARIO).GetCode());
50 throw BError(BError::Codes::SDK_MIXED_SCENARIO);
51 }
52 if (impl_.clientToken != clientToken) {
53 AppRadar::Info info2("", "", "Caller mismatched");
54 AppRadar::GetInstance().RecordDefaultFuncRes(info2, "SvcSessionManager::VerifyCallerAndScenario", impl_.userId,
55 BizStageBackup::BIZ_STAGE_PERMISSION_CHECK_FAIL,
56 BError(BError::Codes::SDK_MIXED_SCENARIO).GetCode());
57 throw BError(BError::Codes::SA_REFUSED_ACT, "Caller mismatched");
58 }
59 HILOGD("Succeed to verify the caller");
60 }
61
GetImpl()62 SvcSessionManager::Impl SvcSessionManager::GetImpl()
63 {
64 return impl_;
65 }
66
GetSessionCnt()67 int SvcSessionManager::GetSessionCnt()
68 {
69 return sessionCnt_.load();
70 }
71
Active(Impl newImpl,bool force)72 ErrCode SvcSessionManager::Active(Impl newImpl, bool force)
73 {
74 unique_lock<shared_mutex> lock(lock_);
75 const Impl &oldImpl = impl_;
76 if (oldImpl.clientToken) {
77 HILOGE("Already have an active session");
78 return BError(BError::Codes::SA_REFUSED_ACT);
79 }
80
81 if (!force && !newImpl.clientToken) {
82 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
83 }
84 if (!force && newImpl.scenario == IServiceReverse::Scenario::UNDEFINED) {
85 throw BError(BError::Codes::SA_INVAL_ARG, "No scenario was specified");
86 }
87
88 if (!force) {
89 InitClient(newImpl);
90 }
91 impl_ = newImpl;
92 IncreaseSessionCnt(__PRETTY_FUNCTION__);
93 return BError(BError::Codes::OK);
94 }
95
Deactive(const wptr<IRemoteObject> & remoteInAction,bool force)96 void SvcSessionManager::Deactive(const wptr<IRemoteObject> &remoteInAction, bool force)
97 {
98 unique_lock<shared_mutex> lock(lock_);
99 if (!impl_.clientToken) {
100 HILOGI("Empty session");
101 return;
102 }
103 if (!force && (!impl_.clientToken || !impl_.clientProxy)) {
104 return;
105 }
106 if (!force && (remoteInAction != impl_.clientProxy->AsObject())) {
107 throw BError(BError::Codes::SA_INVAL_ARG, "Only the client actived the session can deactive it");
108 }
109
110 deathRecipient_ = nullptr;
111 AppRadar::Info info("", "", "deactive session success");
112 if (impl_.scenario == IServiceReverse::Scenario::RESTORE) {
113 AppRadar::GetInstance().RecordRestoreFuncRes(info, "SvcSessionManager::Deactive", impl_.userId,
114 BizStageRestore::BIZ_STAGE_DEACTIVE_SESSION, ERR_OK);
115 } else if (impl_.scenario == IServiceReverse::Scenario::BACKUP) {
116 AppRadar::GetInstance().RecordBackupFuncRes(info, "SvcSessionManager::Deactive", impl_.userId,
117 BizStageBackup::BIZ_STAGE_DEACTIVE_SESSION, ERR_OK);
118 }
119 HILOGI("Succeed to deactive a session");
120 impl_ = {};
121 extConnectNum_ = 0;
122 DecreaseSessionCnt(__PRETTY_FUNCTION__);
123 }
124
VerifyBundleName(string & bundleName)125 void SvcSessionManager::VerifyBundleName(string &bundleName)
126 {
127 shared_lock<shared_mutex> lock(lock_);
128 if (!impl_.clientToken) {
129 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
130 }
131 auto asVerify = [&bundleName](const auto &it) { return it.first == bundleName; };
132 if (none_of(impl_.backupExtNameMap.begin(), impl_.backupExtNameMap.end(), asVerify)) {
133 stringstream ss;
134 ss << "Could not find the " << bundleName << " from current session";
135 throw BError(BError::Codes::SA_REFUSED_ACT, ss.str());
136 }
137 HILOGD("Succeed to verify the bundleName");
138 }
139
GetServiceReverseProxy()140 sptr<IServiceReverse> SvcSessionManager::GetServiceReverseProxy()
141 {
142 unique_lock<shared_mutex> lock(lock_);
143 if (!impl_.clientProxy) {
144 throw BError(BError::Codes::SA_REFUSED_ACT, "Try to deactive an empty session");
145 }
146 return impl_.clientProxy;
147 }
148
GetScenario()149 IServiceReverse::Scenario SvcSessionManager::GetScenario()
150 {
151 shared_lock<shared_mutex> lock(lock_);
152 if (!impl_.clientToken) {
153 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
154 }
155 return impl_.scenario;
156 }
157
GetSessionUserId()158 int32_t SvcSessionManager::GetSessionUserId()
159 {
160 return impl_.userId;
161 }
162
SetSessionUserId(int32_t userId)163 void SvcSessionManager::SetSessionUserId(int32_t userId)
164 {
165 impl_.userId = userId;
166 }
167
OnBundleFileReady(const string & bundleName,const string & fileName)168 bool SvcSessionManager::OnBundleFileReady(const string &bundleName, const string &fileName)
169 {
170 unique_lock<shared_mutex> lock(lock_);
171 if (!impl_.clientToken) {
172 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
173 }
174 HILOGD("Begin, bundleName name is:%{private}s", bundleName.c_str());
175 auto it = impl_.backupExtNameMap.find(bundleName);
176 if (it == impl_.backupExtNameMap.end()) {
177 stringstream ss;
178 ss << "Could not find the " << bundleName << " from current session";
179 throw BError(BError::Codes::SA_REFUSED_ACT, ss.str());
180 }
181
182 // 判断是否结束 通知EXTENTION清理资源 TOOL应用完成备份
183 if (impl_.scenario == IServiceReverse::Scenario::RESTORE || SAUtils::IsSABundleName(bundleName)) {
184 it->second.isBundleFinished = true;
185 return true;
186 } else if (impl_.scenario == IServiceReverse::Scenario::BACKUP) {
187 if (!fileName.empty() && fileName != BConstants::EXT_BACKUP_MANAGE) {
188 auto ret = it->second.fileNameInfo.insert(fileName);
189 if (!ret.second) {
190 it->second.fileNameInfo.erase(fileName);
191 }
192 } else if (fileName.empty()) {
193 it->second.receExtAppDone = true;
194 }
195 if (it->second.receExtManageJson && it->second.fileNameInfo.empty() && it->second.receExtAppDone) {
196 HILOGI("The bundle manage json info and file info support current app done");
197 it->second.isBundleFinished = true;
198 return true;
199 }
200 }
201 HILOGD("End, bundleName name is:%{private}s", bundleName.c_str());
202 return false;
203 }
204
OnBundleExtManageInfo(const string & bundleName,UniqueFd fd)205 UniqueFd SvcSessionManager::OnBundleExtManageInfo(const string &bundleName, UniqueFd fd)
206 {
207 if (!impl_.clientToken) {
208 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
209 }
210 if (impl_.scenario != IServiceReverse::Scenario::BACKUP) {
211 throw BError(BError::Codes::SA_INVAL_ARG, "Invalid Scenario");
212 }
213
214 BJsonCachedEntity<BJsonEntityExtManage> cachedEntity(move(fd));
215 auto cache = cachedEntity.Structuralize();
216 auto info = cache.GetExtManage();
217
218 for (auto &fileName : info) {
219 HILOGE("fileName %{public}s", fileName.data());
220 OnBundleFileReady(bundleName, fileName);
221 }
222
223 unique_lock<shared_mutex> lock(lock_);
224 auto it = GetBackupExtNameMap(bundleName);
225 it->second.receExtManageJson = true;
226 return move(cachedEntity.GetFd());
227 }
228
RemoveExtInfo(const string & bundleName)229 void SvcSessionManager::RemoveExtInfo(const string &bundleName)
230 {
231 HILOGD("svcMrg:RemoveExt, bundleName:%{public}s", bundleName.c_str());
232 unique_lock<shared_mutex> lock(lock_);
233 auto it = impl_.backupExtNameMap.find(bundleName);
234 if (it == impl_.backupExtNameMap.end()) {
235 HILOGI("BackupExtNameMap not contain %{public}s", bundleName.c_str());
236 return;
237 }
238 if (extConnectNum_) {
239 extConnectNum_--;
240 }
241 int32_t &appendNum = impl_.backupExtNameMap[bundleName].appendNum;
242 if (--appendNum > 0) {
243 HILOGI("No need remove bundleName:%{public}s, appendNum=%{public}d", bundleName.c_str(), appendNum);
244 return;
245 }
246 impl_.backupExtNameMap.erase(it);
247 }
248
GetExtConnection(const BundleName & bundleName)249 wptr<SvcBackupConnection> SvcSessionManager::GetExtConnection(const BundleName &bundleName)
250 {
251 HILOGD("svcMrg:GetExt, bundleName:%{public}s", bundleName.c_str());
252 shared_lock<shared_mutex> lock(lock_);
253 if (!impl_.clientToken) {
254 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
255 }
256
257 auto it = GetBackupExtNameMap(bundleName);
258 if (!it->second.backUpConnection) {
259 throw BError(BError::Codes::SA_INVAL_ARG, "Svc backup connection is empty");
260 }
261
262 return wptr(it->second.backUpConnection);
263 }
264
GetSAExtConnection(const BundleName & bundleName)265 std::weak_ptr<SABackupConnection> SvcSessionManager::GetSAExtConnection(const BundleName &bundleName)
266 {
267 HILOGD("svcMrg:GetExt, bundleName:%{public}s", bundleName.c_str());
268 shared_lock<shared_mutex> lock(lock_);
269 if (!impl_.clientToken) {
270 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
271 }
272
273 auto it = GetBackupExtNameMap(bundleName);
274 if (!it->second.saBackupConnection) {
275 throw BError(BError::Codes::SA_INVAL_ARG, "SA backup connection is empty");
276 }
277
278 return std::weak_ptr<SABackupConnection>(it->second.saBackupConnection);
279 }
280
GetBackupAbilityExt(const string & bundleName)281 sptr<SvcBackupConnection> SvcSessionManager::GetBackupAbilityExt(const string &bundleName)
282 {
283 auto callDied = [revPtr {reversePtr_}](const string &&bundleName, bool isSecondCalled = false) {
284 auto revPtrStrong = revPtr.promote();
285 if (!revPtrStrong) {
286 // 服务先于客户端死亡是一种异常场景,但该场景对本流程来说也没什么影响,所以只是简单记录一下
287 HILOGW("It's curious that the backup sa dies before the backup client");
288 return;
289 }
290 revPtrStrong->OnBackupExtensionDied(move(bundleName), isSecondCalled);
291 };
292
293 auto callConnected = [revPtr {reversePtr_}](const string &&bundleName) {
294 auto revPtrStrong = revPtr.promote();
295 if (!revPtrStrong) {
296 // 服务先于客户端死亡是一种异常场景,但该场景对本流程来说也没什么影响,所以只是简单记录一下
297 HILOGW("It's curious that the backup sa dies before the backup client");
298 return;
299 }
300 revPtrStrong->ExtConnectDone(move(bundleName));
301 };
302
303 return sptr<SvcBackupConnection>(new SvcBackupConnection(callDied, callConnected, bundleName));
304 }
305
GetBackupSAExt(const std::string & bundleName)306 std::shared_ptr<SABackupConnection> SvcSessionManager::GetBackupSAExt(const std::string &bundleName)
307 {
308 auto callDied = [revPtr {reversePtr_}](const string &&bundleName) {
309 auto revPtrStrong = revPtr.promote();
310 if (!revPtrStrong) {
311 // 服务先于客户端死亡是一种异常场景,但该场景对本流程来说也没什么影响,所以只是简单记录一下
312 HILOGW("It's curious that the backup sa dies before the backup client");
313 return;
314 }
315 revPtrStrong->OnBackupExtensionDied(move(bundleName));
316 };
317
318 auto callConnected = [revPtr {reversePtr_}](const string &&bundleName) {
319 auto revPtrStrong = revPtr.promote();
320 if (!revPtrStrong) {
321 // 服务先于客户端死亡是一种异常场景,但该场景对本流程来说也没什么影响,所以只是简单记录一下
322 HILOGW("It's curious that the backup sa dies before the backup client");
323 return;
324 }
325 revPtrStrong->ExtConnectDone(move(bundleName));
326 };
327
328 auto callBackup = [revPtr {reversePtr_}](const string &&bundleName, const int &&fd, const std::string result,
329 const ErrCode &&errCode) {
330 auto revPtrStrong = revPtr.promote();
331 if (!revPtrStrong) {
332 // 服务先于客户端死亡是一种异常场景,但该场景对本流程来说也没什么影响,所以只是简单记录一下
333 HILOGW("It's curious that the backup sa dies before the backup client");
334 return;
335 }
336 revPtrStrong->OnSABackup(move(bundleName), move(fd), move(result), move(errCode));
337 };
338
339 auto callRestore = [revPtr {reversePtr_}](const string &&bundleName, const std::string result,
340 const ErrCode &&errCode) {
341 auto revPtrStrong = revPtr.promote();
342 if (!revPtrStrong) {
343 // 服务先于客户端死亡是一种异常场景,但该场景对本流程来说也没什么影响,所以只是简单记录一下
344 HILOGW("It's curious that the backup sa dies before the backup client");
345 return;
346 }
347 revPtrStrong->OnSARestore(move(bundleName), move(result), move(errCode));
348 };
349
350 return std::make_shared<SABackupConnection>(callDied, callConnected, callBackup, callRestore);
351 }
352
DumpInfo(const int fd,const std::vector<std::u16string> & args)353 void SvcSessionManager::DumpInfo(const int fd, const std::vector<std::u16string> &args)
354 {
355 dprintf(fd, "---------------------backup info--------------------\n");
356 dprintf(fd, "Scenario: %d\n", impl_.scenario);
357 }
358
InitClient(Impl & newImpl)359 void SvcSessionManager::InitClient(Impl &newImpl)
360 {
361 if (!newImpl.clientProxy) {
362 throw BError(BError::Codes::SA_INVAL_ARG, "Invalid client");
363 }
364 auto remoteObj = newImpl.clientProxy->AsObject();
365 if (!remoteObj) {
366 throw BError(BError::Codes::SA_BROKEN_IPC, "Proxy's remote object can't be nullptr");
367 }
368
369 auto callback = [revPtr {reversePtr_}](const wptr<IRemoteObject> &obj) {
370 HILOGI("Client died.");
371
372 auto revPtrStrong = revPtr.promote();
373 if (!revPtrStrong) {
374 // 服务先于客户端死亡是一种异常场景,但该场景对本流程来说也没什么影响,所以只是简单记录一下
375 HILOGW("It's curious that the backup sa dies before the backup client");
376 return;
377 }
378 (void)revPtrStrong->SessionDeactive();
379 };
380 deathRecipient_ = sptr(new SvcDeathRecipient(callback));
381 remoteObj->AddDeathRecipient(deathRecipient_);
382 AppRadar::Info info("", "", "active session success");
383 if (newImpl.scenario == IServiceReverse::Scenario::RESTORE) {
384 AppRadar::GetInstance().RecordRestoreFuncRes(info, "SvcSessionManager::InitClient", newImpl.userId,
385 BizStageRestore::BIZ_STAGE_ACTIVE_SESSION, ERR_OK);
386 } else if (newImpl.scenario == IServiceReverse::Scenario::BACKUP) {
387 AppRadar::GetInstance().RecordBackupFuncRes(info, "SvcSessionManager::InitClient", newImpl.userId,
388 BizStageBackup::BIZ_STAGE_ACTIVE_SESSION, ERR_OK);
389 }
390 HILOGI("Succeed to active a session");
391 }
392
SetExtFileNameRequest(const string & bundleName,const string & fileName)393 void SvcSessionManager::SetExtFileNameRequest(const string &bundleName, const string &fileName)
394 {
395 unique_lock<shared_mutex> lock(lock_);
396 if (!impl_.clientToken) {
397 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
398 }
399
400 auto it = GetBackupExtNameMap(bundleName);
401 it->second.fileNameInfo.insert(fileName);
402 }
403
GetExtFileNameRequest(const std::string & bundleName)404 std::set<std::string> SvcSessionManager::GetExtFileNameRequest(const std::string &bundleName)
405 {
406 unique_lock<shared_mutex> lock(lock_);
407 if (!impl_.clientToken) {
408 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
409 }
410
411 if (impl_.scenario != IServiceReverse::Scenario::RESTORE) {
412 throw BError(BError::Codes::SA_INVAL_ARG, "Invalid Scenario");
413 }
414 auto it = GetBackupExtNameMap(bundleName);
415 set<string> fileNameInfo = it->second.fileNameInfo;
416 it->second.fileNameInfo.clear();
417 return fileNameInfo;
418 }
419
GetBackupExtNameMap(const string & bundleName)420 map<BundleName, BackupExtInfo>::iterator SvcSessionManager::GetBackupExtNameMap(const string &bundleName)
421 {
422 auto it = impl_.backupExtNameMap.find(bundleName);
423 if (it == impl_.backupExtNameMap.end()) {
424 stringstream ss;
425 ss << "Could not find the " << bundleName << " from current session";
426 throw BError(BError::Codes::SA_REFUSED_ACT, ss.str());
427 }
428 return it;
429 }
430
GetSchedBundleName(string & bundleName)431 bool SvcSessionManager::GetSchedBundleName(string &bundleName)
432 {
433 unique_lock<shared_mutex> lock(lock_);
434 if (extConnectNum_ >= BConstants::EXT_CONNECT_MAX_COUNT) {
435 return false;
436 }
437
438 for (auto &&it : impl_.backupExtNameMap) {
439 if (it.second.schedAction == BConstants::ServiceSchedAction::WAIT) {
440 bundleName = it.first;
441 if (!it.second.isReadyLaunch) {
442 HILOGE("Current bundle:%{public}s can not sched, baseInfo is not set done", bundleName.c_str());
443 return false;
444 }
445 it.second.schedAction = BConstants::ServiceSchedAction::START;
446 extConnectNum_++;
447 return true;
448 }
449 }
450 return false;
451 }
452
GetServiceSchedAction(const std::string & bundleName)453 BConstants::ServiceSchedAction SvcSessionManager::GetServiceSchedAction(const std::string &bundleName)
454 {
455 shared_lock<shared_mutex> lock(lock_);
456 if (!impl_.clientToken) {
457 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
458 }
459 auto it = GetBackupExtNameMap(bundleName);
460 return it->second.schedAction;
461 }
462
SetServiceSchedAction(const string & bundleName,BConstants::ServiceSchedAction action)463 void SvcSessionManager::SetServiceSchedAction(const string &bundleName, BConstants::ServiceSchedAction action)
464 {
465 unique_lock<shared_mutex> lock(lock_);
466 if (!impl_.clientToken) {
467 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
468 }
469
470 auto it = GetBackupExtNameMap(bundleName);
471 it->second.schedAction = action;
472 if (it->second.schedAction == BConstants::ServiceSchedAction::START) {
473 extConnectNum_++;
474 }
475 }
476
SetBackupExtName(const string & bundleName,const string & backupExtName)477 void SvcSessionManager::SetBackupExtName(const string &bundleName, const string &backupExtName)
478 {
479 unique_lock<shared_mutex> lock(lock_);
480 if (!impl_.clientToken) {
481 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
482 }
483
484 auto it = GetBackupExtNameMap(bundleName);
485 it->second.backupExtName = backupExtName;
486 }
487
GetBackupExtName(const string & bundleName)488 string SvcSessionManager::GetBackupExtName(const string &bundleName)
489 {
490 shared_lock<shared_mutex> lock(lock_);
491 if (!impl_.clientToken) {
492 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
493 }
494
495 auto it = GetBackupExtNameMap(bundleName);
496 return it->second.backupExtName;
497 }
498
SetBackupExtInfo(const string & bundleName,const string & extInfo)499 void SvcSessionManager::SetBackupExtInfo(const string &bundleName, const string &extInfo)
500 {
501 unique_lock<shared_mutex> lock(lock_);
502 if (!impl_.clientToken) {
503 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
504 }
505
506 auto it = GetBackupExtNameMap(bundleName);
507 it->second.extInfo = extInfo;
508 }
509
GetBackupExtInfo(const string & bundleName)510 std::string SvcSessionManager::GetBackupExtInfo(const string &bundleName)
511 {
512 shared_lock<shared_mutex> lock(lock_);
513 if (!impl_.clientToken) {
514 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
515 }
516
517 auto it = GetBackupExtNameMap(bundleName);
518 return it->second.extInfo;
519 }
520
AppendBundles(const vector<BundleName> & bundleNames)521 void SvcSessionManager::AppendBundles(const vector<BundleName> &bundleNames)
522 {
523 unique_lock<shared_mutex> lock(lock_);
524 if (!impl_.clientToken) {
525 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
526 }
527
528 for (auto &&bundleName : bundleNames) {
529 HILOGD("bundleName: %{public}s", bundleName.c_str());
530 BackupExtInfo info {};
531 auto it = impl_.backupExtNameMap.find(bundleName);
532 if (it != impl_.backupExtNameMap.end()) {
533 HILOGI("BackupExtNameMap already contain %{public}s", bundleName.c_str());
534 info.backUpConnection = impl_.backupExtNameMap[bundleName].backUpConnection;
535 info.saBackupConnection = impl_.backupExtNameMap[bundleName].saBackupConnection;
536 info.appendNum = impl_.backupExtNameMap[bundleName].appendNum + 1;
537 impl_.backupExtNameMap[bundleName] = info;
538 continue;
539 }
540 if (SAUtils::IsSABundleName(bundleName)) {
541 info.saBackupConnection = GetBackupSAExt(bundleName);
542 } else {
543 info.backUpConnection = GetBackupAbilityExt(bundleName);
544 }
545 impl_.backupExtNameMap.insert(make_pair(bundleName, info));
546 }
547 impl_.isBackupStart = true;
548 impl_.isAppendFinish = true;
549 }
550
CreateBackupConnection(BundleName & bundleName)551 sptr<SvcBackupConnection> SvcSessionManager::CreateBackupConnection(BundleName &bundleName)
552 {
553 HILOGD("SvcSessionManager::CreateBackupConnection begin.");
554 return GetBackupAbilityExt(bundleName);
555 }
556
Start()557 void SvcSessionManager::Start()
558 {
559 unique_lock<shared_mutex> lock(lock_);
560 if (!impl_.clientToken) {
561 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
562 }
563 impl_.isBackupStart = true;
564 }
565
Finish()566 void SvcSessionManager::Finish()
567 {
568 unique_lock<shared_mutex> lock(lock_);
569 if (!impl_.clientToken) {
570 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
571 }
572 impl_.isAppendFinish = true;
573 }
574
IsOnAllBundlesFinished()575 bool SvcSessionManager::IsOnAllBundlesFinished()
576 {
577 shared_lock<shared_mutex> lock(lock_);
578 if (!impl_.clientToken) {
579 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
580 }
581 bool isAllBundlesFinished = !impl_.backupExtNameMap.size();
582 if (impl_.scenario == IServiceReverse::Scenario::RESTORE) {
583 bool isAllBundlesRestored = SvcRestoreDepsManager::GetInstance().IsAllBundlesRestored();
584 isAllBundlesFinished = (isAllBundlesFinished && isAllBundlesRestored);
585 }
586 HILOGD("isAllBundlesFinished:%{public}d", isAllBundlesFinished);
587 return isAllBundlesFinished;
588 }
589
IsOnOnStartSched()590 bool SvcSessionManager::IsOnOnStartSched()
591 {
592 shared_lock<shared_mutex> lock(lock_);
593 if (!impl_.clientToken) {
594 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
595 }
596 if (impl_.isBackupStart && impl_.backupExtNameMap.size()) {
597 return true;
598 }
599
600 return false;
601 }
602
NeedToUnloadService()603 bool SvcSessionManager::NeedToUnloadService()
604 {
605 unique_lock<shared_mutex> lock(lock_);
606 if (impl_.restoreDataType == RestoreTypeEnum::RESTORE_DATA_READDY) {
607 return false;
608 }
609 bool isNeedToUnloadService = (!impl_.backupExtNameMap.size() && (sessionCnt_.load() <= 0));
610 if (impl_.scenario == IServiceReverse::Scenario::RESTORE) {
611 bool isAllBundlesRestored = SvcRestoreDepsManager::GetInstance().IsAllBundlesRestored();
612 isNeedToUnloadService = (isNeedToUnloadService && isAllBundlesRestored);
613 }
614 HILOGD("isNeedToUnloadService:%{public}d", isNeedToUnloadService);
615 return isNeedToUnloadService;
616 }
617
SetBundleRestoreType(const std::string & bundleName,RestoreTypeEnum restoreType)618 void SvcSessionManager::SetBundleRestoreType(const std::string &bundleName, RestoreTypeEnum restoreType)
619 {
620 unique_lock<shared_mutex> lock(lock_);
621 if (!impl_.clientToken) {
622 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
623 }
624
625 auto it = GetBackupExtNameMap(bundleName);
626 it->second.restoreType = restoreType;
627 }
628
GetBundleRestoreType(const std::string & bundleName)629 RestoreTypeEnum SvcSessionManager::GetBundleRestoreType(const std::string &bundleName)
630 {
631 shared_lock<shared_mutex> lock(lock_);
632 if (!impl_.clientToken) {
633 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
634 }
635
636 auto it = GetBackupExtNameMap(bundleName);
637 return it->second.restoreType;
638 }
639
SetBundleVersionCode(const std::string & bundleName,int64_t versionCode)640 void SvcSessionManager::SetBundleVersionCode(const std::string &bundleName, int64_t versionCode)
641 {
642 unique_lock<shared_mutex> lock(lock_);
643 if (!impl_.clientToken) {
644 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
645 }
646
647 auto it = GetBackupExtNameMap(bundleName);
648 it->second.versionCode = versionCode;
649 }
650
GetBundleVersionCode(const std::string & bundleName)651 int64_t SvcSessionManager::GetBundleVersionCode(const std::string &bundleName)
652 {
653 shared_lock<shared_mutex> lock(lock_);
654 if (!impl_.clientToken) {
655 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
656 }
657
658 auto it = GetBackupExtNameMap(bundleName);
659 return it->second.versionCode;
660 }
661
SetBundleVersionName(const std::string & bundleName,std::string versionName)662 void SvcSessionManager::SetBundleVersionName(const std::string &bundleName, std::string versionName)
663 {
664 unique_lock<shared_mutex> lock(lock_);
665 if (!impl_.clientToken) {
666 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
667 }
668
669 auto it = GetBackupExtNameMap(bundleName);
670 it->second.versionName = versionName;
671 }
672
GetBundleVersionName(const std::string & bundleName)673 std::string SvcSessionManager::GetBundleVersionName(const std::string &bundleName)
674 {
675 shared_lock<shared_mutex> lock(lock_);
676 if (!impl_.clientToken) {
677 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
678 }
679
680 auto it = GetBackupExtNameMap(bundleName);
681 return it->second.versionName;
682 }
683
SetBundleDataSize(const std::string & bundleName,int64_t dataSize)684 void SvcSessionManager::SetBundleDataSize(const std::string &bundleName, int64_t dataSize)
685 {
686 unique_lock<shared_mutex> lock(lock_);
687 if (!impl_.clientToken) {
688 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
689 }
690
691 auto it = GetBackupExtNameMap(bundleName);
692 it->second.dataSize = dataSize;
693 }
694
CalAppProcessTime(const std::string & bundleName)695 uint32_t SvcSessionManager::CalAppProcessTime(const std::string &bundleName)
696 {
697 const int64_t minTimeout = 900; /* 900 second */
698 const int64_t defaultTimeout = 30; /* 30 second */
699 const int64_t processRate = 3 * 1024 * 1024; /* 3M/s */
700 const int64_t multiple = 3;
701 const int64_t invertMillisecond = 1000;
702 int64_t timeout;
703 uint32_t resTimeoutMs;
704
705 try {
706 auto it = GetBackupExtNameMap(bundleName);
707 int64_t appSize = it->second.dataSize;
708 /* timeout = (AppSize / 3Ms) * 3 + 30 */
709 timeout = defaultTimeout + (appSize / processRate) * multiple;
710 } catch (const BError &e) {
711 HILOGE("Failed to get app<%{public}s> dataInfo, err=%{public}d", bundleName.c_str(), e.GetCode());
712 timeout = defaultTimeout;
713 }
714 timeout = timeout < minTimeout ? minTimeout : timeout;
715 resTimeoutMs = (uint32_t)(timeout * invertMillisecond % UINT_MAX); /* conver second to millisecond */
716 HILOGI("Calculate App extension process run timeout=%{public}u(ms), bundleName=%{public}s ", resTimeoutMs,
717 bundleName.c_str());
718 return resTimeoutMs;
719 }
720
StartFwkTimer(const std::string & bundleName,const Utils::Timer::TimerCallback & callback)721 bool SvcSessionManager::StartFwkTimer(const std::string &bundleName, const Utils::Timer::TimerCallback &callback)
722 {
723 unique_lock<shared_mutex> lock(lock_);
724 HILOGI("StartFwkTimer begin bundleName %{public}s", bundleName.c_str());
725 if (!impl_.clientToken) {
726 HILOGE("No caller token was specified");
727 return false;
728 }
729 auto it = GetBackupExtNameMap(bundleName);
730 if (it->second.fwkTimerStatus == true) {
731 HILOGE("FwkTimer is registered, unregister first.");
732 return false;
733 }
734 uint32_t timeout = CalAppProcessTime(bundleName);
735
736 it->second.fwkTimerStatus = true;
737 it->second.timerId = timer_.Register(callback, timeout, true);
738 HILOGI("StartFwkTimer end bundleName %{public}s", bundleName.c_str());
739 return true;
740 }
741
StopFwkTimer(const std::string & bundleName)742 bool SvcSessionManager::StopFwkTimer(const std::string &bundleName)
743 {
744 unique_lock<shared_mutex> lock(lock_);
745 HILOGI("StopFwkTimer begin bundleName %{public}s", bundleName.c_str());
746 if (!impl_.clientToken) {
747 HILOGE("No caller token was specified");
748 return false;
749 }
750 auto it = GetBackupExtNameMap(bundleName);
751 if (it->second.fwkTimerStatus == false) {
752 HILOGE("FwkTimer is unregistered, register first.");
753 return true;
754 }
755
756 it->second.fwkTimerStatus = false;
757 timer_.Unregister(it->second.timerId);
758 HILOGI("StopFwkTimer end bundleName %{public}s", bundleName.c_str());
759 return true;
760 }
761
StartExtTimer(const std::string & bundleName,const Utils::Timer::TimerCallback & callback)762 bool SvcSessionManager::StartExtTimer(const std::string &bundleName, const Utils::Timer::TimerCallback &callback)
763 {
764 unique_lock<shared_mutex> lock(lock_);
765 HILOGI("StartExtTimer begin bundleName %{public}s", bundleName.c_str());
766 if (!impl_.clientToken) {
767 HILOGE("No caller token was specified");
768 return false;
769 }
770 auto it = GetBackupExtNameMap(bundleName);
771 if (it->second.extTimerStatus == true) {
772 HILOGE("ExtTimer is registered, unregister first.");
773 return false;
774 }
775 uint32_t timeout = it->second.timeout;
776 timeout = (timeout != BConstants::TIMEOUT_INVALID) ? timeout : BConstants::DEFAULT_TIMEOUT;
777 it->second.extTimerStatus = true;
778 it->second.timerId = timer_.Register(callback, timeout, true);
779 HILOGI("StartExtTimer end, timeout %{public}u(ms), bundleName %{public}s", timeout, bundleName.c_str());
780 return true;
781 }
782
StopExtTimer(const std::string & bundleName)783 bool SvcSessionManager::StopExtTimer(const std::string &bundleName)
784 {
785 unique_lock<shared_mutex> lock(lock_);
786 HILOGI("StopExtTimer begin bundleName %{public}s", bundleName.c_str());
787 if (!impl_.clientToken) {
788 HILOGE("No caller token was specified");
789 return false;
790 }
791 auto it = GetBackupExtNameMap(bundleName);
792 if (it->second.extTimerStatus == false) {
793 HILOGE("ExtTimer is unregistered, register first.");
794 return true;
795 }
796
797 it->second.extTimerStatus = false;
798 it->second.timeout = BConstants::TIMEOUT_INVALID;
799 timer_.Unregister(it->second.timerId);
800 HILOGI("StopExtTimer end bundleName %{public}s", bundleName.c_str());
801 return true;
802 }
803
UpdateTimer(const std::string & bundleName,uint32_t timeout,const Utils::Timer::TimerCallback & callback)804 bool SvcSessionManager::UpdateTimer(const std::string &bundleName, uint32_t timeout,
805 const Utils::Timer::TimerCallback &callback)
806 {
807 unique_lock<shared_mutex> lock(lock_);
808 HILOGI("UpdateTimer begin bundleName %{public}s", bundleName.c_str());
809 if (!impl_.clientToken) {
810 HILOGE("No caller token was specified");
811 return false;
812 }
813 auto it = GetBackupExtNameMap(bundleName);
814 it->second.timeout = timeout;
815 if (it->second.extTimerStatus == false) {
816 HILOGI("ExtTimer is unregistered, just store timeout %{public}u(ms)", timeout);
817 return true;
818 }
819
820 timer_.Unregister(it->second.timerId);
821 HILOGI("UpdateTimer timeout %{public}u(ms), bundleName %{public}s ", timeout, bundleName.c_str());
822 it->second.timerId = timer_.Register(callback, timeout, true);
823 it->second.extTimerStatus = true;
824 HILOGI("UpdateTimer end bundleName %{public}s", bundleName.c_str());
825 return true;
826 }
827
IncreaseSessionCnt(const std::string funcName)828 void SvcSessionManager::IncreaseSessionCnt(const std::string funcName)
829 {
830 sessionCnt_++;
831 HILOGI("func name:%{public}s, %{public}d.", funcName.c_str(), sessionCnt_.load());
832 }
833
DecreaseSessionCnt(const std::string funcName)834 void SvcSessionManager::DecreaseSessionCnt(const std::string funcName)
835 {
836 if (sessionCnt_.load() > 0) {
837 sessionCnt_--;
838 } else {
839 HILOGE("Invalid sessionCount.");
840 }
841 HILOGI("func name:%{public}s, %{public}d.", funcName.c_str(), sessionCnt_.load());
842 }
843
ClearSessionData()844 ErrCode SvcSessionManager::ClearSessionData()
845 {
846 unique_lock<shared_mutex> lock(lock_);
847 ErrCode ret = BError(BError::Codes::OK);
848 for (auto &&it : impl_.backupExtNameMap) {
849 // clear timer
850 if (it.second.fwkTimerStatus == true || it.second.extTimerStatus == true) {
851 it.second.fwkTimerStatus = false;
852 it.second.extTimerStatus = false;
853 timer_.Unregister(it.second.timerId);
854 }
855 // disconnect extension
856 if (it.second.schedAction == BConstants::ServiceSchedAction::RUNNING) {
857 auto backUpConnection = it.second.backUpConnection;
858 if (backUpConnection == nullptr) {
859 HILOGE("Clear session error, backUpConnection is empty");
860 return BError(BError::Codes::SA_INVAL_ARG);
861 }
862 auto proxy = backUpConnection->GetBackupExtProxy();
863 if (proxy == nullptr) {
864 HILOGE("Clear session error, proxy is empty");
865 return BError(BError::Codes::EXT_INVAL_ARG);
866 }
867 if (impl_.restoreDataType != RestoreTypeEnum::RESTORE_DATA_READDY) {
868 ret = proxy->HandleClear();
869 }
870 backUpConnection->DisconnectBackupExtAbility();
871 }
872 if (ret != BError(BError::Codes::OK)) {
873 return ret;
874 }
875 // clear data
876 it.second.schedAction = BConstants::ServiceSchedAction::FINISH;
877 }
878 impl_.backupExtNameMap.clear();
879 return BError(BError::Codes::OK);
880 }
881
GetIsIncrementalBackup()882 bool SvcSessionManager::GetIsIncrementalBackup()
883 {
884 unique_lock<shared_mutex> lock(lock_);
885 if (!impl_.clientToken) {
886 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
887 }
888 return impl_.isIncrementalBackup;
889 }
890
SetIncrementalData(const BIncrementalData & incrementalData)891 void SvcSessionManager::SetIncrementalData(const BIncrementalData &incrementalData)
892 {
893 unique_lock<shared_mutex> lock(lock_);
894 if (!impl_.clientToken) {
895 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
896 }
897 auto it = GetBackupExtNameMap(incrementalData.bundleName);
898 it->second.lastIncrementalTime = incrementalData.lastIncrementalTime;
899 it->second.manifestFd = incrementalData.manifestFd;
900 it->second.backupParameters = incrementalData.backupParameters;
901 it->second.backupPriority = incrementalData.backupPriority;
902 }
903
GetIncrementalManifestFd(const string & bundleName)904 int32_t SvcSessionManager::GetIncrementalManifestFd(const string &bundleName)
905 {
906 unique_lock<shared_mutex> lock(lock_);
907 if (!impl_.clientToken) {
908 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
909 }
910 auto it = GetBackupExtNameMap(bundleName);
911 return it->second.manifestFd;
912 }
913
GetLastIncrementalTime(const string & bundleName)914 int64_t SvcSessionManager::GetLastIncrementalTime(const string &bundleName)
915 {
916 unique_lock<shared_mutex> lock(lock_);
917 if (!impl_.clientToken) {
918 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
919 }
920 auto it = GetBackupExtNameMap(bundleName);
921 return it->second.lastIncrementalTime;
922 }
923
GetMemParaCurSize()924 int32_t SvcSessionManager::GetMemParaCurSize()
925 {
926 return memoryParaCurSize_;
927 }
928
SetMemParaCurSize(int32_t size)929 void SvcSessionManager::SetMemParaCurSize(int32_t size)
930 {
931 memoryParaCurSize_ = size;
932 }
933
SetClearDataFlag(const std::string & bundleName,bool isClearData)934 void SvcSessionManager::SetClearDataFlag(const std::string &bundleName, bool isClearData)
935 {
936 unique_lock<shared_mutex> lock(lock_);
937 if (!impl_.clientToken) {
938 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
939 }
940 auto it = GetBackupExtNameMap(bundleName);
941 it->second.isClearData = isClearData;
942 HILOGI("bundleName:%{public}s, set clear data flag:%{public}d.", bundleName.c_str(), isClearData);
943 }
GetClearDataFlag(const std::string & bundleName)944 bool SvcSessionManager::GetClearDataFlag(const std::string &bundleName)
945 {
946 unique_lock<shared_mutex> lock(lock_);
947 if (!impl_.clientToken) {
948 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
949 }
950 auto it = GetBackupExtNameMap(bundleName);
951 return it->second.isClearData;
952 }
953
ValidRestoreDataType(RestoreTypeEnum restoreDataType)954 bool SvcSessionManager::ValidRestoreDataType(RestoreTypeEnum restoreDataType)
955 {
956 return impl_.restoreDataType == restoreDataType;
957 }
958
CleanAndCheckIfNeedWait(ErrCode & ret,std::vector<std::string> & bundleNameList)959 bool SvcSessionManager::CleanAndCheckIfNeedWait(ErrCode &ret, std::vector<std::string> &bundleNameList)
960 {
961 unique_lock<shared_mutex> lock(lock_);
962 for (auto it = impl_.backupExtNameMap.begin(); it != impl_.backupExtNameMap.end();) {
963 if (it->second.schedAction == BConstants::ServiceSchedAction::WAIT) {
964 it = impl_.backupExtNameMap.erase(it);
965 } else if (it->second.schedAction == BConstants::ServiceSchedAction::START ||
966 (it->second.schedAction == BConstants::ServiceSchedAction::RUNNING && !it->second.isInPublishFile)) {
967 if (it->second.fwkTimerStatus == true || it->second.extTimerStatus == true) {
968 it->second.fwkTimerStatus = false;
969 it->second.extTimerStatus = false;
970 timer_.Unregister(it->second.timerId);
971 }
972 auto backUpConnection = it->second.backUpConnection;
973 if (backUpConnection == nullptr) {
974 HILOGE("Clear session error, backUpConnection is empty");
975 it = impl_.backupExtNameMap.erase(it);
976 continue;
977 }
978 auto proxy = backUpConnection->GetBackupExtProxy();
979 // start action
980 if (proxy == nullptr) {
981 HILOGE("Clear session error, backUpConnection is empty");
982 backUpConnection->DisconnectBackupExtAbility();
983 it = impl_.backupExtNameMap.erase(it);
984 continue;
985 }
986 // running action
987 ErrCode retTmp = ERR_OK;
988 if (impl_.restoreDataType != RestoreTypeEnum::RESTORE_DATA_READDY) {
989 retTmp = proxy->HandleClear();
990 }
991 if (retTmp == ERR_OK) {
992 bundleNameList.push_back(it->first);
993 } else {
994 ret = retTmp;
995 }
996 backUpConnection->DisconnectBackupExtAbility();
997 it = impl_.backupExtNameMap.erase(it);
998 } else {
999 ++it;
1000 }
1001 }
1002 if (impl_.backupExtNameMap.empty()) {
1003 HILOGI("Release normally, no need wait");
1004 return false;
1005 }
1006 HILOGI("Release abnormally, need wait for restore");
1007 return true;
1008 }
1009
SetPublishFlag(const std::string & bundleName)1010 void SvcSessionManager::SetPublishFlag(const std::string &bundleName)
1011 {
1012 unique_lock<shared_mutex> lock(lock_);
1013 if (!impl_.clientToken) {
1014 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
1015 }
1016 auto it = GetBackupExtNameMap(bundleName);
1017 it->second.isInPublishFile = true;
1018 HILOGE("Set PublishFile success, bundleName = %{public}s", bundleName.c_str());
1019 }
1020
SetImplRestoreType(const RestoreTypeEnum restoreType)1021 void SvcSessionManager::SetImplRestoreType(const RestoreTypeEnum restoreType)
1022 {
1023 impl_.restoreDataType = restoreType;
1024 }
1025
SetIsReadyLaunch(const std::string & bundleName)1026 void SvcSessionManager::SetIsReadyLaunch(const std::string &bundleName)
1027 {
1028 unique_lock<shared_mutex> lock(lock_);
1029 if (!impl_.clientToken) {
1030 throw BError(BError::Codes::SA_INVAL_ARG, "No caller token was specified");
1031 }
1032 auto it = GetBackupExtNameMap(bundleName);
1033 it->second.isReadyLaunch = true;
1034 HILOGE("SetIsReadyLaunch success, bundleName = %{public}s", bundleName.c_str());
1035 }
1036 } // namespace OHOS::FileManagement::Backup
1037