• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <utility>
16 #include <memory>
17 #include <unistd.h>
18 #include "safwk_log.h"
19 #include "string_ex.h"
20 #include "api_cache_manager.h"
21 
22 namespace OHOS {
23 namespace {
24 const std::string TAG = "ApiCacheManager";
25 }
26 
GetInstance()27 ApiCacheManager& ApiCacheManager::GetInstance()
28 {
29     static ApiCacheManager instance;
30     return instance;
31 }
32 
AddCacheApi(const std::u16string & descriptor,uint32_t apiCode,int64_t expireTimeSec)33 void ApiCacheManager::AddCacheApi(const std::u16string& descriptor, uint32_t apiCode, int64_t expireTimeSec)
34 {
35     constexpr size_t defaultCacheSize = 8;
36     auto apiPair = std::make_pair(descriptor, apiCode);
37 
38     std::lock_guard<std::mutex> lock(cachesMutex_);
39     auto iter = caches_.find(apiPair);
40     if (iter == caches_.end()) {
41         auto obj = new ExpireLruCache<std::vector<uint8_t>, std::vector<uint8_t>> (defaultCacheSize, expireTimeSec);
42         caches_[apiPair] = obj;
43         return;
44     }
45 
46     HILOGD(TAG, "Cache api(%{public}s, apiCode:%{public}u) already exists", Str16ToStr8(descriptor).c_str(), apiCode);
47     return;
48 }
49 
DelCacheApi(const std::u16string & descriptor,uint32_t apiCode)50 void ApiCacheManager::DelCacheApi(const std::u16string& descriptor, uint32_t apiCode)
51 {
52     auto apiPair = std::make_pair(descriptor, apiCode);
53     std::lock_guard<std::mutex> lock(cachesMutex_);
54     auto iter = caches_.find(apiPair);
55     if (iter != caches_.end()) {
56         if (iter->second != nullptr) {
57             delete iter->second;
58         }
59         caches_.erase(apiPair);
60         HILOGD(TAG, "Delete cache api(%{public}s, apiCode:%{public}u)", Str16ToStr8(descriptor).c_str(), apiCode);
61     }
62 
63     return;
64 }
65 
ClearCache()66 void ApiCacheManager::ClearCache()
67 {
68     std::lock_guard<std::mutex> lock(cachesMutex_);
69     for (auto &iter : caches_) {
70         if (iter.second != nullptr) {
71             iter.second->Clear();
72             HILOGD(TAG, "Clear the api(%{public}s, apiCode:%{public}u) cache",
73                 Str16ToStr8(iter.first.first).c_str(), iter.first.second);
74         }
75     }
76     return;
77 }
78 
ClearCache(const std::u16string & descriptor)79 void ApiCacheManager::ClearCache(const std::u16string& descriptor)
80 {
81     std::lock_guard<std::mutex> lock(cachesMutex_);
82     for (auto &iter : caches_) {
83         if ((iter.first.first == descriptor) && (iter.second != nullptr)) {
84             HILOGD(TAG, "Clear the api(%{public}s, apiCode:%{public}u) cache",
85                 Str16ToStr8(descriptor).c_str(), iter.first.second);
86             iter.second->Clear();
87         }
88     }
89     return;
90 }
91 
ClearCache(const std::u16string & descriptor,int32_t apiCode)92 void ApiCacheManager::ClearCache(const std::u16string& descriptor, int32_t apiCode)
93 {
94     std::lock_guard<std::mutex> lock(cachesMutex_);
95     auto iter = caches_.find(std::make_pair(descriptor, apiCode));
96     if ((iter != caches_.end()) && (iter->second != nullptr)) {
97         HILOGD(TAG, "Clear the api(%{public}s, apiCode:%{public}u) cache",
98             Str16ToStr8(descriptor).c_str(), apiCode);
99         iter->second->Clear();
100     }
101 
102     return;
103 }
104 
PreSendRequest(const std::u16string & descriptor,uint32_t apiCode,const MessageParcel & data,MessageParcel & reply)105 bool ApiCacheManager::PreSendRequest(const std::u16string& descriptor, uint32_t apiCode, const MessageParcel& data,
106     MessageParcel& reply)
107 {
108     uint8_t *key = reinterpret_cast<uint8_t *>(data.GetData());
109     size_t keySize = data.GetDataSize();
110     std::vector<uint8_t> keyVec(key, key + keySize);
111 
112     std::pair<std::u16string, uint32_t> myPair = std::make_pair(descriptor, apiCode);
113     std::lock_guard<std::mutex> lock(cachesMutex_);
114     auto cache = caches_.find(myPair);
115     if ((cache == caches_.end()) || (cache->second == nullptr)) {
116         HILOGD(TAG, "Find cache api(%{public}s, apiCode:%{public}u) from map failed, maybe this api is no cacheable",
117             Str16ToStr8(descriptor).c_str(), apiCode);
118         return false;
119     }
120 
121     std::shared_ptr<std::vector<uint8_t>> valueVec = cache->second->Get(keyVec);
122     if (valueVec == nullptr) {
123         HILOGD(TAG, "Cache hit failure");
124         return false;
125     }
126 
127     auto size = reply.GetDataSize() + valueVec->size();
128     if (size > reply.GetMaxCapacity()) {
129         reply.SetMaxCapacity(size);
130     }
131     auto ret = reply.WriteBuffer(reinterpret_cast<void *>(&(*valueVec)[0]), valueVec->size());
132     if (!ret) {
133         HILOGE(TAG, "Cache WriteBuffer failure");
134         return false;
135     }
136     HILOGD(TAG, "Cache hit success");
137     return true;
138 }
139 
PostSendRequest(const std::u16string & descriptor,uint32_t apiCode,const MessageParcel & data,MessageParcel & reply)140 bool ApiCacheManager::PostSendRequest(const std::u16string& descriptor, uint32_t apiCode, const MessageParcel& data,
141     MessageParcel& reply)
142 {
143     if (data.GetOffsetsSize() != 0 || reply.GetOffsetsSize() != 0) {
144         HILOGE(TAG, "not support IRemoteObject");
145         return false;
146     }
147     uint8_t *key = reinterpret_cast<uint8_t *>(data.GetData());
148     size_t keySize = data.GetDataSize();
149     std::vector<uint8_t> keyVec(key, key + keySize);
150 
151     std::pair<std::u16string, uint32_t> myPair = std::make_pair(descriptor, apiCode);
152     std::lock_guard<std::mutex> lock(cachesMutex_);
153     auto cache = caches_.find(myPair);
154     if ((cache == caches_.end()) || (cache->second == nullptr)) {
155         HILOGD(TAG, "Find cache api(%{public}s, apiCode:%{public}u) from map failed, maybe this api is no cacheable",
156             Str16ToStr8(descriptor).c_str(), apiCode);
157         return false;
158     }
159 
160     uint8_t *value = reinterpret_cast<uint8_t *>(reply.GetData());
161     size_t valueSize = reply.GetDataSize();
162     std::vector<uint8_t> valueVec(value, value + valueSize);
163 
164     cache->second->Add(keyVec, valueVec);
165     HILOGD(TAG, "Cache the reply of this call");
166 
167     return true;
168 }
169 }