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_kits.h"
16
17 #include "if_system_ability_manager.h"
18 #include "iservice_registry.h"
19 #include "iwatcher.h"
20 #include "iwatcher_manager.h"
21 #include "param_request.h"
22 #include "system_ability_definition.h"
23 #include "watcher_utils.h"
24
25 namespace OHOS {
26 namespace init_param {
GetInstance()27 WatcherManagerKits &WatcherManagerKits::GetInstance()
28 {
29 return DelayedRefSingleton<WatcherManagerKits>::GetInstance();
30 }
31
WatcherManagerKits()32 WatcherManagerKits::WatcherManagerKits() {}
33
~WatcherManagerKits()34 WatcherManagerKits::~WatcherManagerKits() {}
35
ResetService(const wptr<IRemoteObject> & remote)36 void WatcherManagerKits::ResetService(const wptr<IRemoteObject> &remote)
37 {
38 WATCHER_LOGI("Remote is dead, reset service instance");
39 bool resetService = false;
40 {
41 std::lock_guard<std::mutex> lock(lock_);
42 if (watcherManager_ != nullptr) {
43 sptr<IRemoteObject> object = watcherManager_->AsObject();
44 if ((object != nullptr) && (remote == object)) {
45 object->RemoveDeathRecipient(deathRecipient_);
46 watcherManager_ = nullptr;
47 resetService = true;
48 }
49 }
50 }
51 if (resetService) {
52 ReAddWatcher();
53 }
54 }
55
GetService()56 sptr<IWatcherManager> WatcherManagerKits::GetService()
57 {
58 std::lock_guard<std::mutex> lock(lock_);
59 if (watcherManager_ != nullptr) {
60 return watcherManager_;
61 }
62
63 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
64 WATCHER_CHECK(samgr != nullptr, return nullptr, "Get samgr failed");
65 sptr<IRemoteObject> object = samgr->GetSystemAbility(PARAM_WATCHER_DISTRIBUTED_SERVICE_ID);
66 WATCHER_CHECK(object != nullptr, return nullptr, "Get watcher manager object from samgr failed");
67 if (deathRecipient_ == nullptr) {
68 deathRecipient_ = new DeathRecipient();
69 }
70
71 if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
72 WATCHER_LOGE("Failed to add death recipient");
73 }
74 watcherManager_ = iface_cast<IWatcherManager>(object);
75 if (watcherManager_ == nullptr) {
76 WATCHER_LOGE("watcher manager iface_cast failed");
77 }
78 return watcherManager_;
79 }
80
OnRemoteDied(const wptr<IRemoteObject> & remote)81 void WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
82 {
83 DelayedRefSingleton<WatcherManagerKits>::GetInstance().ResetService(remote);
84 }
85
GetParamWatcher(const std::string & keyPrefix)86 WatcherManagerKits::ParamWatcherKitPtr WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix)
87 {
88 std::lock_guard<std::mutex> lock(mutex_);
89 if (watchers_.find(keyPrefix) == watchers_.end()) {
90 return nullptr;
91 }
92 return watchers_[keyPrefix];
93 }
94
SetParamWatcher(const std::string & keyPrefix,ParamWatcherKitPtr watcher)95 void WatcherManagerKits::SetParamWatcher(const std::string &keyPrefix, ParamWatcherKitPtr watcher)
96 {
97 std::lock_guard<std::mutex> lock(mutex_);
98 if (watchers_.find(keyPrefix) == watchers_.end()) {
99 watchers_[keyPrefix] = watcher;
100 }
101 }
102
ReAddWatcher()103 void WatcherManagerKits::ReAddWatcher()
104 {
105 WATCHER_LOGV("ReAddWatcher ");
106 int count = 0;
107 const int maxRetryCount = 100;
108 const int sleepTime = 100;
109 auto watcherManager = GetService();
110 while (watcherManager == nullptr && count < maxRetryCount) {
111 watcherManager = GetService();
112 usleep(sleepTime);
113 count++;
114 }
115 WATCHER_CHECK(watcherManager != nullptr, return, "Failed to get watcher manager");
116 std::lock_guard<std::mutex> lock(mutex_);
117 for (auto iter = watchers_.begin(); iter != watchers_.end(); iter++) {
118 if (iter->second == nullptr) {
119 continue;
120 }
121 WATCHER_LOGV("ReAddWatcher keyPrefix %s ", iter->first.c_str());
122 uint32_t watcherId = watcherManager->AddWatcher(iter->first, iter->second);
123 WATCHER_CHECK(watcherId != 0, continue, "Failed to add watcher for %s", iter->first.c_str());
124 iter->second->SetWatcherId(watcherId);
125 }
126 }
127
AddWatcher(const std::string & keyPrefix,ParameterChangePtr callback,void * context)128 int32_t WatcherManagerKits::AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context)
129 {
130 WATCHER_LOGI("AddWatcher keyPrefix %s", keyPrefix.c_str());
131 ParamWatcherKitPtr watcher = GetParamWatcher(keyPrefix);
132 WATCHER_CHECK(watcher == nullptr, return watcher->GetWatcherId(),
133 "Has been watched by keyPrefix %s", keyPrefix.c_str());
134
135 watcher = new ParamWatcher(keyPrefix, callback, context);
136 WATCHER_CHECK(watcher != nullptr, return -1, "Failed to create watcher for %s", keyPrefix.c_str());
137 auto watcherManager = GetService();
138 WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
139 uint32_t watcherId = watcherManager->AddWatcher(keyPrefix, watcher);
140 WATCHER_CHECK(watcherId != 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str());
141 watcher->SetWatcherId(watcherId);
142 SetParamWatcher(keyPrefix, watcher);
143 return watcher->GetWatcherId();
144 }
145
DelWatcher(const std::string & keyPrefix)146 int32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix)
147 {
148 ParamWatcherKitPtr watcher = GetParamWatcher(keyPrefix);
149 WATCHER_CHECK(watcher != nullptr, return 0, "Can not find watcher for keyPrefix %s", keyPrefix.c_str());
150 auto watcherManager = GetService();
151 WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
152 WATCHER_LOGV("DelWatcher keyPrefix_ %s ", keyPrefix.c_str());
153 int ret = watcherManager->DelWatcher(keyPrefix, watcher->GetWatcherId());
154 WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str());
155 {
156 std::lock_guard<std::mutex> lock(mutex_);
157 auto iter = watchers_.find(keyPrefix);
158 if (iter != watchers_.end()) {
159 watchers_.erase(iter);
160 }
161 }
162 return 0;
163 }
164
OnParamerterChange(const std::string & name,const std::string & value)165 void WatcherManagerKits::ParamWatcher::OnParamerterChange(const std::string &name, const std::string &value)
166 {
167 Watcher::OnParamerterChange(name, value);
168 WATCHER_LOGV("OnParamerterChange name %s value %s", name.c_str(), value.c_str());
169 if (callback_ != nullptr) {
170 callback_(name.c_str(), value.c_str(), context_);
171 }
172 }
173 } // namespace init_param
174 } // namespace OHOS
175
SystemWatchParameter(const char * keyPrefix,ParameterChangePtr callback,void * context)176 int SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context)
177 {
178 WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
179 int ret = 0;
180 std::string key(keyPrefix);
181 if (key.rfind("*") == key.length() - 1) {
182 ret = WatchParamCheck(key.substr(0, key.length() - 1).c_str());
183 } else {
184 ret = WatchParamCheck(keyPrefix);
185 }
186 if (ret != 0) {
187 return ret;
188 }
189 OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
190 if (callback != nullptr) {
191 ret = (instance.AddWatcher(keyPrefix, callback, context) > 0) ? 0 : -1;
192 } else {
193 ret = instance.DelWatcher(keyPrefix);
194 }
195 return ret;
196 }
197