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#include "watcher_manager_kits.h" 16 17#include "if_system_ability_manager.h" 18#include "init_param.h" 19#include "iservice_registry.h" 20#include "iwatcher.h" 21#include "iwatcher_manager.h" 22#include "system_ability_definition.h" 23#include "watcher_utils.h" 24#include "parameter.h" 25#include "init_param.h" 26 27namespace OHOS { 28namespace init_param { 29WatcherManagerKits &WatcherManagerKits::GetInstance(void) 30{ 31 return DelayedRefSingleton<WatcherManagerKits>::GetInstance(); 32} 33 34WatcherManagerKits::WatcherManagerKits(void) {} 35 36WatcherManagerKits::~WatcherManagerKits(void) {} 37 38void WatcherManagerKits::ResetService(const wptr<IRemoteObject> &remote) 39{ 40 WATCHER_LOGI("Remote is dead, reset service instance"); 41 std::lock_guard<std::mutex> lock(lock_); 42 if (watcherManager_ != nullptr) { 43 sptr<IRemoteObject> object = watcherManager_->AsObject(); 44 if ((object != nullptr) && (remote == object)) { 45 object->RemoveDeathRecipient(deathRecipient_); 46 watcherManager_ = nullptr; 47 remoteWatcherId_ = 0; 48 remoteWatcher_ = nullptr; 49 if (threadForReWatch_ != nullptr) { 50 WATCHER_LOGI("Thead exist, delete thread"); 51 stop_ = true; 52 threadForReWatch_->join(); 53 delete threadForReWatch_; 54 } 55 stop_ = false; 56 threadForReWatch_ = new (std::nothrow)std::thread([this] {this->ReAddWatcher();}); 57 WATCHER_CHECK(threadForReWatch_ != nullptr, return, "Failed to create thread"); 58 } 59 } 60} 61 62sptr<IWatcherManager> WatcherManagerKits::GetService(void) 63{ 64 std::lock_guard<std::mutex> lock(lock_); 65 if (watcherManager_ != nullptr) { 66 return watcherManager_; 67 } 68 69 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 70 WATCHER_CHECK(samgr != nullptr, return nullptr, "Get samgr failed"); 71 sptr<IRemoteObject> object = samgr->GetSystemAbility(PARAM_WATCHER_DISTRIBUTED_SERVICE_ID); 72 WATCHER_CHECK(object != nullptr, return nullptr, "Get watcher manager object from samgr failed"); 73 if (deathRecipient_ == nullptr) { 74 deathRecipient_ = new DeathRecipient(); 75 } 76 77 if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) { 78 WATCHER_LOGE("Failed to add death recipient"); 79 } 80 watcherManager_ = iface_cast<IWatcherManager>(object); 81 return watcherManager_; 82} 83 84void WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote) 85{ 86 DelayedRefSingleton<WatcherManagerKits>::GetInstance().ResetService(remote); 87} 88 89void WatcherManagerKits::ReAddWatcher(void) 90{ 91 WATCHER_LOGV("ReAddWatcher"); 92 int count = 0; 93 const int maxRetryCount = 100; 94 const int sleepTime = 100; 95 auto watcherManager = GetService(); 96 while (watcherManager == nullptr && count < maxRetryCount) { 97 if (stop_) { 98 return; 99 } 100 watcherManager = GetService(); 101 usleep(sleepTime); 102 count++; 103 } 104 WATCHER_LOGV("ReAddWatcher count %d ", count); 105 WATCHER_CHECK(watcherManager != nullptr, return, "Failed to get watcher manager"); 106 // add or get remote agent 107 uint32_t remoteWatcherId = GetRemoteWatcher(); 108 WATCHER_CHECK(remoteWatcherId > 0, return, "Failed to get remote agent"); 109 std::lock_guard<std::mutex> lock(mutex_); 110 for (auto iter = watchers_.begin(); iter != watchers_.end(); iter++) { 111 WATCHER_LOGI("Add old watcher keyPrefix %s ", iter->first.c_str()); 112 int ret = watcherManager->AddWatcher(iter->first, remoteWatcherId); 113 WATCHER_CHECK(ret == 0, continue, "Failed to add watcher for %s", iter->first.c_str()); 114 } 115} 116 117WatcherManagerKits::ParamWatcher *WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix) 118{ 119 std::lock_guard<std::mutex> lock(mutex_); 120 auto iter = watchers_.find(keyPrefix); 121 if (iter != watchers_.end()) { 122 return iter->second.get(); 123 } 124 return nullptr; 125} 126 127uint32_t WatcherManagerKits::GetRemoteWatcher(void) 128{ 129 std::lock_guard<std::mutex> lock(mutex_); 130 if (remoteWatcher_ != nullptr) { 131 return remoteWatcherId_; 132 } 133 auto watcherManager = GetService(); 134 WATCHER_CHECK(watcherManager != nullptr, return 0, "Failed to get watcher manager"); 135 remoteWatcher_ = new RemoteWatcher(this); 136 WATCHER_CHECK(remoteWatcher_ != nullptr, return 0, "Failed to create watcher"); 137 remoteWatcherId_ = watcherManager->AddRemoteWatcher(getpid(), remoteWatcher_); 138 WATCHER_CHECK(remoteWatcherId_ != 0, return 0, "Failed to add watcher"); 139 return remoteWatcherId_; 140} 141 142int32_t WatcherManagerKits::AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context) 143{ 144 auto watcherManager = GetService(); 145 WATCHER_CHECK(watcherManager != nullptr, return PARAM_WATCHER_GET_SERVICE_FAILED, "Failed to get watcher manager"); 146 147 // add or get remote agent 148 uint32_t remoteWatcherId = GetRemoteWatcher(); 149 WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent"); 150 ParamWatcherKitPtr watcher = nullptr; 151 { 152 std::lock_guard<std::mutex> lock(mutex_); 153 // must check 154 WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent"); 155 if (watchers_.find(keyPrefix) == watchers_.end()) { 156 watcher = std::make_shared<ParamWatcher>(keyPrefix); 157 WATCHER_CHECK(watcher != nullptr, return -1, "Failed to create watcher for %s", keyPrefix.c_str()); 158 int ret = watcher->AddParameterListener(callback, context); 159 WATCHER_CHECK(ret == 0, return ret, "Failed to add callback for %s ", keyPrefix.c_str()); 160 ret = watcherManager->AddWatcher(keyPrefix, remoteWatcherId); 161 WATCHER_CHECK(ret == 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str()); 162 watchers_[keyPrefix] = watcher; 163 } else { 164 watcher = watchers_[keyPrefix]; 165 int ret = watcher->AddParameterListener(callback, context); 166 WATCHER_CHECK(ret == 0, return ret, "Failed to add callback for %s ", keyPrefix.c_str()); 167 ret = watcherManager->RefreshWatcher(keyPrefix, remoteWatcherId); 168 WATCHER_CHECK(ret == 0, return -1, 169 "Failed to refresh watcher for %s %d", keyPrefix.c_str(), remoteWatcherId); 170 } 171 } 172 WATCHER_LOGI("Add watcher keyPrefix %s remoteWatcherId %u success", keyPrefix.c_str(), remoteWatcherId); 173 return 0; 174} 175 176int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context) 177{ 178 auto watcherManager = GetService(); 179 WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager"); 180 181 WatcherManagerKits::ParamWatcher *watcher = GetParamWatcher(keyPrefix); 182 WATCHER_CHECK(watcher != nullptr, return -1, "Failed to get watcher"); 183 184 int count = watcher->DelParameterListener(callback, context); 185 WATCHER_LOGI("DelWatcher keyPrefix_ %s count %d", keyPrefix.c_str(), count); 186 if (count != 0) { 187 return 0; 188 } 189 // delete watcher 190 int ret = watcherManager->DelWatcher(keyPrefix, remoteWatcherId_); 191 WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str()); 192 { 193 std::lock_guard<std::mutex> lock(mutex_); 194 auto it = watchers_.find(keyPrefix); // delete watcher 195 if (it != watchers_.end()) { 196 watchers_.erase(it); 197 } 198 if (watchers_.empty()) { // no watcher, so delete remote agent 199 watcherManager->DelRemoteWatcher(remoteWatcherId_); 200 remoteWatcherId_ = 0; 201 remoteWatcher_ = nullptr; 202 } 203 } 204 return 0; 205} 206 207WatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::GetParameterListener(uint32_t *idx) 208{ 209 uint32_t index = *idx; 210 if (parameterChangeListeners.empty()) { 211 return nullptr; 212 } 213 while (index < listenerId_) { 214 auto it = parameterChangeListeners.find(index); 215 if (it != parameterChangeListeners.end()) { 216 *idx = index; 217 return parameterChangeListeners[index].get(); 218 } 219 index++; 220 } 221 return nullptr; 222} 223 224void WatcherManagerKits::ParamWatcher::RemoveParameterListener(uint32_t idx) 225{ 226 auto it = parameterChangeListeners.find(idx); 227 if (it != parameterChangeListeners.end()) { 228 parameterChangeListeners.erase(it); 229 } 230} 231 232int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr callback, void *context) 233{ 234 std::lock_guard<std::mutex> lock(mutex_); 235 WATCHER_CHECK(callback != nullptr, return -1, "Invalid callback "); 236 WATCHER_LOGV("AddParameterListener %s listenerId_ %d", keyPrefix_.c_str(), listenerId_); 237 for (auto it = parameterChangeListeners.begin(); it != parameterChangeListeners.end(); it++) { 238 if (it->second == nullptr) { 239 continue; 240 } 241 if (it->second->IsEqual(callback, context)) { 242 return PARAM_WATCHER_CALLBACK_EXIST; 243 } 244 } 245 std::shared_ptr<ParameterChangeListener> changeNode = 246 std::make_shared<ParameterChangeListener>(callback, context); 247 WATCHER_CHECK(changeNode != nullptr, return -1, "Failed to create listener"); 248 parameterChangeListeners[listenerId_] = changeNode; 249 listenerId_++; 250 return 0; 251} 252 253int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr callback, void *context) 254{ 255 std::lock_guard<std::mutex> lock(mutex_); 256 if (callback == nullptr) { 257 parameterChangeListeners.clear(); 258 return 0; 259 } 260 uint32_t index = 0; 261 ParameterChangeListener *listener = GetParameterListener(&index); 262 while (listener != nullptr) { 263 if (listener->IsEqual(callback, context)) { 264 WATCHER_LOGV("DelParameterListener listenerId_ %d", index); 265 RemoveParameterListener(index); 266 break; 267 } 268 index++; 269 listener = GetParameterListener(&index); 270 } 271 return static_cast<int>(parameterChangeListeners.size()); 272} 273 274void WatcherManagerKits::RemoteWatcher::OnParameterChange( 275 const std::string &prefix, const std::string &name, const std::string &value) 276{ 277 Watcher::OnParameterChange(prefix, name, value); 278 // get param watcher 279 WatcherManagerKits::ParamWatcher *watcher = watcherManager_->GetParamWatcher(prefix); 280 WATCHER_CHECK(watcher != nullptr, return, "Failed to get watcher '%s'", prefix.c_str()); 281 if (watcher != nullptr) { 282 watcher->OnParameterChange(name, value); 283 } 284} 285 286void WatcherManagerKits::ParamWatcher::OnParameterChange(const std::string &name, const std::string &value) 287{ 288 std::lock_guard<std::mutex> lock(mutex_); 289 WATCHER_LOGV("OnParameterChange name %s value %s", name.c_str(), value.c_str()); 290 uint32_t index = 0; 291 ParameterChangeListener *listener = GetParameterListener(&index); 292 while (listener != nullptr) { 293 if (!listener->CheckValueChange(name, value)) { 294 listener->OnParameterChange(name, value); 295 } 296 index++; 297 listener = GetParameterListener(&index); 298 } 299} 300 301void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::string &name, const std::string &value) 302{ 303 if (callback_ != nullptr) { 304 callback_(name.c_str(), value.c_str(), context_); 305 } 306} 307} // namespace init_param 308} // namespace OHOS 309 310static int PreHandleWatchParam(std::string &prefix) 311{ 312 // clear space in head or tail 313 prefix.erase(0, prefix.find_first_not_of(" ")); 314 prefix.erase(prefix.find_last_not_of(" ") + 1); 315 WATCHER_CHECK(!prefix.empty(), return PARAM_CODE_INVALID_PARAM, "Invalid prefix"); 316 int ret = 0; 317 if (prefix.rfind(".*") == prefix.length() - 2) { // 2 last index 318 ret = WatchParamCheck(prefix.substr(0, prefix.length() - 2).c_str()); // 2 last index 319 } else if (prefix.rfind("*") == prefix.length() - 1) { 320 ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str()); 321 } else if (prefix.rfind(".") == prefix.length() - 1) { 322 ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str()); 323 } else { 324 ret = WatchParamCheck(prefix.c_str()); 325 } 326 return ret; 327} 328 329int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context) 330{ 331 WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix"); 332 std::string key(keyPrefix); 333 int ret = PreHandleWatchParam(key); 334 if (ret != 0) { 335 return ret; 336 } 337 OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance(); 338 if (callback != nullptr) { 339 ret = instance.AddWatcher(keyPrefix, callback, context); 340 } else { 341 ret = instance.DelWatcher(keyPrefix, nullptr, nullptr); 342 } 343 344 if (ret != 0) { 345 WATCHER_LOGE("SystemWatchParameter is failed! keyPrefix is:%s, errNum is:%d", keyPrefix, ret); 346 } 347 return ret; 348} 349 350int RemoveParameterWatcher(const char *keyPrefix, ParameterChgPtr callback, void *context) 351{ 352 WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix"); 353 std::string key(keyPrefix); 354 int ret = PreHandleWatchParam(key); 355 if (ret != 0) { 356 return ret; 357 } 358 OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance(); 359 ret = instance.DelWatcher(keyPrefix, (ParameterChangePtr)callback, context); 360 if (ret != 0) { 361 WATCHER_LOGE("RemoveParameterWatcher is failed! keyPrefix is:%s, errNum is:%d", keyPrefix, ret); 362 } 363 return ret; 364}