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