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