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