• 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                 DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo, appProvisionInfo, true);
893                 dmsBundleInfos.push_back(dmsBundleInfo);
894             }
895             CleanRedundancyBundleInfo(localUdid, bundleInfo.name, keyOfKVStore, oldUdid);
896             continue;
897         }
898         DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo, appProvisionInfo);
899         if (dmsBundleInfo.bundleName == "") {
900             HILOGE("The package information is empty and does not need to be stored!");
901             continue;
902         }
903         dmsBundleInfos.push_back(dmsBundleInfo);
904     }
905     DmsPutBatch(dmsBundleInfos);
906     HILOGI("end.");
907 }
908 
CleanRedundancyBundleInfo(const std::string & localUdid,const std::string bundleName,const std::string & keyOfKVStore,const std::string & oldUdid) const909 void DmsBmStorage::CleanRedundancyBundleInfo(const std::string &localUdid, const std::string bundleName,
910     const std::string &keyOfKVStore, const std::string &oldUdid) const
911 {
912     if (!localUdid.empty() && oldUdid != localUdid) {
913         HILOGW("Delete DistributedBundleInfo for old udid: %{public}s, bundleName: %{public}s, new udid: %{public}s",
914             GetAnonymStr(oldUdid).c_str(), bundleName.c_str(), GetAnonymStr(localUdid).c_str());
915         Key key(keyOfKVStore);
916         kvStorePtr_->Delete(key);
917     }
918 }
919 
DmsPutBatch(const std::vector<DmsBundleInfo> & dmsBundleInfos)920 void DmsBmStorage::DmsPutBatch(const std::vector<DmsBundleInfo> &dmsBundleInfos)
921 {
922     HILOGI("called.");
923     if (dmsBundleInfos.empty()) {
924         HILOGI("Data not updated, no need to write");
925         return;
926     }
927     if (!CheckKvStore()) {
928         HILOGE("kvStore is nullptr");
929         return;
930     }
931     std::string localUdid;
932     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
933     if (localUdid == "") {
934         HILOGE("GetLocalUdid failed");
935         return;
936     }
937     std::vector<Entry> entries;
938     for (const auto &dmsBundleInfo : dmsBundleInfos) {
939         Entry entrie;
940         std::string keyOfData = DeviceAndNameToKey(localUdid, dmsBundleInfo.bundleName);
941         Key key(keyOfData);
942         entrie.key = key;
943         Value value(dmsBundleInfo.ToString());
944         entrie.value = value;
945         HILOGI("need be put: %{public}s", dmsBundleInfo.bundleName.c_str());
946         entries.push_back(entrie);
947     }
948     Entry entrie;
949     std::string keyOfData = localUdid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
950     Key key(keyOfData);
951     entrie.key = key;
952     PublicRecordsInfo publicRecordsInfo;
953     GetLastBundleNameId(publicRecordsInfo.maxBundleNameId);
954     publicRecordsInfo.maxBundleNameId = bundleNameIdTables_.empty() ? publicRecordsInfo.maxBundleNameId : std::max(
955         (bundleNameIdTables_.rbegin())->first, publicRecordsInfo.maxBundleNameId);
956     Value value(publicRecordsInfo.ToString());
957     entrie.value = value;
958     HILOGI("need be put: %{public}d", publicRecordsInfo.maxBundleNameId);
959     entries.push_back(entrie);
960     Status status = kvStorePtr_->PutBatch(entries);
961     if (status == Status::IPC_ERROR) {
962         status = kvStorePtr_->PutBatch(entries);
963         HILOGW("distribute database ipc error and try to call again, result = %{public}d", status);
964     }
965     SyncBundleInfoData(entries);
966     HILOGI("end.");
967 }
968 
SyncBundleInfoData(std::vector<DistributedKv::Entry> & entries)969 void DmsBmStorage::SyncBundleInfoData(std::vector<DistributedKv::Entry> &entries)
970 {
971 #ifdef DMS_SYNC_DATA_ON_PACKAGE_EVENT
972     if (!entries.empty()) {
973         DmsKvSyncE2E::GetInstance()->PushAndPullData();
974     }
975 #endif
976 }
977 
AddBundleNameId(const uint16_t & bundleNameId,const std::string & bundleName)978 void DmsBmStorage::AddBundleNameId(const uint16_t &bundleNameId, const std::string &bundleName)
979 {
980     std::lock_guard<std::mutex> lock_l(mutex_);
981     bundleNameIdTables_.insert(std::make_pair(bundleNameId, bundleName));
982 }
983 
GetAllOldDistributionBundleInfo(const std::vector<std::string> & bundleNames)984 std::map<std::string, DmsBundleInfo> DmsBmStorage::GetAllOldDistributionBundleInfo(
985     const std::vector<std::string> &bundleNames)
986 {
987     HILOGD("called.");
988     std::map<std::string, DmsBundleInfo> oldDistributedBundleInfos;
989     if (kvStorePtr_ == nullptr) {
990         HILOGE("kvStorePtr_ is null");
991         return oldDistributedBundleInfos;
992     }
993     std::string localUdid;
994     std::string localUuid;
995     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(localUdid);
996     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUuid(localUuid);
997     if (localUdid == "" || localUuid == "") {
998         HILOGE("can not get localUdid or localUuid");
999         return oldDistributedBundleInfos;
1000     }
1001     HILOGI("localUuid: %{public}s", GetAnonymStr(localUuid).c_str());
1002     std::vector<Entry> localEntries;
1003     Status status = kvStorePtr_->GetDeviceEntries(localUuid, localEntries);
1004     if (localEntries.empty() || status != Status::SUCCESS) {
1005         HILOGE("GetEntries error: %{public}d or localEntries is empty", status);
1006         return oldDistributedBundleInfos;
1007     }
1008     std::string keyOfPublic = localUdid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
1009     for (const auto &entry : localEntries) {
1010         std::string key = entry.key.ToString();
1011         if (key.empty() || key.find(keyOfPublic) != std::string::npos) {
1012             continue;
1013         }
1014         std::string value = entry.value.ToString();
1015         DmsBundleInfo distributedBundleInfo;
1016         if (distributedBundleInfo.FromJsonString(value)) {
1017             AddBundleNameId(distributedBundleInfo.bundleNameId, distributedBundleInfo.bundleName);
1018             if (std::find(bundleNames.begin(), bundleNames.end(), distributedBundleInfo.bundleName) ==
1019                 bundleNames.end() || distributedBundleInfo.bundleName == "") {
1020                 HILOGE("Find %{public}s failed,need be delete", distributedBundleInfo.bundleName.c_str());
1021                 kvStorePtr_->Delete(entry.key);
1022                 continue;
1023             }
1024             distributedBundleInfo.keyOfKVStore = key;
1025             oldDistributedBundleInfos.emplace(distributedBundleInfo.bundleName, distributedBundleInfo);
1026         } else {
1027             HILOGE("DistributionInfo FromJsonString key:%{public}s failed", key.c_str());
1028         }
1029     }
1030     HILOGD("end.");
1031     return oldDistributedBundleInfos;
1032 }
1033 
FindContinueType(const DmsBundleInfo & distributedBundleInfo,uint8_t continueTypeId)1034 std::string FindContinueType(const DmsBundleInfo& distributedBundleInfo, uint8_t continueTypeId)
1035 {
1036     uint32_t pos = 0;
1037     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1038         for (auto continueType : dmsAbilityInfo.continueType) {
1039             if (pos == continueTypeId) {
1040                 HILOGD("end.");
1041                 return continueType;
1042             }
1043             ++pos;
1044         }
1045     }
1046     return "";
1047 }
1048 
GetContinueType(const std::string & networkId,std::string & bundleName,uint8_t continueTypeId)1049 std::string DmsBmStorage::GetContinueType(const std::string &networkId, std::string &bundleName,
1050     uint8_t continueTypeId)
1051 {
1052     HILOGD("called.");
1053     HILOGD("networkId: %{public}s,  bundleName: %{public}s,  continueTypeId: %{public}d",
1054         GetAnonymStr(networkId).c_str(), bundleName.c_str(), continueTypeId);
1055     if (!CheckKvStore()) {
1056         HILOGE("kvStore is nullptr");
1057         return "";
1058     }
1059     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
1060     if (udid == "") {
1061         HILOGE("can not get udid by networkId");
1062         return "";
1063     }
1064     Key allEntryKeyPrefix("");
1065     std::vector<Entry> allEntries;
1066     std::promise<OHOS::DistributedKv::Status> resultStatusSignal;
1067     int64_t begin = GetTickCount();
1068     GetEntries(networkId, allEntryKeyPrefix, resultStatusSignal, allEntries);
1069     Status status = GetResultSatus(resultStatusSignal);
1070     HILOGD("GetEntries spend %{public}" PRId64 " ms", GetTickCount() - begin);
1071     if (status != Status::SUCCESS) {
1072         HILOGE("GetEntries error: %{public}d", status);
1073         return "";
1074     }
1075     for (auto entry : allEntries) {
1076         std::string key = entry.key.ToString();
1077         std::string value =  entry.value.ToString();
1078         if (key.find(udid) == std::string::npos) {
1079             continue;
1080         }
1081         DmsBundleInfo distributedBundleInfo;
1082         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1083             std::string continueType = FindContinueType(distributedBundleInfo, continueTypeId);
1084             if (continueType != "") {
1085                 return continueType;
1086             }
1087         }
1088     }
1089     HILOGW("Can't find continueType");
1090     return "";
1091 }
1092 
FindAbilityName(const DmsBundleInfo & distributedBundleInfo,std::string continueType)1093 std::string FindAbilityName(const DmsBundleInfo& distributedBundleInfo, std::string continueType)
1094 {
1095     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1096         for (auto ele : dmsAbilityInfo.continueType) {
1097             if (ele == continueType) {
1098                 return dmsAbilityInfo.abilityName;
1099             }
1100         }
1101     }
1102     return "";
1103 }
1104 
FindModuleName(const DmsBundleInfo & distributedBundleInfo,std::string continueType)1105 std::string FindModuleName(const DmsBundleInfo& distributedBundleInfo, std::string continueType)
1106 {
1107     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1108         for (auto ele : dmsAbilityInfo.continueType) {
1109             if (ele == continueType) {
1110                 return dmsAbilityInfo.moduleName;
1111             }
1112         }
1113     }
1114     return "";
1115 }
1116 
GetAbilityName(const std::string & networkId,std::string & bundleName,std::string & continueType)1117 std::string DmsBmStorage::GetAbilityName(const std::string &networkId, std::string &bundleName,
1118     std::string &continueType)
1119 {
1120     HILOGD("called.");
1121     HILOGD("networkId: %{public}s,  bundleName: %{public}s,  continueTypeId: %{public}s",
1122         GetAnonymStr(networkId).c_str(), bundleName.c_str(), continueType.c_str());
1123     if (!CheckKvStore()) {
1124         HILOGE("kvStore is nullptr");
1125         return "";
1126     }
1127     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
1128     if (udid == "") {
1129         HILOGE("can not get udid by networkId");
1130         return "";
1131     }
1132     Key allEntryKeyPrefix("");
1133     std::vector<Entry> allEntries;
1134     std::promise<OHOS::DistributedKv::Status> resultStatusSignal;
1135     int64_t begin = GetTickCount();
1136     GetEntries(networkId, allEntryKeyPrefix, resultStatusSignal, allEntries);
1137     Status status = GetResultSatus(resultStatusSignal);
1138     HILOGD("GetEntries spend %{public}" PRId64 " ms", GetTickCount() - begin);
1139     if (status != Status::SUCCESS) {
1140         HILOGE("GetEntries error: %{public}d", status);
1141         return "";
1142     }
1143     for (auto entry : allEntries) {
1144         std::string key = entry.key.ToString();
1145         std::string value =  entry.value.ToString();
1146         if (key.find(udid) == std::string::npos) {
1147             continue;
1148         }
1149         DmsBundleInfo distributedBundleInfo;
1150         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1151             std::string abilityName = FindAbilityName(distributedBundleInfo, continueType);
1152             if (abilityName != "") {
1153                 return abilityName;
1154             }
1155         }
1156     }
1157     HILOGW("Can't find abilityName");
1158     return "";
1159 }
1160 
FindContinueTypeId(const DmsBundleInfo & distributedBundleInfo,const std::string & abilityName)1161 uint8_t FindContinueTypeId(const DmsBundleInfo& distributedBundleInfo, const std::string& abilityName)
1162 {
1163     HILOGD("called.");
1164     uint8_t pos = 0;
1165     for (auto dmsAbilityInfo : distributedBundleInfo.dmsAbilityInfos) {
1166         if (dmsAbilityInfo.abilityName == abilityName) {
1167             return pos;
1168         }
1169         ++pos;
1170     }
1171     return MAX_CONTINUETYPEID;
1172 }
1173 
GetContinueTypeId(const std::string & bundleName,const std::string & abilityName,uint8_t & continueTypeId)1174 bool DmsBmStorage::GetContinueTypeId(const std::string &bundleName, const std::string &abilityName,
1175     uint8_t &continueTypeId)
1176 {
1177     HILOGD("called.");
1178     if (!CheckKvStore()) {
1179         HILOGE("kvStore is nullptr");
1180         return false;
1181     }
1182     std::string udid;
1183     DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalUdid(udid);
1184     if (udid == "") {
1185         HILOGE("can not get udid by networkId");
1186         return false;
1187     }
1188     Key allEntryKeyPrefix("");
1189     std::vector<Entry> allEntries;
1190     Status status = kvStorePtr_->GetEntries(allEntryKeyPrefix, allEntries);
1191     if (status != Status::SUCCESS) {
1192         HILOGE("GetEntries error: %{public}d", status);
1193         return false;
1194     }
1195     for (auto entry : allEntries) {
1196         std::string key = entry.key.ToString();
1197         std::string value =  entry.value.ToString();
1198         if (key.find(udid) == std::string::npos) {
1199             continue;
1200         }
1201         DmsBundleInfo distributedBundleInfo;
1202         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1203             continueTypeId = FindContinueTypeId(distributedBundleInfo, abilityName);
1204             if (continueTypeId != MAX_CONTINUETYPEID) {
1205                 HILOGD("end.");
1206                 return true;
1207             }
1208         }
1209     }
1210     HILOGW("Can't find continueTypeId");
1211     return false;
1212 }
1213 
GetContinueEventInfo(const std::string & networkId,const std::string & bundleName,const std::string & continueType,ContinueEventInfo & continueEventInfo)1214 bool DmsBmStorage::GetContinueEventInfo(const std::string &networkId, const std::string &bundleName,
1215     const std::string& continueType, ContinueEventInfo &continueEventInfo)
1216 {
1217     HILOGD("networkId: %{public}s,  bundleName: %{public}s",
1218         GetAnonymStr(networkId).c_str(), bundleName.c_str());
1219     if (!CheckKvStore()) {
1220         HILOGE("kvStore is nullptr");
1221         return false;
1222     }
1223     std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
1224     if (udid == "") {
1225         HILOGE("can not get udid by networkId");
1226         return false;
1227     }
1228     Key allEntryKeyPrefix("");
1229     std::vector<Entry> allEntries;
1230     std::promise<OHOS::DistributedKv::Status> resultStatusSignal;
1231     int64_t begin = GetTickCount();
1232     GetEntries(networkId, allEntryKeyPrefix, resultStatusSignal, allEntries);
1233     Status status = GetResultSatus(resultStatusSignal);
1234     HILOGD("GetEntries spend %{public}" PRId64 " ms", GetTickCount() - begin);
1235     if (status != Status::SUCCESS) {
1236         HILOGE("GetEntries error: %{public}d", status);
1237         return false;
1238     }
1239     for (auto entry : allEntries) {
1240         std::string key = entry.key.ToString();
1241         std::string value =  entry.value.ToString();
1242         if (key.find(udid) == std::string::npos) {
1243             continue;
1244         }
1245         DmsBundleInfo distributedBundleInfo;
1246         if (distributedBundleInfo.FromJsonString(value) && distributedBundleInfo.bundleName == bundleName) {
1247             HILOGD("value: %{public}s", value.c_str());
1248             continueEventInfo.networkId = networkId;
1249             continueEventInfo.bundleName = bundleName;
1250             continueEventInfo.developerId = distributedBundleInfo.developerId;
1251             continueEventInfo.abilityName = FindAbilityName(distributedBundleInfo, continueType);
1252             continueEventInfo.moduleName = FindModuleName(distributedBundleInfo, continueType);
1253             return true;
1254         }
1255     }
1256     HILOGE("Can't find ContinueInfo!");
1257     return false;
1258 }
1259 }  // namespace DistributedSchedule
1260 }  // namespace OHOS
1261