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