1  /*
2   * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3   * Licensed under the Apache License, Version 2.0 (the "License");
4   * you may not use this file except in compliance with the License.
5   * You may obtain a copy of the License at
6   *
7   *     http://www.apache.org/licenses/LICENSE-2.0
8   *
9   * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  #include "ability_auto_startup_data_manager.h"
17  
18  #include <unistd.h>
19  
20  #include "accesstoken_kit.h"
21  #include "hilog_tag_wrapper.h"
22  #include "os_account_manager_wrapper.h"
23  
24  namespace OHOS {
25  namespace AbilityRuntime {
26  namespace {
27  constexpr int32_t CHECK_INTERVAL = 100000; // 100ms
28  constexpr int32_t MAX_TIMES = 5;           // 5 * 100ms = 500ms
29  constexpr const char *AUTO_STARTUP_STORAGE_DIR = "/data/service/el1/public/database/auto_startup_service";
30  const std::string JSON_KEY_BUNDLE_NAME = "bundleName";
31  const std::string JSON_KEY_ABILITY_NAME = "abilityName";
32  const std::string JSON_KEY_MODULE_NAME = "moduleName";
33  const std::string JSON_KEY_IS_AUTO_STARTUP = "isAutoStartup";
34  const std::string JSON_KEY_IS_EDM_FORCE = "isEdmForce";
35  const std::string JSON_KEY_TYPE_NAME = "abilityTypeName";
36  const std::string JSON_KEY_APP_CLONE_INDEX = "appCloneIndex";
37  const std::string JSON_KEY_ACCESS_TOKENID = "accessTokenId";
38  const std::string JSON_KEY_USERID = "userId";
39  } // namespace
40  const DistributedKv::AppId AbilityAutoStartupDataManager::APP_ID = { "auto_startup_storage" };
41  const DistributedKv::StoreId AbilityAutoStartupDataManager::STORE_ID = { "auto_startup_infos" };
AbilityAutoStartupDataManager()42  AbilityAutoStartupDataManager::AbilityAutoStartupDataManager() {}
43  
~AbilityAutoStartupDataManager()44  AbilityAutoStartupDataManager::~AbilityAutoStartupDataManager()
45  {
46      if (kvStorePtr_ != nullptr) {
47          dataManager_.CloseKvStore(APP_ID, kvStorePtr_);
48      }
49  }
50  
RestoreKvStore(DistributedKv::Status status)51  DistributedKv::Status AbilityAutoStartupDataManager::RestoreKvStore(DistributedKv::Status status)
52  {
53      if (status == DistributedKv::Status::DATA_CORRUPTED) {
54          DistributedKv::Options options = { .createIfMissing = true,
55              .encrypt = false,
56              .autoSync = false,
57              .syncable = false,
58              .securityLevel = DistributedKv::SecurityLevel::S2,
59              .area = DistributedKv::EL1,
60              .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
61              .baseDir = AUTO_STARTUP_STORAGE_DIR };
62          TAG_LOGI(AAFwkTag::AUTO_STARTUP, "corrupted, deleting db");
63          dataManager_.DeleteKvStore(APP_ID, STORE_ID, options.baseDir);
64          TAG_LOGI(AAFwkTag::AUTO_STARTUP, "deleted corrupted db, recreating db");
65          status = dataManager_.GetSingleKvStore(options, APP_ID, STORE_ID, kvStorePtr_);
66          TAG_LOGI(AAFwkTag::AUTO_STARTUP, "recreate db result:%{public}d", status);
67      }
68      return status;
69  }
70  
GetKvStore()71  DistributedKv::Status AbilityAutoStartupDataManager::GetKvStore()
72  {
73      DistributedKv::Options options = { .createIfMissing = true,
74          .encrypt = false,
75          .autoSync = false,
76          .syncable = false,
77          .securityLevel = DistributedKv::SecurityLevel::S2,
78          .area = DistributedKv::EL1,
79          .kvStoreType = DistributedKv::KvStoreType::SINGLE_VERSION,
80          .baseDir = AUTO_STARTUP_STORAGE_DIR };
81  
82      DistributedKv::Status status = dataManager_.GetSingleKvStore(options, APP_ID, STORE_ID, kvStorePtr_);
83      if (status != DistributedKv::Status::SUCCESS) {
84          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Error: %{public}d", status);
85          status = RestoreKvStore(status);
86          return status;
87      }
88  
89      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "Get kvStore success");
90      return status;
91  }
92  
CheckKvStore()93  bool AbilityAutoStartupDataManager::CheckKvStore()
94  {
95      if (kvStorePtr_ != nullptr) {
96          return true;
97      }
98      int32_t tryTimes = MAX_TIMES;
99      while (tryTimes > 0) {
100          DistributedKv::Status status = GetKvStore();
101          if (status == DistributedKv::Status::SUCCESS && kvStorePtr_ != nullptr) {
102              return true;
103          }
104          TAG_LOGD(AAFwkTag::AUTO_STARTUP, "Try times: %{public}d", tryTimes);
105          usleep(CHECK_INTERVAL);
106          tryTimes--;
107      }
108      return kvStorePtr_ != nullptr;
109  }
110  
InsertAutoStartupData(const AutoStartupInfo & info,bool isAutoStartup,bool isEdmForce)111  int32_t AbilityAutoStartupDataManager::InsertAutoStartupData(
112      const AutoStartupInfo &info, bool isAutoStartup, bool isEdmForce)
113  {
114      if (info.bundleName.empty() || info.abilityName.empty() || info.accessTokenId.empty() || info.userId == -1) {
115          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Invalid value");
116          return ERR_INVALID_VALUE;
117      }
118  
119      TAG_LOGD(AAFwkTag::AUTO_STARTUP,
120          "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s,"
121          " accessTokenId: %{public}s, userId: %{public}d",
122          info.bundleName.c_str(), info.moduleName.c_str(),
123          info.abilityName.c_str(), info.accessTokenId.c_str(), info.userId);
124      {
125          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
126          if (!CheckKvStore()) {
127              TAG_LOGE(AAFwkTag::AUTO_STARTUP, "null kvStore");
128              return ERR_NO_INIT;
129          }
130      }
131  
132      DistributedKv::Key key = ConvertAutoStartupDataToKey(info);
133      DistributedKv::Value value = ConvertAutoStartupStatusToValue(isAutoStartup, isEdmForce, info.abilityTypeName);
134      DistributedKv::Status status;
135      {
136          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
137          status = kvStorePtr_->Put(key, value);
138      }
139  
140      if (status != DistributedKv::Status::SUCCESS) {
141          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Insert data to kvStore error: %{public}d", status);
142          {
143              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
144              status = RestoreKvStore(status);
145          }
146          return ERR_INVALID_OPERATION;
147      }
148      return ERR_OK;
149  }
150  
UpdateAutoStartupData(const AutoStartupInfo & info,bool isAutoStartup,bool isEdmForce)151  int32_t AbilityAutoStartupDataManager::UpdateAutoStartupData(
152      const AutoStartupInfo &info, bool isAutoStartup, bool isEdmForce)
153  {
154      if (info.bundleName.empty() || info.abilityName.empty() || info.accessTokenId.empty() || info.userId == -1) {
155          TAG_LOGW(AAFwkTag::AUTO_STARTUP, "Invalid value");
156          return ERR_INVALID_VALUE;
157      }
158  
159      TAG_LOGD(AAFwkTag::AUTO_STARTUP,
160          "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s,"
161          " accessTokenId: %{public}s, userId: %{public}d",
162          info.bundleName.c_str(), info.moduleName.c_str(),
163          info.abilityName.c_str(), info.accessTokenId.c_str(), info.userId);
164      {
165          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
166          if (!CheckKvStore()) {
167              TAG_LOGE(AAFwkTag::AUTO_STARTUP, "null kvStore");
168              return ERR_NO_INIT;
169          }
170      }
171  
172      DistributedKv::Key key = ConvertAutoStartupDataToKey(info);
173      DistributedKv::Status status;
174      {
175          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
176          status = kvStorePtr_->Delete(key);
177      }
178      if (status != DistributedKv::Status::SUCCESS) {
179          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Delete data from kvStore error: %{public}d", status);
180          {
181              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
182              status = RestoreKvStore(status);
183          }
184          return ERR_INVALID_OPERATION;
185      }
186      DistributedKv::Value value = ConvertAutoStartupStatusToValue(isAutoStartup, isEdmForce, info.abilityTypeName);
187      {
188          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
189          status = kvStorePtr_->Put(key, value);
190      }
191      if (status != DistributedKv::Status::SUCCESS) {
192          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Insert data to kvStore error: %{public}d", status);
193          {
194              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
195              status = RestoreKvStore(status);
196          }
197          return ERR_INVALID_OPERATION;
198      }
199  
200      return ERR_OK;
201  }
202  
DeleteAutoStartupData(const AutoStartupInfo & info)203  int32_t AbilityAutoStartupDataManager::DeleteAutoStartupData(const AutoStartupInfo &info)
204  {
205      if (info.bundleName.empty() || info.abilityName.empty() || info.accessTokenId.empty() || info.userId == -1) {
206          TAG_LOGW(AAFwkTag::AUTO_STARTUP, "Invalid value");
207          return ERR_INVALID_VALUE;
208      }
209  
210      TAG_LOGD(AAFwkTag::AUTO_STARTUP,
211          "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s,"
212          " accessTokenId: %{public}s, userId: %{public}d",
213          info.bundleName.c_str(), info.moduleName.c_str(),
214          info.abilityName.c_str(), info.accessTokenId.c_str(), info.userId);
215      {
216          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
217          if (!CheckKvStore()) {
218              TAG_LOGE(AAFwkTag::AUTO_STARTUP, "null kvStore");
219              return ERR_NO_INIT;
220          }
221      }
222  
223      DistributedKv::Key key = ConvertAutoStartupDataToKey(info);
224      DistributedKv::Status status;
225      {
226          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
227          status = kvStorePtr_->Delete(key);
228      }
229  
230      if (status != DistributedKv::Status::SUCCESS) {
231          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Delete data from kvStore error: %{public}d", status);
232          {
233              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
234              status = RestoreKvStore(status);
235          }
236          return ERR_INVALID_OPERATION;
237      }
238      return ERR_OK;
239  }
240  
DeleteAutoStartupData(const std::string & bundleName,int32_t accessTokenId)241  int32_t AbilityAutoStartupDataManager::DeleteAutoStartupData(const std::string &bundleName, int32_t accessTokenId)
242  {
243      auto accessTokenIdStr = std::to_string(accessTokenId);
244      if (bundleName.empty() || accessTokenIdStr.empty()) {
245          TAG_LOGW(AAFwkTag::AUTO_STARTUP, "Invalid value");
246          return ERR_INVALID_VALUE;
247      }
248  
249      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "bundleName: %{public}s, accessTokenId: %{public}s",
250          bundleName.c_str(), accessTokenIdStr.c_str());
251      {
252          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
253          if (!CheckKvStore()) {
254              TAG_LOGE(AAFwkTag::AUTO_STARTUP, "null kvStore");
255              return ERR_NO_INIT;
256          }
257      }
258  
259      std::vector<DistributedKv::Entry> allEntries;
260      DistributedKv::Status status = DistributedKv::Status::SUCCESS;
261      {
262          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
263          status = kvStorePtr_->GetEntries(nullptr, allEntries);
264      }
265      if (status != DistributedKv::Status::SUCCESS) {
266          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Get entries error: %{public}d", status);
267          {
268              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
269              status = RestoreKvStore(status);
270          }
271          return ERR_INVALID_OPERATION;
272      }
273  
274      for (const auto &item : allEntries) {
275          if (IsEqual(item.key, accessTokenIdStr)) {
276              {
277                  std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
278                  status = kvStorePtr_->Delete(item.key);
279              }
280              if (status != DistributedKv::Status::SUCCESS) {
281                  TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Delete data from kvStore error: %{public}d", status);
282                  {
283                      std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
284                      status = RestoreKvStore(status);
285                  }
286                  return ERR_INVALID_OPERATION;
287              }
288          }
289      }
290  
291      return ERR_OK;
292  }
293  
QueryAutoStartupData(const AutoStartupInfo & info)294  AutoStartupStatus AbilityAutoStartupDataManager::QueryAutoStartupData(const AutoStartupInfo &info)
295  {
296      AutoStartupStatus asustatus;
297      if (info.bundleName.empty() || info.abilityName.empty() || info.accessTokenId.empty() || info.userId == -1) {
298          TAG_LOGW(AAFwkTag::AUTO_STARTUP, "Invalid value");
299          asustatus.code = ERR_INVALID_VALUE;
300          return asustatus;
301      }
302  
303      TAG_LOGD(AAFwkTag::AUTO_STARTUP,
304          "bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s,"
305          " accessTokenId: %{public}s, userId: %{public}d",
306          info.bundleName.c_str(), info.moduleName.c_str(),
307          info.abilityName.c_str(), info.accessTokenId.c_str(), info.userId);
308      {
309          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
310          if (!CheckKvStore()) {
311              TAG_LOGE(AAFwkTag::AUTO_STARTUP, "null kvStore");
312              asustatus.code = ERR_NO_INIT;
313              return asustatus;
314          }
315      }
316  
317      std::vector<DistributedKv::Entry> allEntries;
318      DistributedKv::Status status = DistributedKv::Status::SUCCESS;
319      {
320          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
321          status = kvStorePtr_->GetEntries(nullptr, allEntries);
322      }
323      if (status != DistributedKv::Status::SUCCESS) {
324          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Get entries error: %{public}d", status);
325          {
326              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
327              status = RestoreKvStore(status);
328          }
329          asustatus.code = ERR_INVALID_OPERATION;
330          return asustatus;
331      }
332  
333      asustatus.code = ERR_NAME_NOT_FOUND;
334      for (const auto &item : allEntries) {
335          if (IsEqual(item.key, info)) {
336              ConvertAutoStartupStatusFromValue(item.value, asustatus.isAutoStartup, asustatus.isEdmForce);
337              asustatus.code = ERR_OK;
338          }
339      }
340  
341      return asustatus;
342  }
343  
QueryAllAutoStartupApplications(std::vector<AutoStartupInfo> & infoList,int32_t userId)344  int32_t AbilityAutoStartupDataManager::QueryAllAutoStartupApplications(std::vector<AutoStartupInfo> &infoList,
345      int32_t userId)
346  {
347      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "called");
348      {
349          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
350          if (!CheckKvStore()) {
351              TAG_LOGE(AAFwkTag::AUTO_STARTUP, "null kvStore");
352              return ERR_NO_INIT;
353          }
354      }
355  
356      std::vector<DistributedKv::Entry> allEntries;
357      DistributedKv::Status status = DistributedKv::Status::SUCCESS;
358      {
359          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
360          status = kvStorePtr_->GetEntries(nullptr, allEntries);
361      }
362      if (status != DistributedKv::Status::SUCCESS) {
363          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Get entries error: %{public}d", status);
364          {
365              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
366              status = RestoreKvStore(status);
367          }
368          return ERR_INVALID_OPERATION;
369      }
370  
371      for (const auto &item : allEntries) {
372          if (!IsEqual(item.key, userId)) {
373              continue;
374          }
375          bool isAutoStartup, isEdmForce;
376          ConvertAutoStartupStatusFromValue(item.value, isAutoStartup, isEdmForce);
377          if (isAutoStartup) {
378              infoList.emplace_back(ConvertAutoStartupInfoFromKeyAndValue(item.key, item.value));
379          }
380      }
381      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "InfoList.size: %{public}zu", infoList.size());
382      return ERR_OK;
383  }
384  
GetCurrentAppAutoStartupData(const std::string & bundleName,std::vector<AutoStartupInfo> & infoList,const std::string & accessTokenId)385  int32_t AbilityAutoStartupDataManager::GetCurrentAppAutoStartupData(
386      const std::string &bundleName, std::vector<AutoStartupInfo> &infoList, const std::string &accessTokenId)
387  {
388      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "called");
389      {
390          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
391          if (!CheckKvStore()) {
392              TAG_LOGE(AAFwkTag::AUTO_STARTUP, "null kvStore");
393              return ERR_NO_INIT;
394          }
395      }
396  
397      std::vector<DistributedKv::Entry> allEntries;
398      DistributedKv::Status status = DistributedKv::Status::SUCCESS;
399      {
400          std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
401          status = kvStorePtr_->GetEntries(nullptr, allEntries);
402      }
403      if (status != DistributedKv::Status::SUCCESS) {
404          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Get entries error: %{public}d", status);
405          {
406              std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
407              status = RestoreKvStore(status);
408          }
409          return ERR_INVALID_OPERATION;
410      }
411  
412      for (const auto &item : allEntries) {
413          if (IsEqual(item.key, accessTokenId)) {
414              infoList.emplace_back(ConvertAutoStartupInfoFromKeyAndValue(item.key, item.value));
415          }
416      }
417      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "InfoList.size: %{public}zu", infoList.size());
418      return ERR_OK;
419  }
420  
ConvertAutoStartupStatusToValue(bool isAutoStartup,bool isEdmForce,const std::string & abilityTypeName)421  DistributedKv::Value AbilityAutoStartupDataManager::ConvertAutoStartupStatusToValue(
422      bool isAutoStartup, bool isEdmForce, const std::string &abilityTypeName)
423  {
424      nlohmann::json jsonObject = nlohmann::json {
425          { JSON_KEY_IS_AUTO_STARTUP, isAutoStartup },
426          { JSON_KEY_IS_EDM_FORCE, isEdmForce },
427          { JSON_KEY_TYPE_NAME, abilityTypeName },
428      };
429      DistributedKv::Value value(jsonObject.dump());
430      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "value: %{public}s", value.ToString().c_str());
431      return value;
432  }
433  
ConvertAutoStartupStatusFromValue(const DistributedKv::Value & value,bool & isAutoStartup,bool & isEdmForce)434  void AbilityAutoStartupDataManager::ConvertAutoStartupStatusFromValue(
435      const DistributedKv::Value &value, bool &isAutoStartup, bool &isEdmForce)
436  {
437      nlohmann::json jsonObject = nlohmann::json::parse(value.ToString(), nullptr, false);
438      if (jsonObject.is_discarded()) {
439          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Parse json string failed");
440          return;
441      }
442      if (jsonObject.contains(JSON_KEY_IS_AUTO_STARTUP) && jsonObject[JSON_KEY_IS_AUTO_STARTUP].is_boolean()) {
443          isAutoStartup = jsonObject.at(JSON_KEY_IS_AUTO_STARTUP).get<bool>();
444      }
445      if (jsonObject.contains(JSON_KEY_IS_EDM_FORCE) && jsonObject[JSON_KEY_IS_EDM_FORCE].is_boolean()) {
446          isEdmForce = jsonObject.at(JSON_KEY_IS_EDM_FORCE).get<bool>();
447      }
448  }
449  
ConvertAutoStartupDataToKey(const AutoStartupInfo & info)450  DistributedKv::Key AbilityAutoStartupDataManager::ConvertAutoStartupDataToKey(const AutoStartupInfo &info)
451  {
452      nlohmann::json jsonObject = nlohmann::json {
453          { JSON_KEY_BUNDLE_NAME, info.bundleName },
454          { JSON_KEY_MODULE_NAME, info.moduleName },
455          { JSON_KEY_ABILITY_NAME, info.abilityName },
456          { JSON_KEY_APP_CLONE_INDEX, info.appCloneIndex },
457  		{ JSON_KEY_ACCESS_TOKENID, info.accessTokenId },
458          { JSON_KEY_USERID, info.userId },
459      };
460      DistributedKv::Key key(jsonObject.dump());
461      TAG_LOGD(AAFwkTag::AUTO_STARTUP, "key: %{public}s", key.ToString().c_str());
462      return key;
463  }
464  
ConvertAutoStartupInfoFromKeyAndValue(const DistributedKv::Key & key,const DistributedKv::Value & value)465  AutoStartupInfo AbilityAutoStartupDataManager::ConvertAutoStartupInfoFromKeyAndValue(
466      const DistributedKv::Key &key, const DistributedKv::Value &value)
467  {
468      AutoStartupInfo info;
469      nlohmann::json jsonObject = nlohmann::json::parse(key.ToString(), nullptr, false);
470      if (jsonObject.is_discarded()) {
471          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Parse jsonObject failed");
472          return info;
473      }
474  
475      if (jsonObject.contains(JSON_KEY_BUNDLE_NAME) && jsonObject[JSON_KEY_BUNDLE_NAME].is_string()) {
476          info.bundleName = jsonObject.at(JSON_KEY_BUNDLE_NAME).get<std::string>();
477      }
478  
479      if (jsonObject.contains(JSON_KEY_MODULE_NAME) && jsonObject[JSON_KEY_MODULE_NAME].is_string()) {
480          info.moduleName = jsonObject.at(JSON_KEY_MODULE_NAME).get<std::string>();
481      }
482  
483      if (jsonObject.contains(JSON_KEY_ABILITY_NAME) && jsonObject[JSON_KEY_ABILITY_NAME].is_string()) {
484          info.abilityName = jsonObject.at(JSON_KEY_ABILITY_NAME).get<std::string>();
485      }
486  
487      if (jsonObject.contains(JSON_KEY_APP_CLONE_INDEX) && jsonObject[JSON_KEY_APP_CLONE_INDEX].is_number()) {
488          info.appCloneIndex = jsonObject.at(JSON_KEY_APP_CLONE_INDEX).get<int32_t>();
489      }
490  
491      if (jsonObject.contains(JSON_KEY_ACCESS_TOKENID) && jsonObject[JSON_KEY_ACCESS_TOKENID].is_string()) {
492          info.accessTokenId = jsonObject.at(JSON_KEY_ACCESS_TOKENID).get<std::string>();
493      }
494  
495      if (jsonObject.contains(JSON_KEY_USERID) && jsonObject[JSON_KEY_USERID].is_number()) {
496          info.userId = jsonObject.at(JSON_KEY_USERID).get<int32_t>();
497      }
498  
499      nlohmann::json jsonValueObject = nlohmann::json::parse(value.ToString(), nullptr, false);
500      if (jsonValueObject.is_discarded()) {
501          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Parse jsonValueObject failed");
502          return info;
503      }
504  
505      if (jsonValueObject.contains(JSON_KEY_TYPE_NAME) && jsonValueObject[JSON_KEY_TYPE_NAME].is_string()) {
506          info.abilityTypeName = jsonValueObject.at(JSON_KEY_TYPE_NAME).get<std::string>();
507      }
508      return info;
509  }
510  
IsEqual(nlohmann::json & jsonObject,const std::string & key,const std::string & value,bool checkEmpty)511  bool AbilityAutoStartupDataManager::IsEqual(
512      nlohmann::json &jsonObject, const std::string &key, const std::string &value, bool checkEmpty)
513  {
514      if (jsonObject.contains(key) && jsonObject[key].is_string()) {
515          std::string  jsonValue = jsonObject.at(key).get<std::string>();
516          if (checkEmpty && !jsonValue.empty() && jsonValue != value) {
517              return false;
518          } else if (value != jsonValue) {
519              return false;
520          }
521      }
522      return true;
523  }
524  
IsEqual(nlohmann::json & jsonObject,const std::string & key,int32_t value)525  bool AbilityAutoStartupDataManager::IsEqual(nlohmann::json &jsonObject, const std::string &key, int32_t value)
526  {
527      if (jsonObject.contains(key) && jsonObject[key].is_number()) {
528          if (value != jsonObject.at(key).get<int32_t>()) {
529              return false;
530          }
531      }
532      return true;
533  }
534  
IsEqual(const DistributedKv::Key & key,const AutoStartupInfo & info)535  bool AbilityAutoStartupDataManager::IsEqual(const DistributedKv::Key &key, const AutoStartupInfo &info)
536  {
537      nlohmann::json jsonObject = nlohmann::json::parse(key.ToString(), nullptr, false);
538      if (jsonObject.is_discarded()) {
539          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Parse json string failed");
540          return false;
541      }
542  
543      if (!IsEqual(jsonObject, JSON_KEY_BUNDLE_NAME, info.bundleName)
544          || !IsEqual(jsonObject, JSON_KEY_ABILITY_NAME, info.abilityName)
545          || !IsEqual(jsonObject, JSON_KEY_MODULE_NAME, info.moduleName, true)
546          || !IsEqual(jsonObject, JSON_KEY_APP_CLONE_INDEX, info.appCloneIndex)
547          || !IsEqual(jsonObject, JSON_KEY_ACCESS_TOKENID, info.accessTokenId)
548          || !IsEqual(jsonObject, JSON_KEY_USERID, info.userId)) {
549          return false;
550      }
551      return true;
552  }
553  
IsEqual(const DistributedKv::Key & key,const std::string & accessTokenId)554  bool AbilityAutoStartupDataManager::IsEqual(const DistributedKv::Key &key, const std::string &accessTokenId)
555  {
556      nlohmann::json jsonObject = nlohmann::json::parse(key.ToString(), nullptr, false);
557      if (jsonObject.is_discarded()) {
558          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Parse json string failed");
559          return false;
560      }
561  
562      if (jsonObject.contains(JSON_KEY_ACCESS_TOKENID) && jsonObject[JSON_KEY_ACCESS_TOKENID].is_string()) {
563          if (accessTokenId == jsonObject.at(JSON_KEY_ACCESS_TOKENID).get<std::string>()) {
564              return true;
565          }
566      }
567      return false;
568  }
569  
IsEqual(const DistributedKv::Key & key,int32_t userId)570  bool AbilityAutoStartupDataManager::IsEqual(const DistributedKv::Key &key, int32_t userId)
571  {
572      nlohmann::json jsonObject = nlohmann::json::parse(key.ToString(), nullptr, false);
573      if (jsonObject.is_discarded()) {
574          TAG_LOGE(AAFwkTag::AUTO_STARTUP, "Parse json string failed");
575          return false;
576      }
577  
578      if (jsonObject.contains(JSON_KEY_USERID) && jsonObject[JSON_KEY_USERID].is_number()) {
579          if (userId == jsonObject.at(JSON_KEY_USERID).get<int32_t>()) {
580              return true;
581          }
582      }
583      return false;
584  }
585  } // namespace AbilityRuntime
586  } // namespace OHOS
587