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