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_