• 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.h"
16 #include <fcntl.h>
17 #include <sys/socket.h>
18 #include <sys/stat.h>
19 #include <sys/time.h>
20 #include <sys/types.h>
21 #include <thread>
22 
23 #include "init_param.h"
24 #include "param_init.h"
25 #include "parameter.h"
26 #include "system_ability_definition.h"
27 #include "string_ex.h"
28 #include "watcher_utils.h"
29 
30 namespace OHOS {
31 namespace init_param {
32 REGISTER_SYSTEM_ABILITY_BY_ID(WatcherManager, PARAM_WATCHER_DISTRIBUTED_SERVICE_ID, true)
33 
34 const static int32_t INVALID_SOCKET = -1;
35 const static int32_t ERR_FAIL = -1;
36 const static int32_t PUBLIC_APP_BEGIN_UID = 10000;
~WatcherManager()37 WatcherManager::~WatcherManager()
38 {
39     Clear();
40 }
41 
AddRemoteWatcher(uint32_t id,uint32_t & watcherId,const sptr<IWatcher> & watcher)42 int32_t WatcherManager::AddRemoteWatcher(uint32_t id, uint32_t &watcherId, const sptr<IWatcher> &watcher)
43 {
44 #ifndef STARTUP_INIT_TEST
45     if (id == static_cast<uint32_t>(getpid())) {
46         WATCHER_LOGE("Failed to add remote watcher %u", id);
47         return ERR_FAIL;
48     }
49 #endif
50     WATCHER_CHECK(watcher != nullptr, return ERR_FAIL, "Invalid remote watcher");
51     WATCHER_CHECK(deathRecipient_ != nullptr, return ERR_FAIL, "Invalid deathRecipient_");
52     sptr<IRemoteObject> object = watcher->AsObject();
53     if ((object != nullptr) && (object->IsProxyObject())) {
54         WATCHER_CHECK(object->AddDeathRecipient(deathRecipient_),
55             return ERR_FAIL, "Failed to add death recipient %u", id);
56     }
57     uint32_t remoteWatcherId = 0;
58     {
59         std::lock_guard<std::mutex> lock(watcherMutex_);
60         // check watcher id
61         int ret = GetRemoteWatcherId(remoteWatcherId);
62         WATCHER_CHECK(ret == 0, return ERR_FAIL, "Failed to get watcher id for %u", id);
63         // create remote watcher
64         RemoteWatcher *remoteWatcher = new RemoteWatcher(remoteWatcherId, watcher);
65         WATCHER_CHECK(remoteWatcher != nullptr, return ERR_FAIL, "Failed to create watcher for %u", id);
66         remoteWatcher->SetAgentId(GetCallingPid());
67         AddRemoteWatcher(remoteWatcher);
68     }
69     WATCHER_LOGI("Add remote watcher remoteWatcherId %u %u success", remoteWatcherId, id);
70     watcherId = remoteWatcherId;
71     return 0;
72 }
73 
DelRemoteWatcher(uint32_t remoteWatcherId)74 int32_t WatcherManager::DelRemoteWatcher(uint32_t remoteWatcherId)
75 {
76     sptr<IWatcher> watcher = {0};
77     {
78         std::lock_guard<std::mutex> lock(watcherMutex_);
79         RemoteWatcher *remoteWatcher = GetRemoteWatcher(remoteWatcherId);
80         WATCHER_CHECK(remoteWatcher != nullptr, return 0, "Can not find watcher %u", remoteWatcherId);
81         WATCHER_CHECK(remoteWatcher->CheckAgent(GetCallingPid()), return 0,
82             "Can not find watcher %u calling %u", remoteWatcher->GetAgentId(), static_cast<uint32_t>(GetCallingPid()));
83         WATCHER_LOGI("Del remote watcher remoteWatcherId %u", remoteWatcherId);
84         watcher = remoteWatcher->GetWatcher();
85         DelRemoteWatcher(remoteWatcher);
86     }
87     sptr<IRemoteObject> object = watcher->AsObject();
88     if (object != nullptr) {
89         object->RemoveDeathRecipient(deathRecipient_);
90     }
91     return 0;
92 }
93 
CheckAppWatchPermission(const std::string & keyPrefix)94 int32_t WatcherManager::CheckAppWatchPermission(const std::string &keyPrefix)
95 {
96     if (keyPrefix.find("*") != std::string::npos) {
97         WATCHER_LOGE("param key has *, not need deal");
98         return false;
99     }
100     static const std::vector<std::string> whitelist = {
101         "persist.ace.debug.statemgr.enabled",
102         "persist.ace.debug.boundary.enabled",
103         "persist.ace.trace.layout.enabled",
104         "persist.ace.trace.inputevent.enabled",
105         "persist.ace.performance.monitor.enabled",
106         "persist.sys.graphic.animationscale",
107         "persist.sys.arkui.animationscale",
108         "persist.hdc.jdwp",
109         "persist.location.switch_mode",
110         "persist.super_privacy.mode",
111         "persist.global.locale",
112         "const.security.developermode.state",
113         "debug.graphic.frame",
114         "debug.graphic.debug_layer",
115         "debug.graphic.overdraw",
116         "debug.graphic.colors_overdraw",
117         "accessibility.config.ready",
118         "sys.hiview.chr.fluchcache",
119         "web.render.dump",
120         "web.debug.trace"
121     };
122 
123     if (std::find(whitelist.begin(), whitelist.end(), keyPrefix) != whitelist.end()) {
124         return true;
125     }
126     return false;
127 }
128 
AddWatcher(const std::string & keyPrefix,uint32_t remoteWatcherId)129 int32_t WatcherManager::AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
130 {
131     std::lock_guard<std::mutex> lock(watcherMutex_);
132     // get remote watcher and group
133     WATCHER_CHECK((keyPrefix != "*") && (keyPrefix.size() < PARAM_NAME_LEN_MAX),
134         return -1, "Failed to verify keyPrefix.");
135 
136     // check calling uid, app not have watch permission
137     int uid = GetCallingUid();
138     if (uid >= PUBLIC_APP_BEGIN_UID && !CheckAppWatchPermission(keyPrefix)) {
139         WATCHER_LOGE("app not have permission watch param:%s uid:%d pid:%d", keyPrefix.c_str(), uid, GetCallingPid());
140         return -1;
141     }
142 
143     auto remoteWatcher = GetRemoteWatcher(remoteWatcherId);
144     WATCHER_CHECK(remoteWatcher != nullptr, return -1, "Can not find remote watcher %d", remoteWatcherId);
145     WATCHER_CHECK(remoteWatcher->CheckAgent(GetCallingPid()), return 0,
146         "Can not find watcher %u calling %u", remoteWatcher->GetAgentId(), static_cast<uint32_t>(GetCallingPid()));
147     auto group = AddWatcherGroup(keyPrefix);
148     WATCHER_CHECK(group != nullptr, return -1, "Failed to create group for %s", keyPrefix.c_str());
149     {
150         // add watcher to agent and group
151         bool newGroup = group->Empty();
152         AddParamWatcher(group, remoteWatcher);
153         if (newGroup) {
154             StartLoop();
155             SendMessage(group, MSG_ADD_WATCHER);
156         } else if (groupRealMap_.find(keyPrefix) == groupRealMap_.end()) {
157             SendMessage(group, MSG_ADD_WATCHER);
158             WATCHER_LOGI("Add watcher %s groupId %u again", keyPrefix.c_str(), group->GetGroupId());
159         }
160     }
161     SendLocalChange(keyPrefix, remoteWatcherId);
162     WATCHER_LOGI("Add watcher %s remoteWatcherId: %u groupId %u success",
163         keyPrefix.c_str(), remoteWatcherId, group->GetGroupId());
164     return 0;
165 }
166 
DelWatcher(const std::string & keyPrefix,uint32_t remoteWatcherId)167 int32_t WatcherManager::DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
168 {
169     std::lock_guard<std::mutex> lock(watcherMutex_);
170     WATCHER_CHECK(keyPrefix.size() < PARAM_NAME_LEN_MAX, return -1, "Failed to verify keyPrefix.");
171     auto group = GetWatcherGroup(keyPrefix);
172     WATCHER_CHECK(group != nullptr, return 0, "Can not find group %s", keyPrefix.c_str());
173     auto remoteWatcher = GetRemoteWatcher(remoteWatcherId);
174     WATCHER_CHECK(remoteWatcher != nullptr, return 0, "Can not find watcher %s %d", keyPrefix.c_str(), remoteWatcherId);
175     WATCHER_CHECK(remoteWatcher->CheckAgent(GetCallingPid()), return -1,
176         "Can not find watcher %u calling %u", remoteWatcher->GetAgentId(), static_cast<uint32_t>(GetCallingPid()));
177     WATCHER_LOGI("Delete watcher prefix %s remoteWatcherId %u", keyPrefix.c_str(), remoteWatcherId);
178     {
179         // remove watcher from agent and group
180         DelParamWatcher(group, remoteWatcher);
181         if (group->Empty()) { // no watcher, so delete it
182             SendMessage(group, MSG_DEL_WATCHER);
183             DelWatcherGroup(group);
184         }
185     }
186     return 0;
187 }
188 
RefreshWatcher(const std::string & keyPrefix,uint32_t remoteWatcherId)189 int32_t WatcherManager::RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId)
190 {
191     std::lock_guard<std::mutex> lock(watcherMutex_);
192     WATCHER_CHECK(keyPrefix.size() < PARAM_NAME_LEN_MAX, return -1, "Failed to verify keyPrefix.");
193     WATCHER_LOGV("Refresh watcher %s remoteWatcherId: %u", keyPrefix.c_str(), remoteWatcherId);
194     auto remoteWatcher = GetRemoteWatcher(remoteWatcherId);
195     WATCHER_CHECK(remoteWatcher != nullptr, return 0, "Can not find watcher %s %d", keyPrefix.c_str(), remoteWatcherId);
196     WATCHER_CHECK(remoteWatcher->CheckAgent(GetCallingPid()), return 0,
197         "Can not find watcher %u calling %d", remoteWatcher->GetAgentId(), static_cast<uint32_t>(GetCallingPid()));
198 
199     auto group = GetWatcherGroup(keyPrefix);
200     WATCHER_CHECK(group != nullptr, return 0, "Can not find group %s", keyPrefix.c_str());
201     SendLocalChange(keyPrefix, remoteWatcherId);
202     return 0;
203 }
204 
SendMessage(WatcherGroupPtr group,int type)205 int WatcherManager::SendMessage(WatcherGroupPtr group, int type)
206 {
207     ParamMessage *request = nullptr;
208     std::string key(group->GetKeyPrefix());
209     if (key.rfind("*") == key.length() - 1) {
210         key = key.substr(0, key.length() - 1);
211     }
212     request = (ParamMessage *)CreateParamMessage(type, key.c_str(), sizeof(ParamMessage));
213     WATCHER_CHECK(request != NULL, return PARAM_CODE_ERROR, "Failed to malloc for watch");
214     request->id.watcherId = group->GetGroupId();
215     request->msgSize = sizeof(ParamMessage);
216     int ret = PARAM_CODE_FAIL_CONNECT;
217     int fd = GetServerFd(false);
218     if (fd < 0) {
219         WATCHER_LOGE("ParamWatcher get server fd failed!");
220         free(request);
221         return PARAM_CODE_FAIL_CONNECT;
222     }
223 
224     ssize_t sendLen = send(serverFd_, (char *)request, request->msgSize, 0);
225     ret = (sendLen > 0) ? 0 : PARAM_CODE_IPC_ERROR;
226     free(request);
227     WATCHER_CHECK(ret == 0, return ret, "SendMessage key: %s %d fail!", group->GetKeyPrefix().c_str(), type);
228     return 0;
229 }
230 
ProcessParameterChange(WatcherManager * manager,const std::string & name,const std::string & value)231 void WatcherGroup::ProcessParameterChange(
232     WatcherManager *manager, const std::string &name, const std::string &value)
233 {
234     WATCHER_LOGV("ProcessParameterChange key '%s' '%s'", GetKeyPrefix().c_str(), name.c_str());
235     // walk watcher
236     TraversalNode([this, manager, name, value](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
237         auto remoteWatcher = manager->GetRemoteWatcher(node->GetNodeId());
238         if (remoteWatcher == nullptr) {
239             return;
240         }
241         WATCHER_LOGI("ProcessParameterChange key '%s' pid: %d", GetKeyPrefix().c_str(), remoteWatcher->GetAgentId());
242         remoteWatcher->ProcessParameterChange(GetKeyPrefix(), name, value);
243     });
244 }
245 
FilterParam(const char * name,const std::string & keyPrefix)246 static int FilterParam(const char *name, const std::string &keyPrefix)
247 {
248     if (keyPrefix.rfind("*") == keyPrefix.length() - 1) {
249         return strncmp(name, keyPrefix.c_str(), keyPrefix.length() - 1) == 0;
250     }
251     if (keyPrefix.rfind(".") == keyPrefix.length() - 1) {
252         return strncmp(name, keyPrefix.c_str(), keyPrefix.length() - 1) == 0;
253     }
254     return strcmp(name, keyPrefix.c_str()) == 0;
255 }
256 
AddRealWatcherGroup(const std::string & keyPrefix,int type)257 void WatcherManager::AddRealWatcherGroup(const std::string &keyPrefix, int type)
258 {
259     std::string key;
260     if (!keyPrefix.empty() && keyPrefix.back() == '.') {
261         key = keyPrefix + '*';
262     } else {
263         key = keyPrefix;
264     }
265     if (groupMap_.find(key) == groupMap_.end() && type != MSG_DEL_WATCHER) {
266         return;
267     }
268 
269     if (type == MSG_ADD_WATCHER) {
270         groupRealMap_[key] = groupMap_[key]->GetGroupId();
271         WATCHER_LOGI("add key %s groupId %u success", key.c_str(), groupMap_[key]->GetGroupId());
272     } else if (type == MSG_DEL_WATCHER && groupRealMap_.find(key) != groupRealMap_.end()) {
273         groupRealMap_.erase(key);
274         WATCHER_LOGI("del key %s", key.c_str());
275     }
276 }
277 
ProcessWatcherMessage(const ParamMessage * msg)278 void WatcherManager::ProcessWatcherMessage(const ParamMessage *msg)
279 {
280     uint32_t offset = 0;
281     if (msg->type == MSG_ADD_WATCHER || msg->type == MSG_DEL_WATCHER) {
282         std::lock_guard<std::mutex> lock(watcherMutex_);
283         WATCHER_LOGV("ProcessWatcherMessage key %s, type %d", msg->key, msg->type);
284         AddRealWatcherGroup(msg->key, msg->type);
285         return;
286     }
287     if (msg->type != MSG_NOTIFY_PARAM) {
288         return;
289     }
290     ParamMsgContent *valueContent = GetNextContent(msg, &offset);
291     WATCHER_CHECK(valueContent != NULL, return, "Invalid msg ");
292     WATCHER_LOGV("Process watcher message name '%s' group id %u ", msg->key, msg->id.watcherId);
293     {
294         std::lock_guard<std::mutex> lock(watcherMutex_);
295         WatcherGroupPtr group = GetWatcherGroup(msg->id.watcherId);
296         WATCHER_CHECK(group != NULL, return, "Can not find group for %u %s", msg->id.watcherId, msg->key);
297         if (!FilterParam(msg->key, group->GetKeyPrefix())) {
298             WATCHER_LOGV("Invalid message name '%s' group '%s' ", msg->key, group->GetKeyPrefix().c_str());
299             return;
300         }
301         group->ProcessParameterChange(this, msg->key, valueContent->content);
302     }
303 }
304 
SendLocalChange(const std::string & keyPrefix,uint32_t remoteWatcherId)305 void WatcherManager::SendLocalChange(const std::string &keyPrefix, uint32_t remoteWatcherId)
306 {
307     struct Context {
308         char *buffer;
309         uint32_t remoteWatcherId;
310         std::string keyPrefix;
311         WatcherManager *watcherManagerPtr;
312     };
313     WATCHER_LOGI("SendLocalChange start keyPrefix '%s' remoteWatcherId %d", keyPrefix.c_str(), remoteWatcherId);
314     std::vector<char> buffer(PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX);
315     struct Context context = {buffer.data(), remoteWatcherId, keyPrefix, this};
316     // walk watcher
317     SystemTraversalParameter("", [](ParamHandle handle, void *cookie) {
318             if (cookie == nullptr) {
319                 return;
320             }
321             struct Context *context = (struct Context *)(cookie);
322             SystemGetParameterName(handle, context->buffer, PARAM_NAME_LEN_MAX);
323             if (!FilterParam(context->buffer, context->keyPrefix)) {
324                 return;
325             }
326             WATCHER_LOGV("SendLocalChange name '%s' prefix '%s'", context->buffer, context->keyPrefix.c_str());
327             uint32_t size = PARAM_CONST_VALUE_LEN_MAX;
328             SystemGetParameterValue(handle, context->buffer + PARAM_NAME_LEN_MAX, &size);
329             auto remoteWatcher = context->watcherManagerPtr->GetRemoteWatcher(context->remoteWatcherId);
330             if (remoteWatcher == nullptr) {
331                 return;
332             }
333             remoteWatcher->ProcessParameterChange(
334                 context->keyPrefix, context->buffer, context->buffer + PARAM_NAME_LEN_MAX);
335         }, reinterpret_cast<void *>(&context));
336 }
337 
RunLoop()338 void WatcherManager::RunLoop()
339 {
340     const int32_t RECV_BUFFER_MAX = 5 * 1024;
341     std::vector<char> buffer(RECV_BUFFER_MAX, 0);
342     bool retry = false;
343     ssize_t recvLen = 0;
344     while (!stop_) {
345         int fd = GetServerFd(retry);
346         if (stop_) {
347             break;
348         }
349         if (fd >= 0) {
350             recvLen = recv(fd, buffer.data(), RECV_BUFFER_MAX, 0);
351         }
352         if (recvLen <= 0) {
353             if (errno == EAGAIN) { // timeout
354                 continue;
355             }
356             PARAM_LOGE("Failed to recv msg from server errno %d", errno);
357             retry = true;  // re connect
358             continue;
359         }
360         uint32_t curr = 0;
361         uint32_t dataLen = static_cast<uint32_t>(recvLen);
362         while (curr < dataLen) {
363             if (sizeof(ParamMessage) >= dataLen - curr) {
364                 break;
365             }
366             ParamMessage *msg = (ParamMessage *)(buffer.data() + curr);
367             if (msg->msgSize == 0 || (msg->msgSize > dataLen - curr)) {
368                 break;
369             }
370             ProcessWatcherMessage(msg);
371             curr += msg->msgSize;
372         }
373     }
374     if (serverFd_ >= 0) {
375         close(serverFd_);
376         serverFd_ = INVALID_SOCKET;
377     }
378     WATCHER_LOGV("Exit runLoop serverFd %d", serverFd_);
379 }
380 
StartLoop()381 void WatcherManager::StartLoop()
382 {
383     if (pRecvThread_ == nullptr) {
384         pRecvThread_ = new (std::nothrow)std::thread([this] {this->RunLoop();});
385         WATCHER_CHECK(pRecvThread_ != nullptr, return, "Failed to create thread");
386     }
387 }
388 
GetServerFd(bool retry)389 int WatcherManager::GetServerFd(bool retry)
390 {
391     const int32_t sleepTime = 200;
392     const int32_t maxRetry = 10;
393     std::lock_guard<std::mutex> lock(mutex_);
394     if (retry && serverFd_ != INVALID_SOCKET) {
395         close(serverFd_);
396         serverFd_ = INVALID_SOCKET;
397     }
398     if (serverFd_ != INVALID_SOCKET) {
399         return serverFd_;
400     }
401     int32_t retryCount = 0;
402     do {
403         serverFd_ = socket(PF_UNIX, SOCK_STREAM, 0);
404         int flags = fcntl(serverFd_, F_GETFL, 0);
405         (void)fcntl(serverFd_, F_SETFL, flags & ~O_NONBLOCK);
406         int ret = ConnectServer(serverFd_, CLIENT_PIPE_NAME);
407         if (ret == 0) {
408             break;
409         }
410         close(serverFd_);
411         serverFd_ = INVALID_SOCKET;
412         usleep(sleepTime);
413         retryCount++;
414         if (stop_) {
415             break;
416         }
417     } while (retryCount < maxRetry);
418     WATCHER_LOGV("GetServerFd serverFd_ %d retryCount %d ", serverFd_, retryCount);
419     return serverFd_;
420 }
421 
OnStart()422 void WatcherManager::OnStart()
423 {
424     int level = GetIntParameter(INIT_DEBUG_LEVEL, (int)INIT_ERROR);
425     SetInitLogLevel((InitLogLevel)level);
426     if (deathRecipient_ == nullptr) {
427         deathRecipient_ = new DeathRecipient(this);
428     }
429     WATCHER_LOGI("Watcher manager OnStart");
430     bool res = Publish(this);
431     if (!res) {
432         WATCHER_LOGE("WatcherManager Publish failed");
433     }
434     SystemSetParameter("bootevent.param_watcher.started", "true");
435     return;
436 }
437 
StopLoop()438 void WatcherManager::StopLoop()
439 {
440     WATCHER_LOGI("Watcher manager StopLoop serverFd_ %d", serverFd_);
441     stop_ = true;
442     if (serverFd_ >= 0) {
443         shutdown(serverFd_, SHUT_RDWR);
444         close(serverFd_);
445         serverFd_ = INVALID_SOCKET;
446     }
447     if (pRecvThread_ != nullptr) {
448         pRecvThread_->join();
449         delete pRecvThread_;
450         pRecvThread_ = nullptr;
451     }
452 }
453 
OnStop()454 void WatcherManager::OnStop()
455 {
456     if (remoteWatchers_ != nullptr) {
457         std::lock_guard<std::mutex> lock(watcherMutex_);
458         remoteWatchers_->TraversalNodeSafe([this](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
459             RemoteWatcherPtr remoteWatcher = ConvertTo<RemoteWatcher>(node);
460             OnRemoteDied(remoteWatcher);
461         });
462     }
463     Clear();
464     StopLoop();
465 }
466 
OnRemoteDied(const wptr<IRemoteObject> & remote)467 void WatcherManager::OnRemoteDied(const wptr<IRemoteObject> &remote)
468 {
469     std::lock_guard<std::mutex> lock(watcherMutex_);
470     WATCHER_CHECK(remote != nullptr, return, "Invalid remote obj");
471     auto remoteWatcher = GetRemoteWatcher(remote);
472     WATCHER_CHECK(remoteWatcher != nullptr, return, "Failed to get remote watcher info ");
473     {
474         OnRemoteDied(remoteWatcher);
475     }
476 }
477 
OnRemoteDied(RemoteWatcherPtr remoteWatcher)478 void WatcherManager::OnRemoteDied(RemoteWatcherPtr remoteWatcher)
479 {
480     WATCHER_CHECK(remoteWatcher != nullptr, return, "Invalid remote obj");
481     WATCHER_LOGI("Agent died %u %u", remoteWatcher->GetRemoteWatcherId(), remoteWatcher->GetAgentId());
482     remoteWatcher->TraversalNodeSafe(
483         [this, remoteWatcher](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
484             auto group = GetWatcherGroup(node->GetNodeId());
485             if (group == nullptr) {
486                 return;
487             }
488             // delete node from group and remote
489             DelParamWatcher(group, remoteWatcher);
490             if (group->Empty()) { // no watcher, so delete it
491                 SendMessage(group, MSG_DEL_WATCHER);
492                 DelWatcherGroup(group);
493             }
494         });
495     DelRemoteWatcher(remoteWatcher);
496 }
497 
GetRemoteWatcher(const wptr<IRemoteObject> & remote)498 RemoteWatcherPtr WatcherManager::GetRemoteWatcher(const wptr<IRemoteObject> &remote)
499 {
500     WatcherNodePtr node = remoteWatchers_->GetNextNode(nullptr);
501     while (node != nullptr) {
502         RemoteWatcherPtr remoteWatcher = ConvertTo<RemoteWatcher>(node);
503         if (remoteWatcher == nullptr) {
504             continue;
505         }
506         if (remote == remoteWatcher->GetWatcher()->AsObject()) {
507             return remoteWatcher;
508         }
509         node = remoteWatchers_->GetNextNode(node);
510     }
511     return nullptr;
512 }
513 
GetRemoteWatcherId(uint32_t & remoteWatcherId)514 int WatcherManager::GetRemoteWatcherId(uint32_t &remoteWatcherId)
515 {
516     remoteWatcherId_++;
517     if (remoteWatcherId_ == 0) {
518         remoteWatcherId_++;
519     }
520     remoteWatcherId = remoteWatcherId_;
521     return 0;
522 }
523 
GetGroupId(uint32_t & groupId)524 int WatcherManager::GetGroupId(uint32_t &groupId)
525 {
526     groupId = groupId_;
527     do {
528         groupId_++;
529         if (watcherGroups_->GetNode(groupId_) == nullptr) {
530             break;
531         }
532         WATCHER_CHECK(groupId_ == groupId, return -1, "No enough groupId %u", groupId);
533     } while (1);
534     groupId = groupId_;
535     return 0;
536 }
537 
DumpAllGroup(int fd,ParamWatcherProcessor dumpHandle)538 void WatcherManager::DumpAllGroup(int fd, ParamWatcherProcessor dumpHandle)
539 {
540     // all output
541     uint32_t count = 0;
542     std::lock_guard<std::mutex> lock(watcherMutex_);
543     for (auto it = groupMap_.begin(); it != groupMap_.end(); ++it) {
544         auto group = it->second;
545         dprintf(fd, "Watch prefix   : %s \n", group->GetKeyPrefix().c_str());
546         dprintf(fd, "Watch group id : %u \n", group->GetGroupId());
547         dprintf(fd, "Watch count    : %u \n", group->GetNodeCount());
548         group->TraversalNode(dumpHandle);
549         count += group->GetNodeCount();
550         dprintf(fd, "\n");
551     }
552 
553     dprintf(fd, "Watch prefix count : %u [%zu  %zu  %zu]\n", watcherGroups_->GetNodeCount(),
554         sizeof(RemoteWatcher), sizeof(WatcherGroup), sizeof(WatcherNode));
555     dprintf(fd, "Watch agent  count : %u \n", remoteWatchers_->GetNodeCount());
556     dprintf(fd, "Watch count        : %u \n", count);
557 }
558 
Dump(int fd,const std::vector<std::u16string> & args)559 int WatcherManager::Dump(int fd, const std::vector<std::u16string>& args)
560 {
561     WATCHER_CHECK(fd >= 0, return -1, "Invalid fd for dump %d", fd);
562     WATCHER_CHECK(remoteWatchers_ != 0, return -1, "Invalid remote watcher");
563     WATCHER_CHECK(watcherGroups_ != 0, return -1, "Invalid watcher group");
564     std::vector<std::string> params;
565     for (auto& arg : args) {
566         params.emplace_back(Str16ToStr8(arg));
567     }
568     if (params.size() >= 1 && params[0] == "-h") {
569         std::string dumpInfo = {};
570         dumpInfo.append("Usage:\n")
571             .append(" -h                    ")
572             .append("|help text for the tool\n")
573             .append(" -k                    ")
574             .append("|dump watcher infomation for key prefix\n");
575         dprintf(fd, "%s\n", dumpInfo.c_str());
576         return 0;
577     }
578     auto dumpParamWatcher = [this, fd](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
579         auto remoteWatcher = GetRemoteWatcher(node->GetNodeId());
580         if (remoteWatcher != nullptr) {
581             dprintf(fd, "%s%u(%u)", (index == 0) ? "Watch id list  : " : ", ",
582                 node->GetNodeId(), remoteWatcher->GetAgentId());
583         } else {
584             dprintf(fd, "%s%u", (index == 0) ? "Watch id list  : " : ", ", node->GetNodeId());
585         }
586     };
587 
588     if (params.size() > 1 && params[0] == "-k") {
589         std::lock_guard<std::mutex> lock(watcherMutex_);
590         auto group = GetWatcherGroup(params[1]);
591         if (group == NULL) {
592             dprintf(fd, "Prefix %s not found in watcher list\n", params[1].c_str());
593             return 0;
594         }
595         {
596             group->TraversalNode(dumpParamWatcher);
597         }
598         return 0;
599     }
600     DumpAllGroup(fd, dumpParamWatcher);
601     return 0;
602 }
603 
Clear(void)604 void WatcherManager::Clear(void)
605 {
606     WATCHER_LOGV("Clear");
607     std::lock_guard<std::mutex> lock(watcherMutex_);
608     remoteWatchers_->TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
609         list->RemoveNode(node);
610         auto group = ConvertTo<WatcherGroup>(node);
611         WATCHER_LOGV("Delete watcher group %u", group->GetGroupId());
612         delete group;
613     });
614     watcherGroups_->TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
615         list->RemoveNode(node);
616         auto remoteWatcher = ConvertTo<RemoteWatcher>(node);
617         WATCHER_LOGV("Delete remote watcher %u", remoteWatcher->GetRemoteWatcherId());
618         delete remoteWatcher;
619     });
620     delete remoteWatchers_;
621     remoteWatchers_ = nullptr;
622     delete watcherGroups_;
623     watcherGroups_ = nullptr;
624 }
625 
AddRemoteWatcher(RemoteWatcherPtr remoteWatcher)626 int WatcherManager::AddRemoteWatcher(RemoteWatcherPtr remoteWatcher)
627 {
628     if (remoteWatchers_ == nullptr) {
629         remoteWatchers_ = new ParamWatcherList();
630         WATCHER_CHECK(remoteWatchers_ != nullptr, return -1, "Failed to create watcher");
631     }
632     return remoteWatchers_->AddNode(ConvertTo<WatcherNode>(remoteWatcher));
633 }
634 
GetRemoteWatcher(uint32_t remoteWatcherId)635 RemoteWatcherPtr WatcherManager::GetRemoteWatcher(uint32_t remoteWatcherId)
636 {
637     WATCHER_CHECK(remoteWatchers_ != nullptr, return nullptr, "Invalid remote watcher");
638     WatcherNodePtr node = remoteWatchers_->GetNode(remoteWatcherId);
639     if (node == nullptr) {
640         return nullptr;
641     }
642     return ConvertTo<RemoteWatcher>(node);
643 }
644 
DelRemoteWatcher(RemoteWatcherPtr remoteWatcher)645 void WatcherManager::DelRemoteWatcher(RemoteWatcherPtr remoteWatcher)
646 {
647     WATCHER_CHECK(remoteWatchers_ != nullptr, return, "Invalid remote watcher");
648     remoteWatchers_->RemoveNode(ConvertTo<WatcherNode>(remoteWatcher));
649     delete remoteWatcher;
650 }
651 
AddParamWatcher(WatcherGroupPtr group,RemoteWatcherPtr remoteWatcher)652 int WatcherManager::AddParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher)
653 {
654     WatcherNodePtr nodeGroup = new ParamWatcher(group->GetGroupId());
655     WATCHER_CHECK(nodeGroup != nullptr, return -1, "Failed to create watcher node for group");
656     WatcherNodePtr nodeRemote = new ParamWatcher(remoteWatcher->GetRemoteWatcherId());
657     WATCHER_CHECK(nodeRemote != nullptr, delete nodeGroup;
658         return -1, "Failed to create watcher node for remote watcher");
659     group->AddNode(nodeRemote);
660     remoteWatcher->AddNode(nodeGroup);
661     return 0;
662 }
663 
DelParamWatcher(WatcherGroupPtr group,RemoteWatcherPtr remoteWatcher)664 int WatcherManager::DelParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher)
665 {
666     WATCHER_LOGI("Delete param watcher remoteWatcherId %u group %u",
667         remoteWatcher->GetRemoteWatcherId(), group->GetGroupId());
668     WatcherNodePtr node = group->GetNode(remoteWatcher->GetRemoteWatcherId());
669     if (node != nullptr) {
670         group->RemoveNode(node);
671         delete node;
672     }
673     node = remoteWatcher->GetNode(group->GetGroupId());
674     if (node != nullptr) {
675         remoteWatcher->RemoveNode(node);
676         delete node;
677     }
678     return 0;
679 }
680 
AddWatcherGroup(const std::string & keyPrefix)681 WatcherGroupPtr WatcherManager::AddWatcherGroup(const std::string &keyPrefix)
682 {
683     if (watcherGroups_ == nullptr) {
684         watcherGroups_ = new ParamWatcherList();
685         WATCHER_CHECK(watcherGroups_ != nullptr, return nullptr, "Failed to create watcher");
686     }
687     // get group
688     auto it = groupMap_.find(keyPrefix);
689     if (it != groupMap_.end()) {
690         return it->second;
691     }
692     // create group
693     uint32_t groupId = 0;
694     int ret = GetGroupId(groupId);
695     WATCHER_CHECK(ret == 0, return nullptr, "Failed to get group id for %s", keyPrefix.c_str());
696     WatcherGroupPtr group = new WatcherGroup(groupId, keyPrefix);
697     WATCHER_CHECK(group != nullptr, return nullptr, "Failed to create group for %s", keyPrefix.c_str());
698     watcherGroups_->AddNode(ConvertTo<WatcherNode>(group));
699     groupMap_[keyPrefix] = group;
700     return group;
701 }
702 
GetWatcherGroup(uint32_t groupId)703 WatcherGroupPtr WatcherManager::GetWatcherGroup(uint32_t groupId)
704 {
705     WATCHER_CHECK(watcherGroups_ != nullptr, return nullptr, "Invalid watcher groups");
706     WatcherNodePtr node = watcherGroups_->GetNode(groupId);
707     if (node == nullptr) {
708         return nullptr;
709     }
710     return ConvertTo<WatcherGroup>(node);
711 }
712 
GetWatcherGroup(const std::string & keyPrefix)713 WatcherGroupPtr WatcherManager::GetWatcherGroup(const std::string &keyPrefix)
714 {
715     // get group
716     auto it = groupMap_.find(keyPrefix);
717     if (it != groupMap_.end()) {
718         return it->second;
719     }
720     return nullptr;
721 }
722 
DelWatcherGroup(WatcherGroupPtr group)723 void WatcherManager::DelWatcherGroup(WatcherGroupPtr group)
724 {
725     WATCHER_CHECK(watcherGroups_ != nullptr, return, "Invalid watcher groups");
726     WATCHER_LOGI("Delete watcher group %s %u", group->GetKeyPrefix().c_str(), group->GetGroupId());
727     watcherGroups_->RemoveNode(ConvertTo<WatcherNode>(group));
728     auto it = groupMap_.find(group->GetKeyPrefix());
729     if (it != groupMap_.end()) {
730         groupMap_.erase(it);
731     }
732     delete group;
733 }
734 
AddNode(WatcherNodePtr node)735 int ParamWatcherList::AddNode(WatcherNodePtr node)
736 {
737     WATCHER_CHECK(node, return -1, "Invalid input node");
738     node->AddToList(&nodeList_);
739     nodeCount_++;
740     return 0;
741 }
742 
RemoveNode(WatcherNodePtr node)743 int ParamWatcherList::RemoveNode(WatcherNodePtr node)
744 {
745     WATCHER_CHECK(node, return -1, "Invalid input node");
746     node->RemoveFromList(&nodeList_);
747     nodeCount_--;
748     return 0;
749 }
750 
GetNode(uint32_t nodeId)751 WatcherNodePtr ParamWatcherList::GetNode(uint32_t nodeId)
752 {
753     return WatcherNode::GetFromList(&nodeList_, nodeId);
754 }
755 
GetNextNodeSafe(WatcherNodePtr node)756 WatcherNodePtr ParamWatcherList::GetNextNodeSafe(WatcherNodePtr node)
757 {
758     if (node == nullptr) { // get first
759         return WatcherNode::GetNextFromList(&nodeList_, 0);
760     }
761     return WatcherNode::GetNextFromList(&nodeList_, node->GetNodeId());
762 }
763 
GetNextNode(WatcherNodePtr node)764 WatcherNodePtr ParamWatcherList::GetNextNode(WatcherNodePtr node)
765 {
766     if (node == nullptr) { // get first
767         return WatcherNode::GetNextFromList(&nodeList_, 0);
768     }
769     return node->GetNext(&nodeList_);
770 }
771 
TraversalNode(ParamWatcherProcessor handle)772 void ParamWatcherList::TraversalNode(ParamWatcherProcessor handle)
773 {
774     uint32_t index = 0;
775     // get first
776     WatcherNodePtr node = WatcherNode::GetNextFromList(&nodeList_, 0);
777     while (node != nullptr) {
778         WatcherNodePtr next = node->GetNext(&nodeList_);
779         handle(this, node, index);
780         node = next;
781         index++;
782     }
783 }
784 
TraversalNodeSafe(ParamWatcherProcessor processor)785 void ParamWatcherList::TraversalNodeSafe(ParamWatcherProcessor processor)
786 {
787     uint32_t index = 0;
788     // get first
789     WatcherNodePtr node = WatcherNode::GetNextFromList(&nodeList_, 0);
790     while (node != nullptr) {
791         uint32_t nodeId = node->GetNodeId();
792         // notify free, must be free
793         processor(this, node, index);
794         node = WatcherNode::GetNextFromList(&nodeList_, nodeId);
795         index++;
796     }
797 }
798 
AddToList(ListHead * list)799 void WatcherNode::AddToList(ListHead *list)
800 {
801     OH_ListAddWithOrder(list, &node_, CompareNode);
802 }
803 
RemoveFromList(ListHead * list)804 void WatcherNode::RemoveFromList(ListHead *list)
805 {
806     OH_ListRemove(&node_);
807 }
808 
GetFromList(ListHead * list,uint32_t nodeId)809 WatcherNodePtr WatcherNode::GetFromList(ListHead *list, uint32_t nodeId)
810 {
811     ListNodePtr node = OH_ListFind(list, &nodeId, CompareData);
812     if (node == nullptr) {
813         return nullptr;
814     }
815     return WatcherNode::ConvertNodeToBase(node);
816 }
817 
GetNextFromList(ListHead * list,uint32_t nodeId)818 WatcherNodePtr WatcherNode::GetNextFromList(ListHead *list, uint32_t nodeId)
819 {
820     ListNodePtr node = OH_ListFind(list, &nodeId, Greater);
821     if (node == nullptr) {
822         return nullptr;
823     }
824     return WatcherNode::ConvertNodeToBase(node);
825 }
826 
GetNext(ListHead * list)827 WatcherNodePtr WatcherNode::GetNext(ListHead *list)
828 {
829     if (node_.next == list) {
830         return nullptr;
831     }
832     return WatcherNode::ConvertNodeToBase(node_.next);
833 }
834 
CompareNode(ListNodePtr node,ListNodePtr newNode)835 int WatcherNode::CompareNode(ListNodePtr node, ListNodePtr newNode)
836 {
837     WatcherNodePtr watcher = WatcherNode::ConvertNodeToBase(node);
838     WatcherNodePtr newWatcher = WatcherNode::ConvertNodeToBase(node);
839     return watcher->nodeId_ - newWatcher->nodeId_;
840 }
841 
CompareData(ListNodePtr node,void * data)842 int WatcherNode::CompareData(ListNodePtr node, void *data)
843 {
844     WatcherNodePtr watcher =  WatcherNode::ConvertNodeToBase(node);
845     uint32_t id = *(uint32_t *)data;
846     return watcher->nodeId_ - id;
847 }
848 
Greater(ListNodePtr node,void * data)849 int WatcherNode::Greater(ListNodePtr node, void *data)
850 {
851     WatcherNodePtr watcher =  WatcherNode::ConvertNodeToBase(node);
852     uint32_t id = *(uint32_t *)data;
853     return (watcher->nodeId_ > id) ? 0 : 1;
854 }
855 
~WatcherGroup(void)856 WatcherGroup::~WatcherGroup(void)
857 {
858     TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
859         list->RemoveNode(node);
860         ParamWatcher *watcher = ConvertTo<ParamWatcher>(node);
861         WATCHER_LOGV("delete watcher group %u", watcher->GetNodeId());
862         delete watcher;
863     });
864 }
865 
~RemoteWatcher(void)866 RemoteWatcher::~RemoteWatcher(void)
867 {
868     watcher_ = nullptr;
869     TraversalNodeSafe([](ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index) {
870         list->RemoveNode(node);
871         ParamWatcher *watcher = ConvertTo<ParamWatcher>(node);
872         WATCHER_LOGV("delete remote watcher %u", watcher->GetNodeId());
873         delete watcher;
874     });
875 }
876 } // namespace init_param
877 } // namespace OHOS
878