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