• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #define LOG_TAG "KvStoreAppManager"
17 
18 #include "kvstore_app_manager.h"
19 
20 #include <directory_ex.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include <thread>
26 
27 #include "account_delegate.h"
28 #include "broadcast_sender.h"
29 #include "checker/checker_manager.h"
30 #include "constant.h"
31 #include "device_kvstore_impl.h"
32 #include "directory_utils.h"
33 #include "ikvstore.h"
34 #include "kv_store_delegate.h"
35 #include "kvstore_app_accessor.h"
36 #include "kvstore_utils.h"
37 #include "log_print.h"
38 #include "permission_validator.h"
39 #include "reporter.h"
40 #include "route_head_handler_impl.h"
41 #include "types.h"
42 
43 namespace OHOS {
44 namespace DistributedKv {
45 using namespace OHOS::DistributedData;
KvStoreAppManager(const std::string & bundleName,pid_t uid)46 KvStoreAppManager::KvStoreAppManager(const std::string &bundleName, pid_t uid)
47     : bundleName_(bundleName), uid_(uid), flowCtrl_(BURST_CAPACITY, SUSTAINED_CAPACITY)
48 {
49     ZLOGI("begin.");
50     deviceAccountId_ = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
51     GetDelegateManager(PATH_DE);
52     GetDelegateManager(PATH_CE);
53 }
54 
~KvStoreAppManager()55 KvStoreAppManager::~KvStoreAppManager()
56 {
57     ZLOGD("begin.");
58     stores_[PATH_DE].clear();
59     stores_[PATH_CE].clear();
60 
61     {
62         std::lock_guard<std::mutex> guard(delegateMutex_);
63         delete delegateManagers_[PATH_DE];
64         delete delegateManagers_[PATH_CE];
65         delegateManagers_[PATH_DE] = nullptr;
66         delegateManagers_[PATH_CE] = nullptr;
67     }
68 }
69 
ConvertErrorStatus(DistributedDB::DBStatus dbStatus,bool createIfMissing)70 Status KvStoreAppManager::ConvertErrorStatus(DistributedDB::DBStatus dbStatus, bool createIfMissing)
71 {
72     if (dbStatus != DistributedDB::DBStatus::OK) {
73         ZLOGE("delegate return error: %d.", static_cast<int>(dbStatus));
74         switch (dbStatus) {
75             case DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB:
76                 return Status::CRYPT_ERROR;
77             case DistributedDB::DBStatus::SCHEMA_MISMATCH:
78                 return Status::SCHEMA_MISMATCH;
79             case DistributedDB::DBStatus::INVALID_SCHEMA:
80                 return Status::INVALID_SCHEMA;
81             case DistributedDB::DBStatus::NOT_SUPPORT:
82                 return Status::NOT_SUPPORT;
83             case DistributedDB::DBStatus::EKEYREVOKED_ERROR: // fallthrough
84             case DistributedDB::DBStatus::SECURITY_OPTION_CHECK_ERROR:
85                 return Status::SECURITY_LEVEL_ERROR;
86             default:
87                 break;
88         }
89         if (createIfMissing) {
90             return Status::DB_ERROR;
91         } else {
92             return Status::STORE_NOT_FOUND;
93         }
94     }
95     return Status::SUCCESS;
96 }
97 
GetKvStore(const Options & options,const std::string & appId,const std::string & storeId,const std::vector<uint8_t> & cipherKey,sptr<KvStoreImpl> & kvStore)98 Status KvStoreAppManager::GetKvStore(const Options &options, const std::string &appId, const std::string &storeId,
99     const std::vector<uint8_t> &cipherKey, sptr<KvStoreImpl> &kvStore)
100 {
101     ZLOGI("begin");
102     kvStore = nullptr;
103     PathType type = ConvertPathType(uid_, bundleName_, options.securityLevel);
104     auto *delegateManager = GetDelegateManager(type);
105     if (delegateManager == nullptr) {
106         ZLOGE("delegateManagers[%d] is nullptr.", type);
107         return Status::ILLEGAL_STATE;
108     }
109 
110     if (!flowCtrl_.IsTokenEnough()) {
111         ZLOGE("flow control denied");
112         return Status::EXCEED_MAX_ACCESS_RATE;
113     }
114 
115     std::lock_guard<std::mutex> lg(storeMutex_);
116     auto it = stores_[type].find(storeId);
117     if (it != stores_[type].end()) {
118         kvStore = it->second;
119         ZLOGI("find store in map refcount: %d.", kvStore->GetSptrRefCount());
120         kvStore->IncreaseOpenCount();
121         return Status::SUCCESS;
122     }
123 
124     if ((GetTotalKvStoreNum()) >= static_cast<size_t>(Constant::MAX_OPEN_KVSTORES)) {
125         ZLOGE("limit %d KvStores can be opened.", Constant::MAX_OPEN_KVSTORES);
126         return Status::ERROR;
127     }
128 
129     DistributedDB::KvStoreDelegate::Option dbOption;
130     auto status = InitDbOption(options, cipherKey, dbOption);
131     if (status != Status::SUCCESS) {
132         ZLOGE("InitDbOption failed.");
133         return status;
134     }
135 
136     DistributedDB::KvStoreDelegate *storeDelegate = nullptr;
137     DistributedDB::DBStatus dbStatusTmp;
138     delegateManager->GetKvStore(storeId, dbOption,
139         [&storeDelegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreDelegate *delegate) {
140             storeDelegate = delegate;
141             dbStatusTmp = dbStatus;
142         });
143 
144     if (storeDelegate == nullptr) {
145         ZLOGE("storeDelegate is nullptr, status:%d.", static_cast<int>(dbStatusTmp));
146         return ConvertErrorStatus(dbStatusTmp, options.createIfMissing);
147     }
148 
149     ZLOGD("get delegate");
150     kvStore = new (std::nothrow)KvStoreImpl(options, deviceAccountId_, bundleName_,
151         appId, storeId, GetDbDir(options), storeDelegate);
152     if (kvStore == nullptr) {
153         delegateManager->CloseKvStore(storeDelegate);
154         kvStore = nullptr;
155         return Status::ERROR;
156     }
157     auto result = stores_[type].emplace(storeId, kvStore);
158     if (!result.second) {
159         ZLOGE("emplace failed.");
160         delegateManager->CloseKvStore(storeDelegate);
161         kvStore = nullptr;
162         return Status::ERROR;
163     }
164 
165     ZLOGD("after emplace refcount: %d", kvStore->GetSptrRefCount());
166     return Status::SUCCESS;
167 }
168 
GetKvStore(const Options & options,const std::string & appId,const std::string & storeId,const std::vector<uint8_t> & cipherKey,sptr<SingleKvStoreImpl> & kvStore)169 Status KvStoreAppManager::GetKvStore(const Options &options, const std::string &appId, const std::string &storeId,
170     const std::vector<uint8_t> &cipherKey, sptr<SingleKvStoreImpl> &kvStore)
171 {
172     ZLOGI("begin");
173     kvStore = nullptr;
174     PathType type = ConvertPathType(uid_, bundleName_, options.securityLevel);
175     auto *delegateManager = GetDelegateManager(type);
176     if (delegateManager == nullptr) {
177         ZLOGE("delegateManagers[%d] is nullptr.", type);
178         return Status::ILLEGAL_STATE;
179     }
180 
181     if (!flowCtrl_.IsTokenEnough()) {
182         ZLOGE("flow control denied");
183         return Status::EXCEED_MAX_ACCESS_RATE;
184     }
185     std::lock_guard<std::mutex> lg(storeMutex_);
186     auto it = singleStores_[type].find(storeId);
187     if (it != singleStores_[type].end()) {
188         kvStore = it->second;
189         ZLOGI("find store in map refcount: %d.", kvStore->GetSptrRefCount());
190         kvStore->IncreaseOpenCount();
191         return Status::SUCCESS;
192     }
193 
194     if ((GetTotalKvStoreNum()) >= static_cast<size_t>(Constant::MAX_OPEN_KVSTORES)) {
195         ZLOGE("limit %d KvStores can be opened.", Constant::MAX_OPEN_KVSTORES);
196         return Status::ERROR;
197     }
198 
199     DistributedDB::KvStoreNbDelegate::Option dbOption;
200     auto status = InitNbDbOption(options, cipherKey, dbOption);
201     if (status != Status::SUCCESS) {
202         ZLOGE("InitNbDbOption failed.");
203         return status;
204     }
205 
206     DistributedDB::KvStoreNbDelegate *storeDelegate = nullptr;
207     DistributedDB::DBStatus dbStatusTmp;
208     delegateManager->GetKvStore(storeId, dbOption,
209         [&](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *kvStoreDelegate) {
210             storeDelegate = kvStoreDelegate;
211             dbStatusTmp = dbStatus;
212         });
213 
214     if (storeDelegate == nullptr) {
215         ZLOGE("storeDelegate is nullptr.");
216         return ConvertErrorStatus(dbStatusTmp, options.createIfMissing);
217     }
218     std::string kvStorePath = GetDbDir(options);
219     switch (options.kvStoreType) {
220         case KvStoreType::DEVICE_COLLABORATION:
221             kvStore = new (std::nothrow) DeviceKvStoreImpl(
222                 options, deviceAccountId_, bundleName_, storeId, trueAppId_, kvStorePath, storeDelegate);
223             break;
224         default:
225             kvStore = new (std::nothrow) SingleKvStoreImpl(
226                 options, deviceAccountId_, bundleName_, storeId, trueAppId_, kvStorePath, storeDelegate);
227             break;
228     }
229     if (kvStore == nullptr) {
230         ZLOGE("store is nullptr.");
231         delegateManager->CloseKvStore(storeDelegate);
232         kvStore = nullptr;
233         return Status::ERROR;
234     }
235     kvStore->SetCompatibleIdentify();
236     auto result = singleStores_[type].emplace(storeId, kvStore);
237     if (!result.second) {
238         ZLOGE("emplace failed.");
239         delegateManager->CloseKvStore(storeDelegate);
240         kvStore = nullptr;
241         return Status::ERROR;
242     }
243 
244     ZLOGI("after emplace refcount: %d autoSync: %d", kvStore->GetSptrRefCount(), static_cast<int>(options.autoSync));
245     if (options.autoSync) {
246         bool autoSync = true;
247         DistributedDB::PragmaData data = static_cast<DistributedDB::PragmaData>(&autoSync);
248         auto pragmaStatus = storeDelegate->Pragma(DistributedDB::PragmaCmd::AUTO_SYNC, data);
249         if (pragmaStatus != DistributedDB::DBStatus::OK) {
250             ZLOGE("pragmaStatus: %d", static_cast<int>(pragmaStatus));
251         }
252     }
253 
254     DistributedDB::AutoLaunchOption launchOption = {
255         options.createIfMissing, options.encrypt, dbOption.cipher, dbOption.passwd, dbOption.schema,
256         dbOption.createDirByStoreIdOnly, kvStorePath, nullptr
257     };
258     launchOption.secOption = ConvertSecurity(options.securityLevel);
259     AppAccessorParam accessorParam = {Constant::DEFAULT_GROUP_ID, trueAppId_, storeId, launchOption};
260     KvStoreAppAccessor::GetInstance().EnableKvStoreAutoLaunch(accessorParam);
261     return Status::SUCCESS;
262 }
263 
CloseKvStore(const std::string & storeId)264 Status KvStoreAppManager::CloseKvStore(const std::string &storeId)
265 {
266     ZLOGI("CloseKvStore");
267     if (!flowCtrl_.IsTokenEnough()) {
268         ZLOGE("flow control denied");
269         return Status::EXCEED_MAX_ACCESS_RATE;
270     }
271     std::lock_guard<std::mutex> lg(storeMutex_);
272     Status status = CloseKvStore(storeId, PATH_DE);
273     if (status != Status::STORE_NOT_OPEN) {
274         return status;
275     }
276 
277     status = CloseKvStore(storeId, PATH_CE);
278     if (status != Status::STORE_NOT_OPEN) {
279         return status;
280     }
281 
282     ZLOGW("store not open");
283     return Status::STORE_NOT_OPEN;
284 }
285 
CloseAllKvStore()286 Status KvStoreAppManager::CloseAllKvStore()
287 {
288     ZLOGI("begin.");
289     std::lock_guard<std::mutex> lg(storeMutex_);
290     if (GetTotalKvStoreNum() == 0) {
291         return Status::STORE_NOT_OPEN;
292     }
293 
294     ZLOGI("close %zu KvStores.", GetTotalKvStoreNum());
295     Status status = CloseAllKvStore(PATH_DE);
296     if (status == Status::DB_ERROR) {
297         return status;
298     }
299     status = CloseAllKvStore(PATH_CE);
300     if (status == Status::DB_ERROR) {
301         return status;
302     }
303     return Status::SUCCESS;
304 }
305 
DeleteKvStore(const std::string & storeId)306 Status KvStoreAppManager::DeleteKvStore(const std::string &storeId)
307 {
308     ZLOGI("%s", storeId.c_str());
309     if (!flowCtrl_.IsTokenEnough()) {
310         ZLOGE("flow control denied");
311         return Status::EXCEED_MAX_ACCESS_RATE;
312     }
313 
314     Status statusDE = DeleteKvStore(storeId, PATH_DE);
315     Status statusCE = DeleteKvStore(storeId, PATH_CE);
316     if (statusDE == Status::SUCCESS || statusCE == Status::SUCCESS) {
317         return Status::SUCCESS;
318     }
319 
320     ZLOGE("delegate close error.");
321     return Status::DB_ERROR;
322 }
323 
DeleteAllKvStore()324 Status KvStoreAppManager::DeleteAllKvStore()
325 {
326     ZLOGI("begin.");
327     std::lock_guard<std::mutex> lg(storeMutex_);
328     if (GetTotalKvStoreNum() == 0) {
329         return Status::STORE_NOT_OPEN;
330     }
331     ZLOGI("delete %d KvStores.", int32_t(GetTotalKvStoreNum()));
332 
333     Status status = DeleteAllKvStore(PATH_DE);
334     if (status != Status::SUCCESS) {
335         ZLOGE("path de delegate delete error: %d.", static_cast<int>(status));
336         return Status::DB_ERROR;
337     }
338     status = DeleteAllKvStore(PATH_CE);
339     if (status != Status::SUCCESS) {
340         ZLOGE("path ce delegate delete error: %d.", static_cast<int>(status));
341         return Status::DB_ERROR;
342     }
343     return Status::SUCCESS;
344 }
345 
MigrateAllKvStore(const std::string & harmonyAccountId)346 Status KvStoreAppManager::MigrateAllKvStore(const std::string &harmonyAccountId)
347 {
348     ZLOGI("begin");
349     if (PermissionValidator::IsAutoLaunchEnabled(bundleName_)) {
350         return Status::SUCCESS;
351     }
352 
353     std::lock_guard<std::mutex> lg(storeMutex_);
354     // update userid in kvstore tuple map of permission adapter.
355     KvStoreTuple srcKvStoreTuple {userId_, bundleName_};
356     KvStoreTuple dstKvStoreTuple {harmonyAccountId, bundleName_};
357     PermissionValidator::UpdateKvStoreTupleMap(srcKvStoreTuple, dstKvStoreTuple);
358     userId_ = harmonyAccountId;
359     ZLOGI("path de migration begin.");
360     Status statusDE = MigrateAllKvStore(harmonyAccountId, PATH_DE);
361     ZLOGI("path ce migration begin.");
362     Status statusCE = MigrateAllKvStore(harmonyAccountId, PATH_CE);
363     return (statusCE != Status::SUCCESS) ? statusCE : statusDE;
364 }
365 
InitDbOption(const Options & options,const std::vector<uint8_t> & cipherKey,DistributedDB::KvStoreDelegate::Option & dbOption)366 Status KvStoreAppManager::InitDbOption(const Options &options, const std::vector<uint8_t> &cipherKey,
367                                        DistributedDB::KvStoreDelegate::Option &dbOption)
368 {
369     DistributedDB::CipherPassword password;
370     auto status = password.SetValue(cipherKey.data(), cipherKey.size());
371     if (status != DistributedDB::CipherPassword::ErrorCode::OK) {
372         ZLOGE("Failed to set the passwd.");
373         return Status::DB_ERROR;
374     }
375     dbOption.createIfNecessary = options.createIfMissing;
376     dbOption.localOnly = false;
377     dbOption.isEncryptedDb = options.encrypt;
378     if (options.encrypt) {
379         dbOption.cipher = DistributedDB::CipherType::AES_256_GCM;
380         dbOption.passwd = password;
381     }
382     dbOption.createDirByStoreIdOnly = options.dataOwnership;
383     return Status::SUCCESS;
384 }
385 
InitNbDbOption(const Options & options,const std::vector<uint8_t> & cipherKey,DistributedDB::KvStoreNbDelegate::Option & dbOption)386 Status KvStoreAppManager::InitNbDbOption(const Options &options, const std::vector<uint8_t> &cipherKey,
387                                          DistributedDB::KvStoreNbDelegate::Option &dbOption)
388 {
389     DistributedDB::CipherPassword password;
390     auto status = password.SetValue(cipherKey.data(), cipherKey.size());
391     if (status != DistributedDB::CipherPassword::ErrorCode::OK) {
392         ZLOGE("Failed to set the passwd.");
393         return Status::DB_ERROR;
394     }
395 
396     dbOption.syncDualTupleMode = true; // tuple of (appid+storeid)
397     dbOption.createIfNecessary = options.createIfMissing;
398     dbOption.isEncryptedDb = options.encrypt;
399     if (options.encrypt) {
400         dbOption.cipher = DistributedDB::CipherType::AES_256_GCM;
401         dbOption.passwd = password;
402     }
403 
404     if (options.kvStoreType == KvStoreType::SINGLE_VERSION) {
405         dbOption.conflictResolvePolicy = DistributedDB::LAST_WIN;
406     } else if (options.kvStoreType == KvStoreType::DEVICE_COLLABORATION) {
407         dbOption.conflictResolvePolicy = DistributedDB::DEVICE_COLLABORATION;
408     } else {
409         ZLOGE("kvStoreType is invalid");
410         return Status::INVALID_ARGUMENT;
411     }
412 
413     dbOption.schema = options.schema;
414     dbOption.createDirByStoreIdOnly = options.dataOwnership;
415     dbOption.secOption = ConvertSecurity(options.securityLevel);
416     return Status::SUCCESS;
417 }
418 
GetDbDir(const Options & options) const419 std::string KvStoreAppManager::GetDbDir(const Options &options) const
420 {
421     return GetDataStoragePath(deviceAccountId_, bundleName_, ConvertPathType(uid_, bundleName_, options.securityLevel));
422 }
423 
ConvertPathType(int32_t uid,const std::string & bundleName,int securityLevel)424 KvStoreAppManager::PathType KvStoreAppManager::ConvertPathType(int32_t uid, const std::string &bundleName,
425                                                                int securityLevel)
426 {
427     switch (securityLevel) {
428         case S0:    // fallthrough
429         case S1:
430             return PATH_DE;
431         case S2:    // fallthrough
432         case S3_EX: // fallthrough
433         case S3:    // fallthrough
434         case S4:    // fallthrough
435             return PATH_CE;
436         default:
437             break;
438     }
439     auto *checker = CheckerManager::GetInstance().GetChecker(CheckerManager::SYSTEM_CHECKER);
440     if (checker == nullptr || !checker->IsValid(uid, bundleName)) {
441         return PATH_CE;
442     }
443     return PATH_DE;
444 }
445 
GetDelegateManager(PathType type)446 DistributedDB::KvStoreDelegateManager *KvStoreAppManager::GetDelegateManager(PathType type)
447 {
448     std::lock_guard<std::mutex> guard(delegateMutex_);
449     if (delegateManagers_[type] != nullptr) {
450         return delegateManagers_[type];
451     }
452 
453     std::string directory = GetDataStoragePath(deviceAccountId_, bundleName_, type);
454     bool ret = ForceCreateDirectory(directory);
455     if (!ret) {
456         ZLOGE("create directory[%s] failed, errstr=[%d].", directory.c_str(), errno);
457         return nullptr;
458     }
459     // change mode for directories to 0755, and for files to 0600.
460     DirectoryUtils::ChangeModeDirOnly(directory, Constant::DEFAULT_MODE_DIR);
461     DirectoryUtils::ChangeModeFileOnly(directory, Constant::DEFAULT_MODE_FILE);
462 
463     trueAppId_ = CheckerManager::GetInstance().GetAppId(bundleName_, uid_);
464     if (trueAppId_.empty()) {
465         delegateManagers_[type] = nullptr;
466         ZLOGW("check bundleName:%{public}s uid:%{public}d failed.", bundleName_.c_str(), uid_);
467         return nullptr;
468     }
469 
470     userId_ = AccountDelegate::GetInstance()->GetCurrentAccountId(bundleName_);
471     ZLOGD("accountId: %{public}s bundleName: %{public}s", deviceAccountId_.c_str(), bundleName_.c_str());
472     delegateManagers_[type] = new (std::nothrow) DistributedDB::KvStoreDelegateManager(trueAppId_, deviceAccountId_);
473     if (delegateManagers_[type] == nullptr) {
474         ZLOGE("delegateManagers_[%d] is nullptr.", type);
475         return nullptr;
476     }
477 
478     DistributedDB::KvStoreConfig kvStoreConfig;
479     kvStoreConfig.dataDir = directory;
480     delegateManagers_[type]->SetKvStoreConfig(kvStoreConfig);
481     return delegateManagers_[type];
482 }
483 
SwitchDelegateManager(PathType type,DistributedDB::KvStoreDelegateManager * delegateManager)484 DistributedDB::KvStoreDelegateManager *KvStoreAppManager::SwitchDelegateManager(PathType type,
485     DistributedDB::KvStoreDelegateManager *delegateManager)
486 {
487     std::lock_guard<std::mutex> guard(delegateMutex_);
488     DistributedDB::KvStoreDelegateManager *oldDelegateManager = delegateManagers_[type];
489     delegateManagers_[type] = delegateManager;
490     return oldDelegateManager;
491 }
492 
CloseKvStore(const std::string & storeId,PathType type)493 Status KvStoreAppManager::CloseKvStore(const std::string &storeId, PathType type)
494 {
495     auto *delegateManager = GetDelegateManager(type);
496     if (delegateManager == nullptr) {
497         ZLOGE("delegateManager[%d] is null.", type);
498         return Status::ILLEGAL_STATE;
499     }
500 
501     auto it = stores_[type].find(storeId);
502     if (it != stores_[type].end()) {
503         ZLOGD("find store and close delegate.");
504         InnerStatus status = it->second->Close(delegateManager);
505         if (status == InnerStatus::SUCCESS) {
506             stores_[type].erase(it);
507             return Status::SUCCESS;
508         }
509         if (status == InnerStatus::DECREASE_REFCOUNT) {
510             return Status::SUCCESS;
511         }
512         ZLOGE("delegate close error: %d.", static_cast<int>(status));
513         return Status::DB_ERROR;
514     }
515 
516     auto itSingle = singleStores_[type].find(storeId);
517     if (itSingle != singleStores_[type].end()) {
518         ZLOGD("find single store and close delegate.");
519         InnerStatus status = itSingle->second->Close(delegateManager);
520         if (status == InnerStatus::SUCCESS) {
521             singleStores_[type].erase(itSingle);
522             return Status::SUCCESS;
523         }
524         if (status == InnerStatus::DECREASE_REFCOUNT) {
525             return Status::SUCCESS;
526         }
527         ZLOGE("delegate close error: %d.", static_cast<int>(status));
528         return Status::DB_ERROR;
529     }
530 
531     return Status::STORE_NOT_OPEN;
532 }
533 
CloseAllKvStore(PathType type)534 Status KvStoreAppManager::CloseAllKvStore(PathType type)
535 {
536     auto *delegateManager = GetDelegateManager(type);
537     if (delegateManager == nullptr) {
538         ZLOGE("delegateManager[%d] is null.", type);
539         return Status::ILLEGAL_STATE;
540     }
541 
542     for (auto it = stores_[type].begin(); it != stores_[type].end(); it = stores_[type].erase(it)) {
543         KvStoreImpl *currentStore = it->second.GetRefPtr();
544         ZLOGI("close kvstore, refcount %d.", it->second->GetSptrRefCount());
545         Status status = currentStore->ForceClose(delegateManager);
546         if (status != Status::SUCCESS) {
547             ZLOGE("delegate close error: %d.", static_cast<int>(status));
548             return Status::DB_ERROR;
549         }
550     }
551     stores_[type].clear();
552 
553     for (auto it = singleStores_[type].begin(); it != singleStores_[type].end(); it = singleStores_[type].erase(it)) {
554         SingleKvStoreImpl *currentStore = it->second.GetRefPtr();
555         ZLOGI("close kvstore, refcount %d.", it->second->GetSptrRefCount());
556         Status status = currentStore->ForceClose(delegateManager);
557         if (status != Status::SUCCESS) {
558             ZLOGE("delegate close error: %d.", static_cast<int>(status));
559             return Status::DB_ERROR;
560         }
561     }
562     singleStores_[type].clear();
563     return Status::SUCCESS;
564 }
565 
DeleteKvStore(const std::string & storeId,PathType type)566 Status KvStoreAppManager::DeleteKvStore(const std::string &storeId, PathType type)
567 {
568     auto *delegateManager = GetDelegateManager(type);
569     if (delegateManager == nullptr) {
570         ZLOGE("delegateManager[%d] is null.", type);
571         return Status::ILLEGAL_STATE;
572     }
573     std::lock_guard<std::mutex> lg(storeMutex_);
574     auto it = stores_[type].find(storeId);
575     if (it != stores_[type].end()) {
576         Status status = it->second->ForceClose(delegateManager);
577         if (status != Status::SUCCESS) {
578             return Status::DB_ERROR;
579         }
580         stores_[type].erase(it);
581     }
582 
583     auto itSingle = singleStores_[type].find(storeId);
584     if (itSingle != singleStores_[type].end()) {
585         Status status = itSingle->second->ForceClose(delegateManager);
586         if (status != Status::SUCCESS) {
587             return Status::DB_ERROR;
588         }
589         singleStores_[type].erase(itSingle);
590     }
591 
592     DistributedDB::DBStatus status = delegateManager->DeleteKvStore(storeId);
593     if (singleStores_[type].empty() && stores_[type].empty()) {
594         SwitchDelegateManager(type, nullptr);
595         delete delegateManager;
596     }
597     return (status != DistributedDB::DBStatus::OK) ? Status::DB_ERROR : Status::SUCCESS;
598 }
599 
DeleteAllKvStore(PathType type)600 Status KvStoreAppManager::DeleteAllKvStore(PathType type)
601 {
602     auto *delegateManager = GetDelegateManager(type);
603     if (delegateManager == nullptr) {
604         ZLOGE("delegateManager[%d] is null.", type);
605         return Status::ILLEGAL_STATE;
606     }
607 
608     for (auto it = stores_[type].begin(); it != stores_[type].end(); it = stores_[type].erase(it)) {
609         std::string storeId = it->first;
610         KvStoreImpl *currentStore = it->second.GetRefPtr();
611         Status status = currentStore->ForceClose(delegateManager);
612         if (status != Status::SUCCESS) {
613             ZLOGE("delegate delete close failed error: %d.", static_cast<int>(status));
614             return Status::DB_ERROR;
615         }
616 
617         ZLOGI("delete kvstore, refcount %d.", it->second->GetSptrRefCount());
618         DistributedDB::DBStatus dbStatus = delegateManager->DeleteKvStore(storeId);
619         if (dbStatus != DistributedDB::DBStatus::OK) {
620             ZLOGE("delegate delete error: %d.", static_cast<int>(dbStatus));
621             return Status::DB_ERROR;
622         }
623     }
624     stores_[type].clear();
625 
626     for (auto it = singleStores_[type].begin(); it != singleStores_[type].end(); it = singleStores_[type].erase(it)) {
627         std::string storeId = it->first;
628         SingleKvStoreImpl *currentStore = it->second.GetRefPtr();
629         Status status = currentStore->ForceClose(delegateManager);
630         if (status != Status::SUCCESS) {
631             ZLOGE("delegate delete close failed error: %d.", static_cast<int>(status));
632             return Status::DB_ERROR;
633         }
634 
635         ZLOGI("close kvstore, refcount %d.", it->second->GetSptrRefCount());
636         DistributedDB::DBStatus dbStatus = delegateManager->DeleteKvStore(storeId);
637         if (dbStatus != DistributedDB::DBStatus::OK) {
638             ZLOGE("delegate delete error: %d.", static_cast<int>(dbStatus));
639             return Status::DB_ERROR;
640         }
641     }
642     singleStores_[type].clear();
643     SwitchDelegateManager(type, nullptr);
644     delete delegateManager;
645     return Status::SUCCESS;
646 }
647 
MigrateAllKvStore(const std::string & harmonyAccountId,PathType type)648 Status KvStoreAppManager::MigrateAllKvStore(const std::string &harmonyAccountId, PathType type)
649 {
650     auto *delegateManager = GetDelegateManager(type);
651     if (delegateManager == nullptr) {
652         ZLOGE("delegateManager is nullptr.");
653         return Status::ILLEGAL_STATE;
654     }
655 
656     std::string dirPath = GetDataStoragePath(deviceAccountId_, bundleName_, type);
657     DistributedDB::KvStoreDelegateManager *newDelegateManager = nullptr;
658     Status status = Status::SUCCESS;
659     ZLOGI("KvStore migration begin.");
660     for (auto &it : stores_[type]) {
661         sptr<KvStoreImpl> impl = it.second;
662         if (impl->MigrateKvStore(harmonyAccountId, dirPath, delegateManager, newDelegateManager) != Status::SUCCESS) {
663             status = Status::MIGRATION_KVSTORE_FAILED;
664             ZLOGE("migrate kvstore for appId-%s failed.", bundleName_.c_str());
665             // skip this failed, continue to migrate other kvstore.
666         }
667     }
668 
669     ZLOGI("SingleKvStore migration begin.");
670     for (auto &it : singleStores_[type]) {
671         sptr<SingleKvStoreImpl> impl = it.second;
672         if (impl->MigrateKvStore(harmonyAccountId, dirPath, delegateManager, newDelegateManager) != Status::SUCCESS) {
673             status = Status::MIGRATION_KVSTORE_FAILED;
674             ZLOGE("migrate single kvstore for appId-%s failed.", bundleName_.c_str());
675             // skip this failed, continue to migrate other kvstore.
676         }
677     }
678 
679     if (newDelegateManager != nullptr) {
680         delegateManager = SwitchDelegateManager(type, newDelegateManager);
681         delete delegateManager;
682     }
683     return status;
684 }
685 
GetTotalKvStoreNum() const686 size_t KvStoreAppManager::GetTotalKvStoreNum() const
687 {
688     size_t total = stores_[PATH_DE].size();
689     total += stores_[PATH_CE].size();
690     total += singleStores_[PATH_DE].size();
691     total += singleStores_[PATH_CE].size();
692     return int(total);
693 };
694 
GetDataStoragePath(const std::string & userId,const std::string & bundleName,PathType type)695 std::string KvStoreAppManager::GetDataStoragePath(const std::string &userId, const std::string &bundleName,
696                                                   PathType type)
697 {
698     std::string miscPath = (type == PATH_DE) ? Constant::ROOT_PATH_DE : Constant::ROOT_PATH_CE;
699     return Constant::Concatenate({
700         miscPath, "/", Constant::SERVICE_NAME, "/", userId, "/", Constant::GetDefaultHarmonyAccountName(),
701         "/", bundleName, "/"
702     });
703 }
704 
ConvertSecurity(int securityLevel)705 DistributedDB::SecurityOption KvStoreAppManager::ConvertSecurity(int securityLevel)
706 {
707     if (securityLevel < SecurityLevel::NO_LABEL || securityLevel > SecurityLevel::S4) {
708         return {DistributedDB::NOT_SET, DistributedDB::ECE};
709     }
710     switch (securityLevel) {
711         case SecurityLevel::S3:
712             return {DistributedDB::S3, DistributedDB::SECE};
713         case SecurityLevel::S4:
714             return {DistributedDB::S4, DistributedDB::ECE};
715         default:
716             return {securityLevel, DistributedDB::ECE};
717     }
718 }
719 
Dump(int fd) const720 void KvStoreAppManager::Dump(int fd) const
721 {
722     const std::string prefix(8, ' ');
723     std::string dePath = GetDataStoragePath(deviceAccountId_, bundleName_, PATH_DE);
724     std::string cePath = GetDataStoragePath(deviceAccountId_, bundleName_, PATH_CE);
725     size_t singleStoreNum = singleStores_[PATH_DE].size() + singleStores_[PATH_CE].size();
726     dprintf(fd, "%s----------------------------------------------------------\n", prefix.c_str());
727     dprintf(fd, "%sAppID         : %s\n", prefix.c_str(), trueAppId_.c_str());
728     dprintf(fd, "%sBundleName    : %s\n", prefix.c_str(), bundleName_.c_str());
729     dprintf(fd, "%sAppDEDirectory: %s\n", prefix.c_str(), dePath.c_str());
730     dprintf(fd, "%sAppCEDirectory: %s\n", prefix.c_str(), cePath.c_str());
731     dprintf(fd, "%sStore count   : %u\n", prefix.c_str(), static_cast<uint32_t>(singleStoreNum));
732     for (const auto &singleStoreMap : singleStores_) {
733         for (const auto &pair : singleStoreMap) {
734             pair.second->OnDump(fd);
735         }
736     }
737 }
738 
IsStoreOpened(const std::string & storeId) const739 bool KvStoreAppManager::IsStoreOpened(const std::string &storeId) const
740 {
741     return (!singleStores_[PATH_DE].empty() && singleStores_->find(storeId) != singleStores_->end())
742            || (!singleStores_[PATH_CE].empty() && singleStores_->find(storeId) != singleStores_->end());
743 }
744 
SetCompatibleIdentify(const std::string & deviceId) const745 void KvStoreAppManager::SetCompatibleIdentify(const std::string &deviceId) const
746 {
747     for (const auto &storeType : singleStores_) {
748         for (const auto &item : storeType) {
749             if (item.second == nullptr) {
750                 continue;
751             }
752             item.second->SetCompatibleIdentify(deviceId);
753         }
754     }
755 }
756 }  // namespace DistributedKv
757 }  // namespace OHOS
758