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