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