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