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