1 /*
2 * Copyright (c) 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 #include "kv_adapter_manager.h"
16
17 #include <mutex>
18 #include <unistd.h>
19
20 #include "datetime_ex.h"
21 #include "string_ex.h"
22
23 #include "dm_anonymous.h"
24 #include "dm_error_type.h"
25 #include "dm_log.h"
26
27 namespace OHOS {
28 namespace DistributedHardware {
29 namespace {
30 constexpr const char* DM_KV_STORE_PREFIX = "DM2_";
31 constexpr const char* DB_KEY_DELIMITER = "###";
32 constexpr int64_t DM_KV_STORE_REFRESH_TIME = 24 * 60 * 60; // one day
33 constexpr int64_t MAX_SUPPORTED_EXIST_TIME = 3 * 24 * 60 * 60; // 3days
34 }
35
36 DM_IMPLEMENT_SINGLE_INSTANCE(KVAdapterManager);
37
Init()38 int32_t KVAdapterManager::Init()
39 {
40 LOGI("Init Kv-Adapter manager");
41 {
42 std::lock_guard<std::mutex> lock(idCacheMapMtx_);
43 idCacheMap_.clear();
44 }
45 kvAdapter_ = std::make_shared<KVAdapter>();
46 return kvAdapter_->Init();
47 }
48
UnInit()49 void KVAdapterManager::UnInit()
50 {
51 LOGI("Uninit Kv-Adapter manager");
52 CHECK_NULL_VOID(kvAdapter_);
53 kvAdapter_->UnInit();
54 kvAdapter_ = nullptr;
55 }
56
ReInit()57 void KVAdapterManager::ReInit()
58 {
59 LOGI("Re init kv adapter");
60 CHECK_NULL_VOID(kvAdapter_);
61 kvAdapter_->ReInit();
62 }
63
PutByAnoyDeviceId(const std::string & key,const DmKVValue & value)64 int32_t KVAdapterManager::PutByAnoyDeviceId(const std::string &key, const DmKVValue &value)
65 {
66 std::string dmKey = DM_KV_STORE_PREFIX + key;
67 std::lock_guard<std::mutex> lock(idCacheMapMtx_);
68 auto idIter = idCacheMap_.find(dmKey);
69 if (idIter != idCacheMap_.end() && !IsTimeOut(idIter->second.lastModifyTime, value.lastModifyTime,
70 DM_KV_STORE_REFRESH_TIME)) {
71 LOGD("Kv value is existed");
72 return DM_OK;
73 }
74 idCacheMap_[dmKey] = value;
75 std::string prefixKey = DM_KV_STORE_PREFIX + value.appID + DB_KEY_DELIMITER + value.udidHash;
76 idCacheMap_[prefixKey] = value;
77 std::string valueStr = "";
78 ConvertDmKVValueToJson(value, valueStr);
79 CHECK_NULL_RETURN(kvAdapter_, ERR_DM_POINT_NULL);
80 if (kvAdapter_->Put(dmKey, valueStr) != DM_OK) {
81 LOGE("Insert value to DB for dmKey failed");
82 return ERR_DM_FAILED;
83 }
84 if (kvAdapter_->Put(prefixKey, valueStr) != DM_OK) {
85 LOGE("Insert value to DB for prefixKey failed");
86 return ERR_DM_FAILED;
87 }
88 return DM_OK;
89 }
90
Get(const std::string & key,DmKVValue & value)91 int32_t KVAdapterManager::Get(const std::string &key, DmKVValue &value)
92 {
93 std::string dmKey = DM_KV_STORE_PREFIX + key;
94 std::lock_guard<std::mutex> lock(idCacheMapMtx_);
95 auto idIter = idCacheMap_.find(dmKey);
96 if (idIter != idCacheMap_.end()) {
97 value = idIter->second;
98 return DM_OK;
99 }
100 CHECK_NULL_RETURN(kvAdapter_, ERR_DM_POINT_NULL);
101 std::string valueStr;
102 if (kvAdapter_->Get(dmKey, valueStr) != DM_OK) {
103 LOGE("Get kv value failed, dmKey: %{public}s", GetAnonyString(dmKey).c_str());
104 return ERR_DM_FAILED;
105 }
106 ConvertJsonToDmKVValue(valueStr, value);
107 idCacheMap_[dmKey] = value;
108 std::string prefixKey = DM_KV_STORE_PREFIX + value.appID + DB_KEY_DELIMITER + value.udidHash;
109 idCacheMap_[prefixKey] = value;
110 return DM_OK;
111 }
112
DeleteAgedEntry()113 int32_t KVAdapterManager::DeleteAgedEntry()
114 {
115 int64_t nowTime = GetSecondsSince1970ToNow();
116 std::lock_guard<std::mutex> lock(idCacheMapMtx_);
117 for (auto it = idCacheMap_.begin(); it != idCacheMap_.end();) {
118 if (IsTimeOut(it->second.lastModifyTime, nowTime, MAX_SUPPORTED_EXIST_TIME)) {
119 it = idCacheMap_.erase(it);
120 } else {
121 ++it;
122 }
123 }
124 return DM_OK;
125 }
126
IsTimeOut(int64_t sourceTime,int64_t targetTime,int64_t timeOut)127 inline bool KVAdapterManager::IsTimeOut(int64_t sourceTime, int64_t targetTime, int64_t timeOut)
128 {
129 return targetTime - sourceTime >= timeOut ? true : false;
130 }
131
AppUnintall(const std::string & appId)132 int32_t KVAdapterManager::AppUnintall(const std::string &appId)
133 {
134 LOGI("appId %{public}s.", GetAnonyString(appId).c_str());
135 std::lock_guard<std::mutex> lock(idCacheMapMtx_);
136 for (auto it = idCacheMap_.begin(); it != idCacheMap_.end();) {
137 if (it->second.appID == appId) {
138 it = idCacheMap_.erase(it);
139 } else {
140 ++it;
141 }
142 }
143 CHECK_NULL_RETURN(kvAdapter_, ERR_DM_POINT_NULL);
144 if (kvAdapter_->DeleteByAppId(appId, DM_KV_STORE_PREFIX) != DM_OK) {
145 LOGE("DeleteByAppId failed");
146 return ERR_DM_FAILED;
147 }
148 return DM_OK;
149 }
150 } // namespace DistributedHardware
151 } // namespace OHOS
152