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
27 namespace OHOS {
28 namespace init_param {
GetInstance(void)29 WatcherManagerKits &WatcherManagerKits::GetInstance(void)
30 {
31 return DelayedRefSingleton<WatcherManagerKits>::GetInstance();
32 }
33
WatcherManagerKits(void)34 WatcherManagerKits::WatcherManagerKits(void) {}
35
~WatcherManagerKits(void)36 WatcherManagerKits::~WatcherManagerKits(void) {}
37
ResetService(const wptr<IRemoteObject> & remote)38 void 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
GetService(void)62 sptr<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
OnRemoteDied(const wptr<IRemoteObject> & remote)84 void WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
85 {
86 DelayedRefSingleton<WatcherManagerKits>::GetInstance().ResetService(remote);
87 }
88
ReAddWatcher(void)89 void 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
GetParamWatcher(const std::string & keyPrefix)117 WatcherManagerKits::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
GetRemoteWatcher(void)127 uint32_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
AddWatcher(const std::string & keyPrefix,ParameterChangePtr callback,void * context)142 int32_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
DelWatcher(const std::string & keyPrefix,ParameterChangePtr callback,void * context)176 int32_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
GetParameterListener(uint32_t * idx)207 WatcherManagerKits::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
RemoveParameterListener(uint32_t idx)224 void 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
AddParameterListener(ParameterChangePtr callback,void * context)232 int 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
DelParameterListener(ParameterChangePtr callback,void * context)253 int 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
OnParameterChange(const std::string & prefix,const std::string & name,const std::string & value)274 void 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
OnParameterChange(const std::string & name,const std::string & value)286 void 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
OnParameterChange(const std::string & name,const std::string & value)301 void 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
PreHandleWatchParam(std::string & prefix)310 static 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
SystemWatchParameter(const char * keyPrefix,ParameterChangePtr callback,void * context)329 int 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
RemoveParameterWatcher(const char * keyPrefix,ParameterChgPtr callback,void * context)350 int 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 }