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#ifndef WATCHER_MANAGER_H_
16d9f0492fSopenharmony_ci#define WATCHER_MANAGER_H_
17d9f0492fSopenharmony_ci#include <atomic>
18d9f0492fSopenharmony_ci#include <iostream>
19d9f0492fSopenharmony_ci#include <map>
20d9f0492fSopenharmony_ci#include <mutex>
21d9f0492fSopenharmony_ci#include <thread>
22d9f0492fSopenharmony_ci#include <vector>
23d9f0492fSopenharmony_ci
24d9f0492fSopenharmony_ci#include "iremote_stub.h"
25d9f0492fSopenharmony_ci#include "iwatcher.h"
26d9f0492fSopenharmony_ci#include "list.h"
27d9f0492fSopenharmony_ci#include "message_parcel.h"
28d9f0492fSopenharmony_ci#include "param_utils.h"
29d9f0492fSopenharmony_ci#include "parcel.h"
30d9f0492fSopenharmony_ci#include "param_message.h"
31d9f0492fSopenharmony_ci#include "system_ability.h"
32d9f0492fSopenharmony_ci#include "watcher_manager_stub.h"
33d9f0492fSopenharmony_ci
34d9f0492fSopenharmony_cinamespace OHOS {
35d9f0492fSopenharmony_cinamespace init_param {
36d9f0492fSopenharmony_ciclass WatcherNode;
37d9f0492fSopenharmony_ciclass ParamWatcherList;
38d9f0492fSopenharmony_ciclass WatcherGroup;
39d9f0492fSopenharmony_ciclass RemoteWatcher;
40d9f0492fSopenharmony_ciusing WatcherGroupPtr = WatcherGroup *;
41d9f0492fSopenharmony_ciusing RemoteWatcherPtr = RemoteWatcher *;
42d9f0492fSopenharmony_ciusing WatcherNodePtr = WatcherNode *;
43d9f0492fSopenharmony_ciusing ListNodePtr = ListNode *;
44d9f0492fSopenharmony_ciusing ListHeadPtr = ListHead *;
45d9f0492fSopenharmony_ciusing ParamWatcherListPtr = ParamWatcherList *;
46d9f0492fSopenharmony_ciusing ParamWatcherProcessor = std::function<void(ParamWatcherListPtr list, WatcherNodePtr node, uint32_t index)>;
47d9f0492fSopenharmony_ci
48d9f0492fSopenharmony_ciclass WatcherManager : public SystemAbility, public WatcherManagerStub {
49d9f0492fSopenharmony_cipublic:
50d9f0492fSopenharmony_ci    friend class WatcherGroup;
51d9f0492fSopenharmony_ci    DECLARE_SYSTEM_ABILITY(WatcherManager);
52d9f0492fSopenharmony_ci    DISALLOW_COPY_AND_MOVE(WatcherManager);
53d9f0492fSopenharmony_ci    explicit WatcherManager(int32_t systemAbilityId, bool runOnCreate = true)
54d9f0492fSopenharmony_ci        : SystemAbility(systemAbilityId, runOnCreate)
55d9f0492fSopenharmony_ci    {
56d9f0492fSopenharmony_ci    }
57d9f0492fSopenharmony_ci    ~WatcherManager() override;
58d9f0492fSopenharmony_ci
59d9f0492fSopenharmony_ci    // For death event procession
60d9f0492fSopenharmony_ci    class DeathRecipient final : public IRemoteObject::DeathRecipient {
61d9f0492fSopenharmony_ci    public:
62d9f0492fSopenharmony_ci        explicit DeathRecipient(WatcherManager *manager) : manager_(manager) {}
63d9f0492fSopenharmony_ci        ~DeathRecipient() final = default;
64d9f0492fSopenharmony_ci        DISALLOW_COPY_AND_MOVE(DeathRecipient);
65d9f0492fSopenharmony_ci        void OnRemoteDied(const wptr<IRemoteObject> &remote) final
66d9f0492fSopenharmony_ci        {
67d9f0492fSopenharmony_ci            manager_->OnRemoteDied(remote);
68d9f0492fSopenharmony_ci        }
69d9f0492fSopenharmony_ci    private:
70d9f0492fSopenharmony_ci        WatcherManager *manager_;
71d9f0492fSopenharmony_ci    };
72d9f0492fSopenharmony_ci    sptr<IRemoteObject::DeathRecipient> GetDeathRecipient(void)
73d9f0492fSopenharmony_ci    {
74d9f0492fSopenharmony_ci        return deathRecipient_;
75d9f0492fSopenharmony_ci    }
76d9f0492fSopenharmony_ci    uint32_t AddRemoteWatcher(uint32_t id, const sptr<IWatcher> &watcher) override;
77d9f0492fSopenharmony_ci    int32_t DelRemoteWatcher(uint32_t remoteWatcherId) override;
78d9f0492fSopenharmony_ci    int32_t AddWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
79d9f0492fSopenharmony_ci    int32_t DelWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
80d9f0492fSopenharmony_ci    int32_t RefreshWatcher(const std::string &keyPrefix, uint32_t remoteWatcherId) override;
81d9f0492fSopenharmony_ciprotected:
82d9f0492fSopenharmony_ci    void OnStart() override;
83d9f0492fSopenharmony_ci    void OnStop() override;
84d9f0492fSopenharmony_ci    int Dump(int fd, const std::vector<std::u16string>& args) override;
85d9f0492fSopenharmony_ciprivate:
86d9f0492fSopenharmony_ci    void RunLoop();
87d9f0492fSopenharmony_ci    void StartLoop();
88d9f0492fSopenharmony_ci    void StopLoop();
89d9f0492fSopenharmony_ci    void SendLocalChange(const std::string &keyPrefix, uint32_t remoteWatcherId);
90d9f0492fSopenharmony_ci    int SendMessage(WatcherGroupPtr group, int type);
91d9f0492fSopenharmony_ci    int GetServerFd(bool retry);
92d9f0492fSopenharmony_ci    int GetRemoteWatcherId(uint32_t &remoteWatcherId);
93d9f0492fSopenharmony_ci    int GetGroupId(uint32_t &groupId);
94d9f0492fSopenharmony_ci    // for remote watcher
95d9f0492fSopenharmony_ci    int AddRemoteWatcher(RemoteWatcherPtr remoteWatcher);
96d9f0492fSopenharmony_ci    RemoteWatcherPtr GetRemoteWatcher(uint32_t remoteWatcherId);
97d9f0492fSopenharmony_ci    RemoteWatcherPtr GetRemoteWatcher(const wptr<IRemoteObject> &remote);
98d9f0492fSopenharmony_ci    void DelRemoteWatcher(RemoteWatcherPtr remoteWatcher);
99d9f0492fSopenharmony_ci    // for group
100d9f0492fSopenharmony_ci    WatcherGroupPtr AddWatcherGroup(const std::string &keyPrefix);
101d9f0492fSopenharmony_ci    WatcherGroupPtr GetWatcherGroup(const std::string &keyPrefix);
102d9f0492fSopenharmony_ci    WatcherGroupPtr GetWatcherGroup(uint32_t groupId);
103d9f0492fSopenharmony_ci    void DelWatcherGroup(WatcherGroupPtr group);
104d9f0492fSopenharmony_ci    // for param watcher
105d9f0492fSopenharmony_ci    int AddParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher);
106d9f0492fSopenharmony_ci    int DelParamWatcher(WatcherGroupPtr group, RemoteWatcherPtr remoteWatcher);
107d9f0492fSopenharmony_ci    // for process message form init
108d9f0492fSopenharmony_ci    void ProcessWatcherMessage(const ParamMessage *msg);
109d9f0492fSopenharmony_ci    // for client died
110d9f0492fSopenharmony_ci    void OnRemoteDied(const wptr<IRemoteObject> &remote);
111d9f0492fSopenharmony_ci    void OnRemoteDied(RemoteWatcherPtr remoteWatcher);
112d9f0492fSopenharmony_ci    // clear
113d9f0492fSopenharmony_ci    void Clear(void);
114d9f0492fSopenharmony_ci    // dump
115d9f0492fSopenharmony_ci    void DumpAllGroup(int fd, ParamWatcherProcessor dumpHandle);
116d9f0492fSopenharmony_ciprivate:
117d9f0492fSopenharmony_ci    std::atomic<uint32_t> remoteWatcherId_ { 0 };
118d9f0492fSopenharmony_ci    std::atomic<uint32_t> groupId_ { 0 };
119d9f0492fSopenharmony_ci    std::mutex mutex_;
120d9f0492fSopenharmony_ci    std::mutex watcherMutex_;
121d9f0492fSopenharmony_ci    int serverFd_ { -1 };
122d9f0492fSopenharmony_ci    std::thread *pRecvThread_ { nullptr };
123d9f0492fSopenharmony_ci    std::atomic<bool> stop_ { false };
124d9f0492fSopenharmony_ci    std::map<std::string, WatcherGroupPtr> groupMap_ {};
125d9f0492fSopenharmony_ci    sptr<IRemoteObject::DeathRecipient> deathRecipient_ {};
126d9f0492fSopenharmony_ci    ParamWatcherListPtr watcherGroups_ {};
127d9f0492fSopenharmony_ci    ParamWatcherListPtr remoteWatchers_ {};
128d9f0492fSopenharmony_ci};
129d9f0492fSopenharmony_ci
130d9f0492fSopenharmony_ciclass WatcherNode {
131d9f0492fSopenharmony_cipublic:
132d9f0492fSopenharmony_ci    explicit WatcherNode(uint32_t nodeId) : nodeId_(nodeId)
133d9f0492fSopenharmony_ci    {
134d9f0492fSopenharmony_ci        OH_ListInit(&node_);
135d9f0492fSopenharmony_ci    }
136d9f0492fSopenharmony_ci    virtual ~WatcherNode(void) = default;
137d9f0492fSopenharmony_ci    uint32_t GetNodeId(void) const
138d9f0492fSopenharmony_ci    {
139d9f0492fSopenharmony_ci        return nodeId_;
140d9f0492fSopenharmony_ci    }
141d9f0492fSopenharmony_ci
142d9f0492fSopenharmony_ci    void AddToList(ListHeadPtr list);
143d9f0492fSopenharmony_ci    void RemoveFromList(ListHeadPtr list);
144d9f0492fSopenharmony_ci    WatcherNodePtr GetNext(ListHeadPtr list);
145d9f0492fSopenharmony_ci    static WatcherNodePtr GetFromList(ListHeadPtr list, uint32_t nodeId);
146d9f0492fSopenharmony_ci    static WatcherNodePtr GetNextFromList(ListHeadPtr list, uint32_t nodeId);
147d9f0492fSopenharmony_ci    static WatcherNodePtr ConvertNodeToBase(ListNodePtr node)
148d9f0492fSopenharmony_ci    {
149d9f0492fSopenharmony_ci        return reinterpret_cast<WatcherNodePtr>((char *)node - (char*)(&(((WatcherNodePtr)0)->node_)));
150d9f0492fSopenharmony_ci    }
151d9f0492fSopenharmony_ci    ListNodePtr GetListNode()
152d9f0492fSopenharmony_ci    {
153d9f0492fSopenharmony_ci        return &node_;
154d9f0492fSopenharmony_ci    }
155d9f0492fSopenharmony_ciprivate:
156d9f0492fSopenharmony_ci    static int CompareNode(ListNodePtr node, ListNodePtr newNode);
157d9f0492fSopenharmony_ci    static int CompareData(ListNodePtr node, void *data);
158d9f0492fSopenharmony_ci    static int Greater(ListNodePtr node, void *data);
159d9f0492fSopenharmony_ci    ListNode node_;
160d9f0492fSopenharmony_ci    uint32_t nodeId_;
161d9f0492fSopenharmony_ci};
162d9f0492fSopenharmony_ci
163d9f0492fSopenharmony_citemplate<typename T>
164d9f0492fSopenharmony_ciinline T *ConvertTo(WatcherNodePtr node)
165d9f0492fSopenharmony_ci{
166d9f0492fSopenharmony_ci#ifdef PARAM_WATCHER_RTTI_ENABLE
167d9f0492fSopenharmony_ci    // when -frtti is enabled, we use dynamic cast directly
168d9f0492fSopenharmony_ci    // to achieve the correct base class side-to-side conversion.
169d9f0492fSopenharmony_ci    T *obj = dynamic_cast<T *>(node);
170d9f0492fSopenharmony_ci#else
171d9f0492fSopenharmony_ci    // adjust pointer position when multiple inheritance.
172d9f0492fSopenharmony_ci    void *tmp = reinterpret_cast<void *>(node);
173d9f0492fSopenharmony_ci    // when -frtti is not enable, we use static cast.
174d9f0492fSopenharmony_ci    // static cast is not safe enough, but we have checked before we get here.
175d9f0492fSopenharmony_ci    T *obj = static_cast<T *>(tmp);
176d9f0492fSopenharmony_ci#endif
177d9f0492fSopenharmony_ci    return obj;
178d9f0492fSopenharmony_ci}
179d9f0492fSopenharmony_ci
180d9f0492fSopenharmony_ciclass ParamWatcher : public WatcherNode {
181d9f0492fSopenharmony_cipublic:
182d9f0492fSopenharmony_ci    explicit ParamWatcher(uint32_t watcherId) : WatcherNode(watcherId) {}
183d9f0492fSopenharmony_ci    ~ParamWatcher(void) override  {}
184d9f0492fSopenharmony_ci};
185d9f0492fSopenharmony_ci
186d9f0492fSopenharmony_ciclass ParamWatcherList {
187d9f0492fSopenharmony_cipublic:
188d9f0492fSopenharmony_ci    ParamWatcherList(void)
189d9f0492fSopenharmony_ci    {
190d9f0492fSopenharmony_ci        OH_ListInit(&nodeList_);
191d9f0492fSopenharmony_ci    }
192d9f0492fSopenharmony_ci    ~ParamWatcherList(void) = default;
193d9f0492fSopenharmony_ci
194d9f0492fSopenharmony_ci    bool Empty(void) const
195d9f0492fSopenharmony_ci    {
196d9f0492fSopenharmony_ci        return nodeList_.next == &nodeList_;
197d9f0492fSopenharmony_ci    }
198d9f0492fSopenharmony_ci    uint32_t GetNodeCount(void) const
199d9f0492fSopenharmony_ci    {
200d9f0492fSopenharmony_ci        return nodeCount_;
201d9f0492fSopenharmony_ci    }
202d9f0492fSopenharmony_ci    int AddNode(WatcherNodePtr node);
203d9f0492fSopenharmony_ci    int RemoveNode(WatcherNodePtr node);
204d9f0492fSopenharmony_ci    WatcherNodePtr GetNode(uint32_t nodeId);
205d9f0492fSopenharmony_ci    WatcherNodePtr GetNextNodeSafe(WatcherNodePtr node);
206d9f0492fSopenharmony_ci    WatcherNodePtr GetNextNode(WatcherNodePtr node);
207d9f0492fSopenharmony_ci    void TraversalNode(ParamWatcherProcessor handle);
208d9f0492fSopenharmony_ci    void TraversalNodeSafe(ParamWatcherProcessor processor);
209d9f0492fSopenharmony_cipublic:
210d9f0492fSopenharmony_ci    ListHead nodeList_ {};
211d9f0492fSopenharmony_ci    uint32_t nodeCount_ = 0;
212d9f0492fSopenharmony_ci};
213d9f0492fSopenharmony_ci
214d9f0492fSopenharmony_ciclass RemoteWatcher : public WatcherNode, public ParamWatcherList {
215d9f0492fSopenharmony_cipublic:
216d9f0492fSopenharmony_ci    RemoteWatcher(uint32_t watcherId, const sptr<IWatcher> &watcher)
217d9f0492fSopenharmony_ci        : WatcherNode(watcherId), ParamWatcherList(), watcher_(watcher) {}
218d9f0492fSopenharmony_ci    ~RemoteWatcher(void) override;
219d9f0492fSopenharmony_ci
220d9f0492fSopenharmony_ci    uint32_t GetRemoteWatcherId(void) const
221d9f0492fSopenharmony_ci    {
222d9f0492fSopenharmony_ci        return GetNodeId();
223d9f0492fSopenharmony_ci    }
224d9f0492fSopenharmony_ci    uint32_t GetAgentId(void) const
225d9f0492fSopenharmony_ci    {
226d9f0492fSopenharmony_ci        return id_;
227d9f0492fSopenharmony_ci    }
228d9f0492fSopenharmony_ci    bool CheckAgent(pid_t calling) const
229d9f0492fSopenharmony_ci    {
230d9f0492fSopenharmony_ci        return id_ == static_cast<uint32_t>(calling);
231d9f0492fSopenharmony_ci    }
232d9f0492fSopenharmony_ci    void SetAgentId(uint32_t id)
233d9f0492fSopenharmony_ci    {
234d9f0492fSopenharmony_ci        id_ = id;
235d9f0492fSopenharmony_ci    }
236d9f0492fSopenharmony_ci    void ProcessParameterChange(const std::string &prefix, const std::string &name, const std::string &value)
237d9f0492fSopenharmony_ci    {
238d9f0492fSopenharmony_ci        watcher_->OnParameterChange(prefix, name, value);
239d9f0492fSopenharmony_ci    }
240d9f0492fSopenharmony_ci    sptr<IWatcher> GetWatcher(void)
241d9f0492fSopenharmony_ci    {
242d9f0492fSopenharmony_ci        return watcher_;
243d9f0492fSopenharmony_ci    }
244d9f0492fSopenharmony_ciprivate:
245d9f0492fSopenharmony_ci    uint32_t id_ = { 0 };
246d9f0492fSopenharmony_ci    sptr<IWatcher> watcher_ {};
247d9f0492fSopenharmony_ci};
248d9f0492fSopenharmony_ci
249d9f0492fSopenharmony_ciclass WatcherGroup : public WatcherNode, public ParamWatcherList {
250d9f0492fSopenharmony_cipublic:
251d9f0492fSopenharmony_ci    WatcherGroup(uint32_t groupId, const std::string &key)
252d9f0492fSopenharmony_ci        : WatcherNode(groupId), ParamWatcherList(), keyPrefix_(key) {}
253d9f0492fSopenharmony_ci    ~WatcherGroup(void) override;
254d9f0492fSopenharmony_ci
255d9f0492fSopenharmony_ci    void ProcessParameterChange(WatcherManager *mananger, const std::string &name, const std::string &value);
256d9f0492fSopenharmony_ci    const std::string GetKeyPrefix() const
257d9f0492fSopenharmony_ci    {
258d9f0492fSopenharmony_ci        return keyPrefix_;
259d9f0492fSopenharmony_ci    }
260d9f0492fSopenharmony_ci    uint32_t GetGroupId() const
261d9f0492fSopenharmony_ci    {
262d9f0492fSopenharmony_ci        return GetNodeId();
263d9f0492fSopenharmony_ci    }
264d9f0492fSopenharmony_ciprivate:
265d9f0492fSopenharmony_ci    std::string keyPrefix_ { };
266d9f0492fSopenharmony_ci};
267d9f0492fSopenharmony_ci} // namespace init_param
268d9f0492fSopenharmony_ci} // namespace OHOS
269d9f0492fSopenharmony_ci#endif // WATCHER_MANAGER_H_