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