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