• 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_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