1 /* 2 * Copyright (c) 2023 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 #ifndef DYNAMIC_CACHE_H 17 #define DYNAMIC_CACHE_H 18 19 #include <map> 20 #include <string> 21 #include <vector> 22 23 #include "datetime_ex.h" 24 #include "iremote_object.h" 25 #include "parameter.h" 26 #include "refbase.h" 27 #include "sam_log.h" 28 #include "sysparam_errno.h" 29 30 namespace OHOS { 31 using namespace std; 32 class DynamicCache : public IRemoteObject::DeathRecipient { 33 public: OnRemoteDied(const wptr<IRemoteObject> & remote)34 void OnRemoteDied(const wptr<IRemoteObject>& remote) override 35 { 36 HILOGD("DynamicCache OnRemoteDied called"); 37 ClearCache(); 38 } QueryResult(int32_t querySaId,int32_t code)39 sptr<IRemoteObject> QueryResult(int32_t querySaId, int32_t code) 40 { 41 int32_t waterLineLength = 128; 42 char waterLine[128] = {0}; 43 string defaultValue = "default"; 44 GetParameter(key_.c_str(), defaultValue.c_str(), waterLine, waterLineLength); 45 { 46 std::lock_guard<std::mutex> autoLock(queryCacheLock_); 47 if (CanUseCache(querySaId, waterLine, defaultValue)) { 48 HILOGD("DynamicCache QueryResult Return Cache"); 49 return lastQuerySaProxy_; 50 } 51 } 52 HILOGD("DynamicCache QueryResult Recompute"); 53 sptr<IRemoteObject> res = Recompute(querySaId, code); 54 if (res == nullptr) { 55 return nullptr; 56 } 57 { 58 std::lock_guard<std::mutex> autoLock(queryCacheLock_); 59 localPara_[key_] = waterLine; 60 if (lastQuerySaProxy_ != nullptr) { 61 HILOGD("DynamicCache RemoveDeathRecipient"); 62 lastQuerySaProxy_->RemoveDeathRecipient(this); 63 } 64 lastQuerySaId_ = querySaId; 65 lastQuerySaProxy_ = res; 66 res->AddDeathRecipient(this); 67 } 68 return res; 69 } 70 CanUseCache(int32_t querySaId,char * waterLine,string defaultValue)71 bool CanUseCache(int32_t querySaId, char* waterLine, string defaultValue) 72 { 73 return localPara_.count(key_) != 0 && lastQuerySaId_ == querySaId && 74 defaultValue != string(waterLine) && string(waterLine) == localPara_[key_] && 75 lastQuerySaProxy_ != nullptr && !lastQuerySaProxy_->IsObjectDead(); 76 } 77 78 __attribute__((no_sanitize("cfi"))) ClearCache()79 void ClearCache() 80 { 81 std::lock_guard<std::mutex> autoLock(queryCacheLock_); 82 if (lastQuerySaProxy_ != nullptr) { 83 HILOGD("DynamicCache RemoveDeathRecipient"); 84 lastQuerySaProxy_->RemoveDeathRecipient(this); 85 } 86 lastQuerySaId_ = -1; 87 lastQuerySaProxy_ = nullptr; 88 } 89 InvalidateCache()90 bool InvalidateCache() 91 { 92 HILOGD("DynamicCache InvalidateCache Begin"); 93 string tickCount = to_string(GetTickCount()); 94 int32_t ret = SetParameter(key_.c_str(), tickCount.c_str()); 95 if (ret != EC_SUCCESS) { 96 HILOGE("DynamicCache InvalidateCache SetParameter error:%{public}d!", ret); 97 return false; 98 } 99 HILOGD("DynamicCache InvalidateCache End"); 100 return true; 101 } 102 SetKey(const string & key)103 bool SetKey(const string& key) 104 { 105 int32_t maxLength = 256; 106 if (key.size() == 0 || (int32_t)key.size() > maxLength) { 107 HILOGE("DynamicCache SetKey size error:%{public}zu!", key.size()); 108 return false; 109 } 110 key_ = key; 111 return true; 112 } 113 Recompute(int32_t querySaId,int32_t code)114 virtual sptr<IRemoteObject> Recompute(int32_t querySaId, int32_t code) 115 { 116 std::lock_guard<std::mutex> autoLock(queryCacheLock_); 117 if (lastQuerySaId_ != querySaId) { 118 return nullptr; 119 } 120 return lastQuerySaProxy_; 121 } 122 private: 123 std::mutex queryCacheLock_; 124 map<string, string> localPara_; 125 string key_; 126 int32_t lastQuerySaId_; 127 sptr<IRemoteObject> lastQuerySaProxy_; 128 }; 129 } 130 #endif /* DYNAMIC_CACHE_H */