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