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