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