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