• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2025 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 "mission/distributed_bm_storage.h"
17 
18 #include "datetime_ex.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 
22 #include "distributed_sched_utils.h"
23 #include "dtbschedmgr_device_info_storage.h"
24 #include "dtbschedmgr_log.h"
25 #include "mission/distributed_sched_mission_manager.h"
26 #include "mission/dsched_sync_e2e.h"
27 
28 using namespace OHOS::DistributedKv;
29 
30 namespace OHOS {
31 namespace DistributedSchedule {
32 namespace {
33 const std::string TAG = "DmsBmDataStorage";
34 const std::string BMS_KV_BASE_DIR = "/data/service/el1/public/database/DistributedSchedule";
35 const std::string PUBLIC_RECORDS = "publicRecords";
36 const int32_t EL1 = 1;
37 const int32_t MAX_TIMES = 600;              // 1min
38 const int32_t SLEEP_INTERVAL = 100 * 1000;  // 100ms
39 const int32_t FLAGS = AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES |
40                       AppExecFwk::ApplicationFlag::GET_APPLICATION_INFO_WITH_DISABLE |
41                       AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_DISABLE;
42 }  // namespace
43 
44 std::shared_ptr<DmsBmStorage> DmsBmStorage::instance_ = nullptr;
45 std::mutex DmsBmStorage::mutex_;
46 
DmsBmStorage()47 DmsBmStorage::DmsBmStorage()
48 {
49     HILOGD("called.");
50     TryTwice([this] { return GetKvStore(); });
51     HILOGD("end.");
52 }
53 
~DmsBmStorage()54 DmsBmStorage::~DmsBmStorage()
55 {
56     HILOGD("called.");
57     dataManager_.CloseKvStore(appId_, storeId_);
58     HILOGD("end.");
59 }
60 
GetInstance()61 std::shared_ptr<DmsBmStorage> DmsBmStorage::GetInstance()
62 {
63     HILOGD("called.");
64     std::lock_guard<std::mutex> lock_l(mutex_);
65     if (instance_ == nullptr) {
66         instance_ = std::make_shared<DmsBmStorage>();
67     }
68     HILOGD("end.");
69     return instance_;
70 }
71 
IsContinuable(AppExecFwk::BundleInfo bundleInfo)72 bool IsContinuable(AppExecFwk::BundleInfo bundleInfo)
73 {
74     if (bundleInfo.name == "") {
75         return false;
76     }
77     for (auto abilityInfo : bundleInfo.abilityInfos) {
78         if (abilityInfo.continuable == true) {
79             return true;
80         }
81     }
82     return false;
83 }
84 
SaveStorageDistributeInfo(const std::string & bundleName,bool isPackageChange)85 bool DmsBmStorage::SaveStorageDistributeInfo(const std::string &bundleName, bool isPackageChange)
86 {
87     HILOGI("called.");
88     if (!CheckKvStore()) {
89         HILOGE("kvStore is nullptr");
90         return false;
91     }
92     auto bundleMgr = DmsBmStorage::GetInstance()->GetBundleMgr();
93     if (bundleMgr == nullptr) {
94         HILOGE("Get bundleMgr shared_ptr nullptr");
95         return false;
96     }
97     AppExecFwk::BundleInfo bundleInfo;
98     bool ret = bundleMgr->GetBundleInfo(bundleName, FLAGS, bundleInfo, AppExecFwk::Constants::ALL_USERID);
99     if (!ret || !IsContinuable(bundleInfo)) {
100         HILOGW("GetBundleInfo of %{public}s failed:%{public}d or cannot be continued", bundleName.c_str(), ret);
101         return false;
102     }
103     std::string localUdid;
104     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
105     if (localUdid == "") {
106         HILOGE("GetLocalUdid failed");
107         return false;
108     }
109 
110     AppExecFwk::AppProvisionInfo appProvisionInfo;
111     std::vector<AccountSA::OsAccountInfo> accounts;
112     ErrCode result = AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(accounts);
113     if (result == ERR_OK && !accounts.empty()) {
114         for (auto &account: accounts) {
115             result = bundleMgr->GetAppProvisionInfo(bundleName, account.GetLocalId(), appProvisionInfo);
116             if (result == ERR_OK && !appProvisionInfo.developerId.empty()) {
117                 break;
118             }
119         }
120     }
121 
122     ret = InnerSaveStorageDistributeInfo(
123         ConvertToDistributedBundleInfo(bundleInfo, appProvisionInfo), localUdid);
124     if (!ret) {
125         HILOGW("InnerSaveStorageDistributeInfo:%{public}s  failed", bundleName.c_str());
126         return false;
127     }
128 #ifdef DMS_SYNC_DATA_ON_PACKAGE_EVENT
129     DmsKvSyncE2E::GetInstance()->PushAndPullData();
130 #endif
131     HILOGI("end.");
132     return true;
133 }
134 
UpdatePublicRecords(const std::string & localUdid)135 bool DmsBmStorage::UpdatePublicRecords(const std::string &localUdid)
136 {
137     if (!CheckKvStore()) {
138         HILOGE("kvStore is nullptr");
139         return false;
140     }
141     std::string keyOfPublic = localUdid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
142     Key publicKey(keyOfPublic);
143     PublicRecordsInfo publicRecordsInfo;
144     GetLastBundleNameId(publicRecordsInfo.maxBundleNameId);
145     if (bundleNameIdTables_.empty()) {
146         HILOGE("bundleNameIdTables_ is empty");
147         return false;
148     }
149     publicRecordsInfo.maxBundleNameId =
150         std::max((bundleNameIdTables_.rbegin())->first, publicRecordsInfo.maxBundleNameId);
151     HILOGI("maxBundleNameId = %{public}d", publicRecordsInfo.maxBundleNameId);
152     Value publicValue(publicRecordsInfo.ToString());
153     Status status = kvStorePtr_->Put(publicKey, publicValue);
154     if (status != Status::SUCCESS) {
155         HILOGE("put to kvStore error: %{public}d", status);
156         return false;
157     }
158     return true;
159 }
160 
InnerSaveStorageDistributeInfo(const DmsBundleInfo & distributedBundleInfo,const std::string & localUdid)161 bool DmsBmStorage::InnerSaveStorageDistributeInfo(const DmsBundleInfo &distributedBundleInfo,
162     const std::string &localUdid)
163 
164 {
165     if (distributedBundleInfo.bundleName == "") {
166         HILOGE("The package information is empty and does not need to be stored!");
167         return false;
168     }
169     if (!CheckKvStore()) {
170         HILOGE("kvStore is nullptr");
171         return false;
172     }
173     std::string keyOfData = DeviceAndNameToKey(localUdid, distributedBundleInfo.bundleName);
174     Key key(keyOfData);
175     Value value(distributedBundleInfo.ToString());
176     Status status = kvStorePtr_->Put(key, value);
177     if (status == Status::IPC_ERROR) {
178         status = kvStorePtr_->Put(key, value);
179         HILOGW("distribute database ipc error and try to call again, result = %{public}d", status);
180     }
181     if (status != Status::SUCCESS) {
182         HILOGE("put to kvStore error: %{public}d", status);
183         return false;
184     }
185     UpdatePublicRecords(localUdid);
186     return true;
187 }
188 
DelBundleNameId(const std::string & bundleName)189 void DmsBmStorage::DelBundleNameId(const std::string &bundleName)
190 {
191     std::lock_guard<std::mutex> lock_l(mutex_);
192     for (auto it = bundleNameIdTables_.begin(); it != bundleNameIdTables_.end(); ++it) {
193         if (it->second == bundleName) {
194             it = bundleNameIdTables_.erase(it);
195             HILOGI("DelBundleNameId ok");
196             return;
197         }
198     }
199     HILOGE("DelBundleNameId failed");
200 }
201 
DeleteStorageDistributeInfo(const std::string & bundleName)202 bool DmsBmStorage::DeleteStorageDistributeInfo(const std::string &bundleName)
203 {
204     HILOGI("called.");
205     if (!CheckKvStore()) {
206         HILOGE("kvStore is nullptr");
207         return false;
208     }
209     std::string udid;
210     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(udid);
211     if (udid == "") {
212         HILOGE("GetLocalUdid failed");
213         return false;
214     }
215 
216     auto bundleMgr = DmsBmStorage::GetInstance()->GetBundleMgr();
217     if (bundleMgr == nullptr) {
218         HILOGE("Get bundleMgr shared_ptr nullptr");
219         return false;
220     }
221     AppExecFwk::BundleInfo bundleInfo;
222     bool ret = bundleMgr->GetBundleInfo(bundleName, FLAGS, bundleInfo, AppExecFwk::Constants::ALL_USERID);
223     if (ret) {
224         HILOGW("The bundleInfo exists and does not need to be deleted.");
225         return true;
226     }
227     std::string keyOfData = DeviceAndNameToKey(udid, bundleName);
228     Key key(keyOfData);
229     Status status = kvStorePtr_->Delete(key);
230     if (status == Status::IPC_ERROR) {
231         status = kvStorePtr_->Delete(key);
232         HILOGW("distribute database ipc error and try to call again, result = %{public}d", status);
233     }
234     if (status != Status::SUCCESS) {
235         HILOGE("delete key error: %{public}d", status);
236         return false;
237     }
238 #ifdef DMS_SYNC_DATA_ON_PACKAGE_EVENT
239     DmsKvSyncE2E::GetInstance()->PushAndPullData();
240 #endif
241     HILOGI("delete value to kvStore success");
242     return true;
243 }
244 
GetStorageDistributeInfo(const std::string & networkId,const std::string & bundleName,DmsBundleInfo & info)245 bool DmsBmStorage::GetStorageDistributeInfo(const std::string &networkId,
246     const std::string &bundleName, DmsBundleInfo &info)
247 {
248     HILOGI("called.");
249     if (!CheckKvStore()) {
250         HILOGE("kvStore is nullptr");
251         return false;
252     }
253     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
254     if (udid == "") {
255         HILOGE("can not get udid by networkId");
256         return false;
257     }
258     std::string keyOfData = DeviceAndNameToKey(udid, bundleName);
259     Key key(keyOfData);
260     Value value;
261     std::promise<OHOS::DistributedKv::Status> resultStatusSignal;
262     int64_t begin = GetTickCount();
263     kvStorePtr_->Get(key, networkId,
264         [&value, &resultStatusSignal](Status innerStatus, Value innerValue) {
265             HILOGD("The get, result = %{public}d", innerStatus);
266             if (innerStatus == Status::SUCCESS) {
267                 value = innerValue;
268             }
269             resultStatusSignal.set_value(innerStatus);
270         });
271     Status status = GetResultSatus(resultStatusSignal);
272     HILOGD("GetEntries spend %{public}" PRId64 " ms", GetTickCount() - begin);
273     if (status == Status::SUCCESS) {
274         HILOGD("Get result = ok");
275         info.FromJsonString(value.ToString());
276         return true;
277     }
278     HILOGI("end.");
279     return false;
280 }
281 
DealGetBundleName(const std::string & networkId,const uint16_t & bundleNameId,std::string & bundleName)282 bool DmsBmStorage::DealGetBundleName(const std::string &networkId, const uint16_t& bundleNameId,
283     std::string &bundleName)
284 {
285     HILOGD("networkId: %{public}s  bundleNameId: %{public}d", GetAnonymStr(networkId).c_str(), bundleNameId);
286     if (!CheckKvStore()) {
287         HILOGE("kvStore is nullptr");
288         return false;
289     }
290     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
291     std::string uuid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUuidByNetworkId(networkId);
292     if (udid == "" || uuid == "") {
293         HILOGE("can not get udid or uuid");
294         return false;
295     }
296     HILOGI("uuid: %{public}s", GetAnonymStr(uuid).c_str());
297     std::vector<Entry> remoteEntries;
298     Status status = kvStorePtr_->GetDeviceEntries(uuid, remoteEntries);
299     if (remoteEntries.empty() || status != Status::SUCCESS) {
300         HILOGE("GetDeviceEntries error: %{public}d or remoteEntries is empty", status);
301         return false;
302     }
303 
304     std::vector<Entry> reduRiskEntries;
305     std::string keyOfPublic = udid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
306     for (auto entry : remoteEntries) {
307         std::string key = entry.key.ToString();
308         std::string value =  entry.value.ToString();
309         if (key.find(keyOfPublic) != std::string::npos) {
310             continue;
311         }
312         DmsBundleInfo distributedBundleInfo;
313         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleNameId == bundleNameId) {
314             bundleName = distributedBundleInfo.bundleName;
315             reduRiskEntries.push_back(entry);
316         }
317     }
318     if (reduRiskEntries.size() > 1) {
319         HILOGE("Redundant data needs to be deleted.");
320         DelReduData(networkId, reduRiskEntries);
321         bundleName = "";
322         return false;
323     }
324     if (bundleName.empty()) {
325         HILOGI("get bundleName failed.");
326         return false;
327     }
328     HILOGI("end.");
329     return true;
330 }
331 
DelReduData(const std::string & networkId,const std::vector<DistributedKv::Entry> & reduRiskEntries)332 bool DmsBmStorage::DelReduData(const std::string &networkId, const std::vector<DistributedKv::Entry> &reduRiskEntries)
333 {
334     if (!CheckKvStore()) {
335         HILOGE("kvStore is nullptr");
336         return false;
337     }
338     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
339     std::string uuid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUuidByNetworkId(networkId);
340     if (udid == "" || uuid == "") {
341         HILOGE("can not get udid or uuid by networkId");
342         return false;
343     }
344     HILOGE("uuid: %{public}s", GetAnonymStr(uuid).c_str());
345     std::vector<Entry> newEntries;
346     Status status = kvStorePtr_->GetDeviceEntries(uuid, newEntries);
347     if (newEntries.empty() || status != Status::SUCCESS) {
348         HILOGE("GetEntries error: %{public}d", status);
349         return false;
350     }
351     std::vector<Key> reduKeyArr;
352     std::vector<std::string> newKeyArr;
353     for (auto entry : newEntries) {
354         newKeyArr.push_back(entry.key.ToString());
355         HILOGI("newKey: %{public}s", GetAnonymStr(entry.key.ToString()).c_str());
356     }
357     for (auto reduRiskEntry : reduRiskEntries) {
358         std::string key = reduRiskEntry.key.ToString();
359         if (find(newKeyArr.begin(), newKeyArr.end(), reduRiskEntry.key.ToString()) == newKeyArr.end()) {
360             HILOGE("Needs to be deleted: %{public}s", GetAnonymStr(reduRiskEntry.key.ToString()).c_str());
361             reduKeyArr.push_back(reduRiskEntry.key);
362         }
363     }
364     status = kvStorePtr_->DeleteBatch(reduKeyArr);
365     if (status != Status::SUCCESS) {
366         HILOGE("DeleteBatch error: %{public}d", status);
367         return false;
368     }
369     return true;
370 }
371 
CheckSyncData(const std::string & networkId)372 bool DmsBmStorage::CheckSyncData(const std::string &networkId)
373 {
374     HILOGD("called");
375     std::string uuid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUuidByNetworkId(networkId);
376     if (uuid == "") {
377         HILOGE("can not get udid or uuid by networkId");
378         return false;
379     }
380     HILOGI("uuid: %{public}s", GetAnonymStr(uuid).c_str());
381     std::vector<Entry> newEntries;
382     if (kvStorePtr_ == nullptr) {
383         HILOGE("kvstore is null");
384         return false;
385     }
386     Status status = kvStorePtr_->GetDeviceEntries(uuid, newEntries);
387     if (newEntries.empty() || status != Status::SUCCESS) {
388         HILOGE("CheckSyncData fail: %{public}d", status);
389         return false;
390     }
391     return true;
392 }
393 
GetDistributedBundleName(const std::string & networkId,const uint16_t & bundleNameId,std::string & bundleName)394 bool DmsBmStorage::GetDistributedBundleName(const std::string &networkId, const uint16_t& bundleNameId,
395     std::string &bundleName)
396 {
397     HILOGD("networkId: %{public}s  bundleNameId: %{public}d", GetAnonymStr(networkId).c_str(), bundleNameId);
398     if (!CheckSyncData(networkId)) {
399         HILOGE("CheckSyncData fail");
400         return false;
401     }
402     bool ret = DealGetBundleName(networkId, bundleNameId, bundleName);
403     if (!ret || bundleName == "") {
404         HILOGE("get bundleName failed: %{public}d", ret);
405         return false;
406     }
407     HILOGD("end.");
408     return true;
409 }
410 
GetDistributedBundleInfo(const std::string & networkId,const uint16_t & bundleNameId,DmsBundleInfo & distributeBundleInfo)411 bool DmsBmStorage::GetDistributedBundleInfo(const std::string &networkId,
412     const uint16_t &bundleNameId, DmsBundleInfo &distributeBundleInfo)
413 {
414     HILOGD("networkId: %{public}s  bundleNameId: %{public}d", GetAnonymStr(networkId).c_str(), bundleNameId);
415     if (!CheckKvStore()) {
416         HILOGE("kvStore is nullptr");
417         return false;
418     }
419     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
420     std::string uuid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUuidByNetworkId(networkId);
421     if (udid == "" || uuid == "") {
422         HILOGE("can not get udid or uuid");
423         return false;
424     }
425     HILOGI("uuid: %{public}s", GetAnonymStr(uuid).c_str());
426     std::vector<Entry> remoteEntries;
427     Status status = kvStorePtr_->GetDeviceEntries(uuid, remoteEntries);
428     if (remoteEntries.empty() || status != Status::SUCCESS) {
429         HILOGE("GetDeviceEntries error: %{public}d or remoteEntries is empty", status);
430         return false;
431     }
432 
433     std::vector<Entry> reduRiskEntries;
434     std::string keyOfPublic = udid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
435     for (auto entry: remoteEntries) {
436         std::string key = entry.key.ToString();
437         std::string value = entry.value.ToString();
438         if (key.find(keyOfPublic) != std::string::npos) {
439             continue;
440         }
441         DmsBundleInfo distributedBundleInfoTmp;
442         if (distributedBundleInfoTmp.FromJsonString(value)
443             && distributedBundleInfoTmp.bundleNameId == bundleNameId) {
444             distributeBundleInfo = distributedBundleInfoTmp;
445             reduRiskEntries.push_back(entry);
446         }
447     }
448     if (reduRiskEntries.size() > 1) {
449         HILOGE("Redundant data needs to be deleted.");
450         DelReduData(networkId, reduRiskEntries);
451         distributeBundleInfo = DmsBundleInfo();
452         return false;
453     }
454     if (reduRiskEntries.empty()) {
455         HILOGE("get distributedBundleInfo failed.");
456         return false;
457     }
458     HILOGD("end.");
459     return true;
460 }
461 
GetDistributedBundleInfo(const std::string & networkId,const std::string & bundleName,DmsBundleInfo & distributeBundleInfo)462 bool DmsBmStorage::GetDistributedBundleInfo(const std::string &networkId, const std::string &bundleName,
463     DmsBundleInfo &distributeBundleInfo)
464 {
465     HILOGD("networkId: %{public}s  bundleNameId: %{public}s", GetAnonymStr(networkId).c_str(), bundleName.c_str());
466     if (!CheckKvStore()) {
467         HILOGE("kvStore is nullptr");
468         return false;
469     }
470     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
471     std::string uuid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUuidByNetworkId(networkId);
472     if (udid == "" || uuid == "") {
473         HILOGE("can not get udid or uuid");
474         return false;
475     }
476     HILOGI("uuid: %{public}s", GetAnonymStr(uuid).c_str());
477     std::vector<Entry> remoteEntries;
478     Status status = kvStorePtr_->GetDeviceEntries(uuid, remoteEntries);
479     if (remoteEntries.empty() || status != Status::SUCCESS) {
480         HILOGE("GetDeviceEntries error: %{public}d or remoteEntries is empty", status);
481         return false;
482     }
483 
484     std::vector<Entry> reduRiskEntries;
485     std::string keyOfPublic = udid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
486     for (auto entry: remoteEntries) {
487         std::string key = entry.key.ToString();
488         std::string value = entry.value.ToString();
489         if (key.find(keyOfPublic) != std::string::npos) {
490             continue;
491         }
492         DmsBundleInfo distributedBundleInfoTmp;
493         if (distributedBundleInfoTmp.FromJsonString(value)
494             && distributedBundleInfoTmp.bundleName == bundleName) {
495             distributeBundleInfo = distributedBundleInfoTmp;
496             reduRiskEntries.push_back(entry);
497         }
498     }
499     if (reduRiskEntries.size() > 1) {
500         HILOGE("Redundant data needs to be deleted.");
501         DelReduData(networkId, reduRiskEntries);
502         distributeBundleInfo = DmsBundleInfo();
503         return false;
504     }
505     if (reduRiskEntries.empty()) {
506         HILOGE("get distributedBundleInfo failed.");
507         return false;
508     }
509     HILOGD("end.");
510     return true;
511 }
512 
GetDistributeInfosByNetworkId(const std::string & networkId,std::vector<DmsBundleInfo> & infos)513 bool DmsBmStorage::GetDistributeInfosByNetworkId(const std::string &networkId, std::vector<DmsBundleInfo> &infos)
514 {
515     HILOGD("networkId: %{public}s", GetAnonymStr(networkId).c_str());
516     if (!CheckKvStore()) {
517         HILOGE("kvStore is nullptr");
518         return false;
519     }
520     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
521     std::string uuid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUuidByNetworkId(networkId);
522     if (udid == "" || uuid == "") {
523         HILOGE("can not get udid or uuid");
524         return false;
525     }
526     HILOGI("uuid: %{public}s", GetAnonymStr(uuid).c_str());
527     std::vector<Entry> remoteEntries;
528     Status status = kvStorePtr_->GetDeviceEntries(uuid, remoteEntries);
529     if (remoteEntries.empty() || status != Status::SUCCESS) {
530         HILOGE("GetDeviceEntries error: %{public}d or remoteEntries is empty", status);
531         return false;
532     }
533 
534     std::string keyOfPublic = udid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
535     for (auto& entry: remoteEntries) {
536         std::string key = entry.key.ToString();
537         std::string value = entry.value.ToString();
538         if (key.find(keyOfPublic) != std::string::npos) {
539             continue;
540         }
541         DmsBundleInfo info;
542         if (info.FromJsonString(value)) {
543             infos.push_back(info);
544         }
545     }
546     HILOGD("end.");
547     return true;
548 }
549 
GetResultSatus(std::promise<OHOS::DistributedKv::Status> & resultStatusSignal)550 Status DmsBmStorage::GetResultSatus(std::promise<OHOS::DistributedKv::Status> &resultStatusSignal)
551 {
552     auto future = resultStatusSignal.get_future();
553     if (future.wait_for(std::chrono::seconds(waittingTime_)) == std::future_status::ready) {
554         Status status = future.get();
555         return status;
556     }
557     return Status::ERROR;
558 }
559 
GetEntries(const std::string & networkId,const Key & allEntryKeyPrefix,std::promise<OHOS::DistributedKv::Status> & resultStatusSignal,std::vector<Entry> & allEntries)560 void DmsBmStorage::GetEntries(const std::string &networkId, const Key &allEntryKeyPrefix,
561     std::promise<OHOS::DistributedKv::Status> &resultStatusSignal, std::vector<Entry> &allEntries)
562 {
563     HILOGD("called.");
564     if (kvStorePtr_ == nullptr) {
565         HILOGE("kvstore is null");
566         return;
567     }
568     kvStorePtr_->GetEntries(allEntryKeyPrefix, networkId,
569         [&resultStatusSignal, &allEntries](Status innerStatus, std::vector<Entry> innerAllEntries) {
570             HILOGD("GetEntries, result = %{public}d", innerStatus);
571             if (innerStatus == Status::SUCCESS) {
572                 std::copy(innerAllEntries.begin(), innerAllEntries.end(), std::back_inserter(allEntries));
573             }
574             resultStatusSignal.set_value(innerStatus);
575         });
576     HILOGD("end.");
577 }
578 
GetBundleNameId(const std::string & bundleName,uint16_t & bundleNameId)579 bool DmsBmStorage::GetBundleNameId(const std::string& bundleName, uint16_t &bundleNameId)
580 {
581     HILOGD("called.");
582     if (!CheckKvStore()) {
583         HILOGE("kvStore is nullptr");
584         return false;
585     }
586     std::string localUdid;
587     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
588     if (localUdid == "") {
589         HILOGE("can not get localUdid by networkId");
590         return false;
591     }
592     Key key(DeviceAndNameToKey(localUdid, bundleName));
593     Value value;
594     Status status = kvStorePtr_->Get(key, value);
595     if (status != Status::SUCCESS) {
596         HILOGW("BundleNameId not found, Get result: %{public}d", status);
597         return false;
598     }
599     DmsBundleInfo distributedBundleInfo;
600     if (distributedBundleInfo.FromJsonString(value.ToString()) && distributedBundleInfo.bundleName == bundleName) {
601         bundleNameId = distributedBundleInfo.bundleNameId;
602         HILOGD("end.");
603         return true;
604     }
605     HILOGE("get distributed bundleName no matching data: %{public}s %{public}d", GetAnonymStr(localUdid).c_str(),
606         bundleNameId);
607     return false;
608 }
609 
DeviceAndNameToKey(const std::string & udid,const std::string & bundleName) const610 std::string DmsBmStorage::DeviceAndNameToKey(const std::string &udid, const std::string &bundleName) const
611 {
612     std::string key = udid + AppExecFwk::Constants::FILE_UNDERLINE + bundleName;
613     return key;
614 }
615 
CheckKvStore()616 bool DmsBmStorage::CheckKvStore()
617 {
618     HILOGD("called.");
619     std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
620     if (kvStorePtr_ != nullptr) {
621         return true;
622     }
623     int32_t tryTimes = MAX_TIMES;
624     while (tryTimes > 0) {
625         Status status = GetKvStore();
626         if (status == Status::SUCCESS && kvStorePtr_ != nullptr) {
627             return true;
628         }
629         HILOGW("CheckKvStore, Times: %{public}d", tryTimes);
630         usleep(SLEEP_INTERVAL);
631         tryTimes--;
632     }
633     HILOGD("end.");
634     return kvStorePtr_ != nullptr;
635 }
636 
GetKvStore()637 Status DmsBmStorage::GetKvStore()
638 {
639     HILOGI("called.");
640     Options options = {
641         .createIfMissing = true,
642         .encrypt = false,
643         .autoSync = false,
644         .isPublic = true,
645         .securityLevel = SecurityLevel::S1,
646         .area = EL1,
647         .kvStoreType = KvStoreType::SINGLE_VERSION,
648         .baseDir = BMS_KV_BASE_DIR,
649         .dataType = DataType::TYPE_DYNAMICAL,
650         .cloudConfig = {
651             .enableCloud = true,
652             .autoSync = true
653         },
654     };
655     Status status = dataManager_.GetSingleKvStore(options, appId_, storeId_, kvStorePtr_);
656     if (status == Status::SUCCESS) {
657         HILOGI("get kvStore success");
658     } else if (status == DistributedKv::Status::STORE_META_CHANGED) {
659         HILOGE("This db meta changed, remove and rebuild it");
660         dataManager_.DeleteKvStore(appId_, storeId_, BMS_KV_BASE_DIR + appId_.appId);
661     }
662     HILOGI("end.");
663     return status;
664 }
665 
TryTwice(const std::function<Status ()> & func) const666 void DmsBmStorage::TryTwice(const std::function<Status()> &func) const
667 {
668     HILOGD("called.");
669     Status status = func();
670     if (status == Status::IPC_ERROR) {
671         status = func();
672         HILOGW("distribute database ipc error and try to call again, result = %{public}d", status);
673     }
674     HILOGD("end.");
675 }
676 
GetLastBundleNameId(uint16_t & bundleNameId)677 bool DmsBmStorage::GetLastBundleNameId(uint16_t &bundleNameId)
678 {
679     HILOGI("call.");
680     std::string localUdid;
681     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
682     if (localUdid == "") {
683         HILOGE("GetLocalUdid failed");
684         return false;
685     }
686     if (!CheckKvStore()) {
687         HILOGE("kvStore is nullptr");
688         return false;
689     }
690     std::string keyOfPublic = localUdid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
691     Key publicKey(keyOfPublic);
692     Value value;
693     Status status = kvStorePtr_->Get(publicKey, value);
694     if (status != Status::SUCCESS) {
695         HILOGW("This information not be found in the database, Get error: %{public}d", status);
696         return false;
697     }
698     PublicRecordsInfo publicRecordsInfo;
699     if (publicRecordsInfo.FromJsonString(value.ToString())) {
700         bundleNameId = publicRecordsInfo.maxBundleNameId;
701         HILOGI("bundleNameId: %{public}d", bundleNameId);
702         return true;
703     }
704     return false;
705 }
706 
CreateBundleNameId(const std::string & bundleName,bool isPackageChange)707 uint16_t DmsBmStorage::CreateBundleNameId(const std::string &bundleName, bool isPackageChange)
708 {
709     HILOGI("called.");
710     uint16_t bundleNameId = 0;
711     if (isPackageChange && GetBundleNameId(bundleName, bundleNameId)) {
712         HILOGI("The bundleNameId: %{public}d already exists in the bundleName.", bundleNameId);
713         return bundleNameId;
714     }
715     if (bundleNameIdTables_.empty()) {
716         HILOGI("Encode from the first one.");
717         std::lock_guard<std::mutex> lock_l(mutex_);
718         bundleNameIdTables_.insert(std::make_pair(bundleNameId, bundleName));
719         return bundleNameId;
720     }
721     uint16_t lastBundleNameId = 0;
722     GetLastBundleNameId(lastBundleNameId);
723     lastBundleNameId = std::max((bundleNameIdTables_.rbegin())->first, lastBundleNameId);
724     if (lastBundleNameId < MAX_BUNDLEID) {
725         HILOGI("Add bundleNameId: %{public}d", lastBundleNameId + 1);
726         std::lock_guard<std::mutex> lock_l(mutex_);
727         bundleNameIdTables_.insert(std::make_pair(lastBundleNameId + 1, bundleName));
728         return lastBundleNameId + 1;
729     }
730     HILOGE("The bundleNameId exceeds the maximum value! Delete the local data and re-create the data.");
731     RebuildLocalData();
732     GetBundleNameId(bundleName, bundleNameId);
733     return bundleNameId;
734 }
735 
RebuildLocalData()736 bool DmsBmStorage::RebuildLocalData()
737 {
738     HILOGE("called.");
739     std::string localUdid;
740     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
741     if (localUdid == "") {
742         HILOGE("GetLocalUdid failed");
743         return false;
744     }
745     if (!CheckKvStore()) {
746         HILOGE("kvStore is nullptr");
747         return false;
748     }
749     Key allEntryKeyPrefix(localUdid);
750     std::vector<Entry> allEntries;
751     Status status = kvStorePtr_->GetEntries(allEntryKeyPrefix, allEntries);
752     if (status != Status::SUCCESS) {
753         HILOGE("GetEntries error: %{public}d", status);
754         return false;
755     }
756     std::vector<Key> keyArr;
757     for (const auto &entry : allEntries) {
758         keyArr.push_back(entry.key);
759     }
760     status = kvStorePtr_->DeleteBatch(keyArr);
761     if (status != Status::SUCCESS) {
762         HILOGE("DeleteBatch error: %{public}d", status);
763         return false;
764     }
765     bundleNameIdTables_.clear();
766     UpdateDistributedData();
767     return true;
768 }
769 
ConvertToDistributedBundleInfo(const AppExecFwk::BundleInfo & bundleInfo,AppExecFwk::AppProvisionInfo appProvisionInfo,bool isPackageChange)770 DmsBundleInfo DmsBmStorage::ConvertToDistributedBundleInfo(const AppExecFwk::BundleInfo &bundleInfo,
771     AppExecFwk::AppProvisionInfo appProvisionInfo, bool isPackageChange)
772 {
773     DmsBundleInfo distributedBundleInfo;
774     if (bundleInfo.name == "") {
775         HILOGE("The bundleName is empty and does not require conversion!");
776         return distributedBundleInfo;
777     }
778     distributedBundleInfo.bundleName = bundleInfo.name;
779     distributedBundleInfo.versionCode = bundleInfo.versionCode;
780     distributedBundleInfo.compatibleVersionCode = bundleInfo.compatibleVersion;
781     distributedBundleInfo.versionName = bundleInfo.versionName;
782     distributedBundleInfo.minCompatibleVersion = bundleInfo.minCompatibleVersionCode;
783     distributedBundleInfo.targetVersionCode = bundleInfo.targetVersion;
784     distributedBundleInfo.appId = bundleInfo.appId;
785     distributedBundleInfo.enabled = bundleInfo.applicationInfo.enabled;
786     distributedBundleInfo.bundleNameId = CreateBundleNameId(bundleInfo.name, isPackageChange);
787     distributedBundleInfo.updateTime = bundleInfo.updateTime;
788     distributedBundleInfo.developerId = appProvisionInfo.developerId;
789     uint8_t pos = 0;
790     for (const auto &abilityInfo : bundleInfo.abilityInfos) {
791         DmsAbilityInfo dmsAbilityInfo;
792         dmsAbilityInfo.abilityName = abilityInfo.name;
793         for (const auto &continueType : abilityInfo.continueType) {
794             dmsAbilityInfo.continueType.push_back(continueType);
795             dmsAbilityInfo.continueTypeId.push_back(pos++);
796         }
797         dmsAbilityInfo.moduleName = abilityInfo.moduleName;
798         for (const auto &item: abilityInfo.continueBundleNames) {
799             dmsAbilityInfo.continueBundleName.push_back(item);
800         }
801         distributedBundleInfo.dmsAbilityInfos.push_back(dmsAbilityInfo);
802     }
803     return distributedBundleInfo;
804 }
805 
GetBundleMgr()806 OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> DmsBmStorage::GetBundleMgr()
807 {
808     HILOGD("called.");
809     if (bundleMgr_ == nullptr) {
810         if (bundleMgr_ == nullptr) {
811             auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
812             if (systemAbilityManager == nullptr) {
813                 HILOGE("GetBundleMgr GetSystemAbilityManager is null");
814                 return nullptr;
815             }
816             auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
817             if (bundleMgrSa == nullptr) {
818                 HILOGE("GetBundleMgr GetSystemAbility is null");
819                 return nullptr;
820             }
821             bundleMgr_ = OHOS::iface_cast<AppExecFwk::IBundleMgr>(bundleMgrSa);
822         }
823     }
824     HILOGD("end.");
825     return bundleMgr_;
826 }
827 
CloudSync()828 int32_t DmsBmStorage::CloudSync()
829 {
830     HILOGI("called.");
831     if (!CheckKvStore()) {
832         HILOGE("kvStore is nullptr");
833         return INVALID_REMOTE_PARAMETERS_ERR;
834     }
835     Status status = kvStorePtr_->CloudSync(nullptr);
836     if (status != Status::SUCCESS) {
837         HILOGE("Cloud sync failed, error = %{public}d", status);
838     } else {
839         HILOGI("Cloud synchronizing");
840     }
841     HILOGD("end.");
842     return static_cast<int32_t>(status);
843 }
844 
FindProvishionInfo(OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> bundleMgr,AppExecFwk::AppProvisionInfo & appProvisionInfo,std::vector<AccountSA::OsAccountInfo> accounts,int32_t result,const std::string & bundleName)845 void DmsBmStorage::FindProvishionInfo(OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> bundleMgr,
846     AppExecFwk::AppProvisionInfo &appProvisionInfo, std::vector<AccountSA::OsAccountInfo> accounts,
847     int32_t result, const std::string& bundleName)
848 {
849     if (result == ERR_OK && !accounts.empty()) {
850         for (auto &account: accounts) {
851             result = bundleMgr->GetAppProvisionInfo(bundleName, account.GetLocalId(), appProvisionInfo);
852             if (result == ERR_OK && !appProvisionInfo.developerId.empty()) {
853                 break;
854             }
855         }
856     }
857 }
858 
UpdateDistributedData()859 void DmsBmStorage::UpdateDistributedData()
860 {
861     HILOGI("called.");
862     auto bundleMgr = DmsBmStorage::GetInstance()->GetBundleMgr();
863     if (bundleMgr == nullptr) {
864         HILOGE("Get bundleMgr shared_ptr nullptr");
865         return;
866     }
867     std::vector<AppExecFwk::BundleInfo> bundleInfos;
868     if (!bundleMgr->GetBundleInfosForContinuation(FLAGS, bundleInfos, AppExecFwk::Constants::ALL_USERID)) {
869         HILOGE("get bundleInfos failed");
870         return;
871     }
872     HILOGI("bundleInfos size: %{public}zu", bundleInfos.size());
873     std::vector<std::string> bundleNames;
874     for (const auto &bundleInfo : bundleInfos) {
875         bundleNames.push_back(bundleInfo.name);
876     }
877     std::map<std::string, DmsBundleInfo> oldDistributedBundleInfos =
878         GetAllOldDistributionBundleInfo(bundleNames);
879     AppExecFwk::AppProvisionInfo appProvisionInfo;
880     std::vector<AccountSA::OsAccountInfo> accounts;
881     int32_t result = AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(accounts);
882     std::string localUdid;
883     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
884     std::vector<DmsBundleInfo> dmsBundleInfos;
885     for (const auto &bundleInfo: bundleInfos) {
886         std::string keyOfKVStore = oldDistributedBundleInfos[bundleInfo.name].keyOfKVStore;
887         FindProvishionInfo(bundleMgr, appProvisionInfo, accounts, result, bundleInfo.name);
888         if (oldDistributedBundleInfos.find(bundleInfo.name) != oldDistributedBundleInfos.end()) {
889             int64_t updateTime = oldDistributedBundleInfos[bundleInfo.name].updateTime;
890             std::string oldUdid = keyOfKVStore.substr(0, localUdid.length());
891             if (updateTime != bundleInfo.updateTime || (!localUdid.empty() && oldUdid != localUdid)
892             || oldDistributedBundleInfos[bundleInfo.name].developerId.empty()) {
893                 DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo, appProvisionInfo, true);
894                 dmsBundleInfos.push_back(dmsBundleInfo);
895             }
896             CleanRedundancyBundleInfo(localUdid, bundleInfo.name, keyOfKVStore, oldUdid);
897             continue;
898         }
899         DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo, appProvisionInfo);
900         if (dmsBundleInfo.bundleName == "") {
901             HILOGE("The package information is empty and does not need to be stored!");
902             continue;
903         }
904         dmsBundleInfos.push_back(dmsBundleInfo);
905     }
906     DmsPutBatch(dmsBundleInfos);
907     HILOGI("end.");
908 }
909 
CleanRedundancyBundleInfo(const std::string & localUdid,const std::string bundleName,const std::string & keyOfKVStore,const std::string & oldUdid) const910 void DmsBmStorage::CleanRedundancyBundleInfo(const std::string &localUdid, const std::string bundleName,
911     const std::string &keyOfKVStore, const std::string &oldUdid) const
912 {
913     if (!localUdid.empty() && oldUdid != localUdid) {
914         HILOGW("Delete DistributedBundleInfo for old udid: %{public}s, bundleName: %{public}s, new udid: %{public}s",
915             GetAnonymStr(oldUdid).c_str(), bundleName.c_str(), GetAnonymStr(localUdid).c_str());
916         Key key(keyOfKVStore);
917         kvStorePtr_->Delete(key);
918     }
919 }
920 
DmsPutBatch(const std::vector<DmsBundleInfo> & dmsBundleInfos)921 void DmsBmStorage::DmsPutBatch(const std::vector<DmsBundleInfo> &dmsBundleInfos)
922 {
923     HILOGI("called.");
924     if (dmsBundleInfos.empty()) {
925         HILOGI("Data not updated, no need to write");
926         return;
927     }
928     if (!CheckKvStore()) {
929         HILOGE("kvStore is nullptr");
930         return;
931     }
932     std::string localUdid;
933     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
934     if (localUdid == "") {
935         HILOGE("GetLocalUdid failed");
936         return;
937     }
938     std::vector<Entry> entries;
939     for (const auto &dmsBundleInfo : dmsBundleInfos) {
940         Entry entrie;
941         std::string keyOfData = DeviceAndNameToKey(localUdid, dmsBundleInfo.bundleName);
942         Key key(keyOfData);
943         entrie.key = key;
944         Value value(dmsBundleInfo.ToString());
945         entrie.value = value;
946         HILOGI("need be put: %{public}s, developer id: %{public}s", dmsBundleInfo.bundleName.c_str(),
947             GetAnonymStr(dmsBundleInfo.developerId).c_str());
948         entries.push_back(entrie);
949     }
950     Entry entrie;
951     std::string keyOfData = localUdid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
952     Key key(keyOfData);
953     entrie.key = key;
954     PublicRecordsInfo publicRecordsInfo;
955     GetLastBundleNameId(publicRecordsInfo.maxBundleNameId);
956     publicRecordsInfo.maxBundleNameId = bundleNameIdTables_.empty() ? publicRecordsInfo.maxBundleNameId : std::max(
957         (bundleNameIdTables_.rbegin())->first, publicRecordsInfo.maxBundleNameId);
958     Value value(publicRecordsInfo.ToString());
959     entrie.value = value;
960     HILOGI("need be put: %{public}d", publicRecordsInfo.maxBundleNameId);
961     entries.push_back(entrie);
962     Status status = kvStorePtr_->PutBatch(entries);
963     if (status == Status::IPC_ERROR) {
964         status = kvStorePtr_->PutBatch(entries);
965         HILOGW("distribute database ipc error and try to call again, result = %{public}d", status);
966     }
967     SyncBundleInfoData(entries);
968     HILOGI("end.");
969 }
970 
SyncBundleInfoData(std::vector<DistributedKv::Entry> & entries)971 void DmsBmStorage::SyncBundleInfoData(std::vector<DistributedKv::Entry> &entries)
972 {
973 #ifdef DMS_SYNC_DATA_ON_PACKAGE_EVENT
974     if (!entries.empty()) {
975         DmsKvSyncE2E::GetInstance()->PushAndPullData();
976     }
977 #endif
978 }
979 
AddBundleNameId(const uint16_t & bundleNameId,const std::string & bundleName)980 void DmsBmStorage::AddBundleNameId(const uint16_t &bundleNameId, const std::string &bundleName)
981 {
982     std::lock_guard<std::mutex> lock_l(mutex_);
983     bundleNameIdTables_.insert(std::make_pair(bundleNameId, bundleName));
984 }
985 
GetAllOldDistributionBundleInfo(const std::vector<std::string> & bundleNames)986 std::map<std::string, DmsBundleInfo> DmsBmStorage::GetAllOldDistributionBundleInfo(
987     const std::vector<std::string> &bundleNames)
988 {
989     HILOGD("called.");
990     std::map<std::string, DmsBundleInfo> oldDistributedBundleInfos;
991     if (kvStorePtr_ == nullptr) {
992         HILOGE("kvStorePtr_ is null");
993         return oldDistributedBundleInfos;
994     }
995     std::string localUdid;
996     std::string localUuid;
997     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
998     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUuid(localUuid);
999     if (localUdid == "" || localUuid == "") {
1000         HILOGE("can not get localUdid or localUuid");
1001         return oldDistributedBundleInfos;
1002     }
1003     HILOGI("localUuid: %{public}s", GetAnonymStr(localUuid).c_str());
1004     std::vector<Entry> localEntries;
1005     Status status = kvStorePtr_->GetDeviceEntries(localUuid, localEntries);
1006     if (localEntries.empty() || status != Status::SUCCESS) {
1007         HILOGE("GetEntries error: %{public}d or localEntries is empty", status);
1008         return oldDistributedBundleInfos;
1009     }
1010     std::string keyOfPublic = localUdid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
1011     for (const auto &entry : localEntries) {
1012         std::string key = entry.key.ToString();
1013         if (key.empty() || key.find(keyOfPublic) != std::string::npos) {
1014             continue;
1015         }
1016         std::string value = entry.value.ToString();
1017         DmsBundleInfo distributedBundleInfo;
1018         if (distributedBundleInfo.FromJsonString(value)) {
1019             AddBundleNameId(distributedBundleInfo.bundleNameId, distributedBundleInfo.bundleName);
1020             if (std::find(bundleNames.begin(), bundleNames.end(), distributedBundleInfo.bundleName) ==
1021                 bundleNames.end() || distributedBundleInfo.bundleName == "") {
1022                 HILOGE("Find %{public}s failed,need be delete", distributedBundleInfo.bundleName.c_str());
1023                 kvStorePtr_->Delete(entry.key);
1024                 continue;
1025             }
1026             distributedBundleInfo.keyOfKVStore = key;
1027             oldDistributedBundleInfos.emplace(distributedBundleInfo.bundleName, distributedBundleInfo);
1028         } else {
1029             HILOGE("DistributionInfo FromJsonString key:%{public}s failed", key.c_str());
1030         }
1031     }
1032     HILOGD("end.");
1033     return oldDistributedBundleInfos;
1034 }
1035 
FindContinueType(const DmsBundleInfo & distributedBundleInfo,uint8_t continueTypeId)1036 std::string FindContinueType(const DmsBundleInfo& distributedBundleInfo, uint8_t continueTypeId)
1037 {
1038     uint32_t pos = 0;
1039     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1040         for (auto continueType : dmsAbilityInfo.continueType) {
1041             if (pos == continueTypeId) {
1042                 HILOGD("end.");
1043                 return continueType;
1044             }
1045             ++pos;
1046         }
1047     }
1048     return "";
1049 }
1050 
GetContinueType(const std::string & networkId,std::string & bundleName,uint8_t continueTypeId)1051 std::string DmsBmStorage::GetContinueType(const std::string &networkId, std::string &bundleName,
1052     uint8_t continueTypeId)
1053 {
1054     HILOGD("called.");
1055     HILOGD("networkId: %{public}s,  bundleName: %{public}s,  continueTypeId: %{public}d",
1056         GetAnonymStr(networkId).c_str(), bundleName.c_str(), continueTypeId);
1057     if (!CheckKvStore()) {
1058         HILOGE("kvStore is nullptr");
1059         return "";
1060     }
1061     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
1062     if (udid == "") {
1063         HILOGE("can not get udid by networkId");
1064         return "";
1065     }
1066     Key allEntryKeyPrefix("");
1067     std::vector<Entry> allEntries;
1068     std::promise<OHOS::DistributedKv::Status> resultStatusSignal;
1069     int64_t begin = GetTickCount();
1070     GetEntries(networkId, allEntryKeyPrefix, resultStatusSignal, allEntries);
1071     Status status = GetResultSatus(resultStatusSignal);
1072     HILOGD("GetEntries spend %{public}" PRId64 " ms", GetTickCount() - begin);
1073     if (status != Status::SUCCESS) {
1074         HILOGE("GetEntries error: %{public}d", status);
1075         return "";
1076     }
1077     for (auto entry : allEntries) {
1078         std::string key = entry.key.ToString();
1079         std::string value =  entry.value.ToString();
1080         if (key.find(udid) == std::string::npos) {
1081             continue;
1082         }
1083         DmsBundleInfo distributedBundleInfo;
1084         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1085             std::string continueType = FindContinueType(distributedBundleInfo, continueTypeId);
1086             if (continueType != "") {
1087                 return continueType;
1088             }
1089         }
1090     }
1091     HILOGW("Can't find continueType");
1092     return "";
1093 }
1094 
FindAbilityName(const DmsBundleInfo & distributedBundleInfo,std::string continueType)1095 std::string FindAbilityName(const DmsBundleInfo& distributedBundleInfo, std::string continueType)
1096 {
1097     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1098         for (auto ele : dmsAbilityInfo.continueType) {
1099             if (ele == continueType) {
1100                 return dmsAbilityInfo.abilityName;
1101             }
1102         }
1103     }
1104     return "";
1105 }
1106 
FindModuleName(const DmsBundleInfo & distributedBundleInfo,std::string continueType)1107 std::string FindModuleName(const DmsBundleInfo& distributedBundleInfo, std::string continueType)
1108 {
1109     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1110         for (auto ele : dmsAbilityInfo.continueType) {
1111             if (ele == continueType) {
1112                 return dmsAbilityInfo.moduleName;
1113             }
1114         }
1115     }
1116     return "";
1117 }
1118 
GetAbilityName(const std::string & networkId,std::string & bundleName,std::string & continueType)1119 std::string DmsBmStorage::GetAbilityName(const std::string &networkId, std::string &bundleName,
1120     std::string &continueType)
1121 {
1122     HILOGD("called.");
1123     HILOGD("networkId: %{public}s,  bundleName: %{public}s,  continueTypeId: %{public}s",
1124         GetAnonymStr(networkId).c_str(), bundleName.c_str(), continueType.c_str());
1125     if (!CheckKvStore()) {
1126         HILOGE("kvStore is nullptr");
1127         return "";
1128     }
1129     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
1130     if (udid == "") {
1131         HILOGE("can not get udid by networkId");
1132         return "";
1133     }
1134     Key allEntryKeyPrefix("");
1135     std::vector<Entry> allEntries;
1136     std::promise<OHOS::DistributedKv::Status> resultStatusSignal;
1137     int64_t begin = GetTickCount();
1138     GetEntries(networkId, allEntryKeyPrefix, resultStatusSignal, allEntries);
1139     Status status = GetResultSatus(resultStatusSignal);
1140     HILOGD("GetEntries spend %{public}" PRId64 " ms", GetTickCount() - begin);
1141     if (status != Status::SUCCESS) {
1142         HILOGE("GetEntries error: %{public}d", status);
1143         return "";
1144     }
1145     for (auto entry : allEntries) {
1146         std::string key = entry.key.ToString();
1147         std::string value =  entry.value.ToString();
1148         if (key.find(udid) == std::string::npos) {
1149             continue;
1150         }
1151         DmsBundleInfo distributedBundleInfo;
1152         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1153             std::string abilityName = FindAbilityName(distributedBundleInfo, continueType);
1154             if (abilityName != "") {
1155                 return abilityName;
1156             }
1157         }
1158     }
1159     HILOGW("Can't find abilityName");
1160     return "";
1161 }
1162 
FindContinueTypeId(const DmsBundleInfo & distributedBundleInfo,const std::string & abilityName)1163 uint8_t FindContinueTypeId(const DmsBundleInfo& distributedBundleInfo, const std::string& abilityName)
1164 {
1165     HILOGD("called.");
1166     uint8_t pos = 0;
1167     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1168         if (dmsAbilityInfo.abilityName == abilityName) {
1169             return pos;
1170         }
1171         ++pos;
1172     }
1173     return MAX_CONTINUETYPEID;
1174 }
1175 
GetContinueTypeId(const std::string & bundleName,const std::string & abilityName,uint8_t & continueTypeId)1176 bool DmsBmStorage::GetContinueTypeId(const std::string &bundleName, const std::string &abilityName,
1177     uint8_t &continueTypeId)
1178 {
1179     HILOGD("called.");
1180     if (!CheckKvStore()) {
1181         HILOGE("kvStore is nullptr");
1182         return false;
1183     }
1184     std::string udid;
1185     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(udid);
1186     if (udid == "") {
1187         HILOGE("can not get udid by networkId");
1188         return false;
1189     }
1190     Key allEntryKeyPrefix("");
1191     std::vector<Entry> allEntries;
1192     Status status = kvStorePtr_->GetEntries(allEntryKeyPrefix, allEntries);
1193     if (status != Status::SUCCESS) {
1194         HILOGE("GetEntries error: %{public}d", status);
1195         return false;
1196     }
1197     for (auto entry : allEntries) {
1198         std::string key = entry.key.ToString();
1199         std::string value =  entry.value.ToString();
1200         if (key.find(udid) == std::string::npos) {
1201             continue;
1202         }
1203         DmsBundleInfo distributedBundleInfo;
1204         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1205             continueTypeId = FindContinueTypeId(distributedBundleInfo, abilityName);
1206             if (continueTypeId != MAX_CONTINUETYPEID) {
1207                 HILOGD("end.");
1208                 return true;
1209             }
1210         }
1211     }
1212     HILOGW("Can't find continueTypeId");
1213     return false;
1214 }
1215 
GetContinueEventInfo(const std::string & networkId,const std::string & bundleName,const std::string & continueType,ContinueEventInfo & continueEventInfo)1216 bool DmsBmStorage::GetContinueEventInfo(const std::string &networkId, const std::string &bundleName,
1217     const std::string& continueType, ContinueEventInfo &continueEventInfo)
1218 {
1219     HILOGD("networkId: %{public}s,  bundleName: %{public}s",
1220         GetAnonymStr(networkId).c_str(), bundleName.c_str());
1221     if (!CheckKvStore()) {
1222         HILOGE("kvStore is nullptr");
1223         return false;
1224     }
1225     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
1226     if (udid == "") {
1227         HILOGE("can not get udid by networkId");
1228         return false;
1229     }
1230     Key allEntryKeyPrefix("");
1231     std::vector<Entry> allEntries;
1232     std::promise<OHOS::DistributedKv::Status> resultStatusSignal;
1233     int64_t begin = GetTickCount();
1234     GetEntries(networkId, allEntryKeyPrefix, resultStatusSignal, allEntries);
1235     Status status = GetResultSatus(resultStatusSignal);
1236     HILOGD("GetEntries spend %{public}" PRId64 " ms", GetTickCount() - begin);
1237     if (status != Status::SUCCESS) {
1238         HILOGE("GetEntries error: %{public}d", status);
1239         return false;
1240     }
1241     for (auto entry : allEntries) {
1242         std::string key = entry.key.ToString();
1243         std::string value =  entry.value.ToString();
1244         if (key.find(udid) == std::string::npos) {
1245             continue;
1246         }
1247         DmsBundleInfo distributedBundleInfo;
1248         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1249             HILOGD("value: %{public}s", value.c_str());
1250             continueEventInfo.networkId = networkId;
1251             continueEventInfo.bundleName = bundleName;
1252             continueEventInfo.developerId = distributedBundleInfo.developerId;
1253             continueEventInfo.abilityName = FindAbilityName(distributedBundleInfo, continueType);
1254             continueEventInfo.moduleName = FindModuleName(distributedBundleInfo, continueType);
1255             return true;
1256         }
1257     }
1258     HILOGE("Can't find ContinueInfo!");
1259     return false;
1260 }
1261 }  // namespace DistributedSchedule
1262 }  // namespace OHOS
1263