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