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