• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&WatcherManagerKits::ReAddWatcher, this);
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     std::lock_guard<std::mutex> lock(mutex_);
210     uint32_t index = *idx;
211     if (parameterChangeListeners.empty()) {
212         return nullptr;
213     }
214     while (index < listenerId_) {
215         auto it = parameterChangeListeners.find(index);
216         if (it != parameterChangeListeners.end()) {
217             *idx = index;
218             return parameterChangeListeners[index].get();
219         }
220         index++;
221     }
222     return nullptr;
223 }
224 
RemoveParameterListener(uint32_t idx)225 void WatcherManagerKits::ParamWatcher::RemoveParameterListener(uint32_t idx)
226 {
227     std::lock_guard<std::mutex> lock(mutex_);
228     auto it = parameterChangeListeners.find(idx);
229     if (it != parameterChangeListeners.end()) {
230         parameterChangeListeners.erase(it);
231     }
232 }
233 
AddParameterListener(ParameterChangePtr callback,void * context)234 int WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr callback, void *context)
235 {
236     WATCHER_CHECK(callback != nullptr, return -1, "Invalid callback ");
237     WATCHER_LOGV("AddParameterListener %s listenerId_ %d", keyPrefix_.c_str(), listenerId_);
238     for (auto it = parameterChangeListeners.begin(); it != parameterChangeListeners.end(); it++) {
239         if (it->second == nullptr) {
240             continue;
241         }
242         if (it->second->IsEqual(callback, context)) {
243             return PARAM_WATCHER_CALLBACK_EXIST;
244         }
245     }
246     std::shared_ptr<ParameterChangeListener> changeNode =
247         std::make_shared<ParameterChangeListener>(callback, context);
248     WATCHER_CHECK(changeNode != nullptr, return -1, "Failed to create listener");
249     parameterChangeListeners[listenerId_] = changeNode;
250     listenerId_++;
251     return 0;
252 }
253 
DelParameterListener(ParameterChangePtr callback,void * context)254 int WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr callback, void *context)
255 {
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     WATCHER_LOGV("OnParameterChange name %s value %s", name.c_str(), value.c_str());
289     uint32_t index = 0;
290     ParameterChangeListener *listener = GetParameterListener(&index);
291     while (listener != nullptr) {
292         if (!listener->CheckValueChange(name, value)) {
293             listener->OnParameterChange(name, value);
294         }
295         index++;
296         listener = GetParameterListener(&index);
297     }
298 }
299 
OnParameterChange(const std::string & name,const std::string & value)300 void WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::string &name, const std::string &value)
301 {
302     if (callback_ != nullptr) {
303         callback_(name.c_str(), value.c_str(), context_);
304     }
305 }
306 } // namespace init_param
307 } // namespace OHOS
308 
PreHandleWatchParam(std::string & prefix)309 static int PreHandleWatchParam(std::string &prefix)
310 {
311     // clear space in head or tail
312     prefix.erase(0, prefix.find_first_not_of(" "));
313     prefix.erase(prefix.find_last_not_of(" ") + 1);
314     WATCHER_CHECK(!prefix.empty(), return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
315     int ret = 0;
316     if (prefix.rfind(".*") == prefix.length() - 2) { // 2 last index
317         ret = WatchParamCheck(prefix.substr(0, prefix.length() - 2).c_str()); // 2 last index
318     } else if (prefix.rfind("*") == prefix.length() - 1) {
319         ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
320     } else if (prefix.rfind(".") == prefix.length() - 1) {
321         ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
322     } else {
323         ret = WatchParamCheck(prefix.c_str());
324     }
325     return ret;
326 }
327 
SystemWatchParameter(const char * keyPrefix,ParameterChangePtr callback,void * context)328 int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context)
329 {
330     WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
331     std::string key(keyPrefix);
332     int ret = PreHandleWatchParam(key);
333     if (ret != 0) {
334         return ret;
335     }
336     OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
337     if (callback != nullptr) {
338         ret = instance.AddWatcher(keyPrefix, callback, context);
339     } else {
340         ret = instance.DelWatcher(keyPrefix, nullptr, nullptr);
341     }
342 
343     if (ret != 0) {
344         WATCHER_LOGE("SystemWatchParameter is failed! keyPrefix is:%s, errNum is:%d", keyPrefix, ret);
345     }
346     return ret;
347 }
348 
RemoveParameterWatcher(const char * keyPrefix,ParameterChgPtr callback,void * context)349 int RemoveParameterWatcher(const char *keyPrefix, ParameterChgPtr callback, void *context)
350 {
351     WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
352     std::string key(keyPrefix);
353     int ret = PreHandleWatchParam(key);
354     if (ret != 0) {
355         return ret;
356     }
357     OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
358     ret = instance.DelWatcher(keyPrefix, (ParameterChangePtr)callback, context);
359     if (ret != 0) {
360         WATCHER_LOGE("RemoveParameterWatcher is failed! keyPrefix is:%s, errNum is:%d", keyPrefix, ret);
361     }
362     return ret;
363 }