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#include "watcher_manager_kits.h"
16d9f0492fSopenharmony_ci
17d9f0492fSopenharmony_ci#include "if_system_ability_manager.h"
18d9f0492fSopenharmony_ci#include "init_param.h"
19d9f0492fSopenharmony_ci#include "iservice_registry.h"
20d9f0492fSopenharmony_ci#include "iwatcher.h"
21d9f0492fSopenharmony_ci#include "iwatcher_manager.h"
22d9f0492fSopenharmony_ci#include "system_ability_definition.h"
23d9f0492fSopenharmony_ci#include "watcher_utils.h"
24d9f0492fSopenharmony_ci#include "parameter.h"
25d9f0492fSopenharmony_ci#include "init_param.h"
26d9f0492fSopenharmony_ci
27d9f0492fSopenharmony_cinamespace OHOS {
28d9f0492fSopenharmony_cinamespace init_param {
29d9f0492fSopenharmony_ciWatcherManagerKits &WatcherManagerKits::GetInstance(void)
30d9f0492fSopenharmony_ci{
31d9f0492fSopenharmony_ci    return DelayedRefSingleton<WatcherManagerKits>::GetInstance();
32d9f0492fSopenharmony_ci}
33d9f0492fSopenharmony_ci
34d9f0492fSopenharmony_ciWatcherManagerKits::WatcherManagerKits(void) {}
35d9f0492fSopenharmony_ci
36d9f0492fSopenharmony_ciWatcherManagerKits::~WatcherManagerKits(void) {}
37d9f0492fSopenharmony_ci
38d9f0492fSopenharmony_civoid WatcherManagerKits::ResetService(const wptr<IRemoteObject> &remote)
39d9f0492fSopenharmony_ci{
40d9f0492fSopenharmony_ci    WATCHER_LOGI("Remote is dead, reset service instance");
41d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
42d9f0492fSopenharmony_ci    if (watcherManager_ != nullptr) {
43d9f0492fSopenharmony_ci        sptr<IRemoteObject> object = watcherManager_->AsObject();
44d9f0492fSopenharmony_ci        if ((object != nullptr) && (remote == object)) {
45d9f0492fSopenharmony_ci            object->RemoveDeathRecipient(deathRecipient_);
46d9f0492fSopenharmony_ci            watcherManager_ = nullptr;
47d9f0492fSopenharmony_ci            remoteWatcherId_ = 0;
48d9f0492fSopenharmony_ci            remoteWatcher_ = nullptr;
49d9f0492fSopenharmony_ci            if (threadForReWatch_ != nullptr) {
50d9f0492fSopenharmony_ci                WATCHER_LOGI("Thead exist, delete thread");
51d9f0492fSopenharmony_ci                stop_ = true;
52d9f0492fSopenharmony_ci                threadForReWatch_->join();
53d9f0492fSopenharmony_ci                delete threadForReWatch_;
54d9f0492fSopenharmony_ci            }
55d9f0492fSopenharmony_ci            stop_ = false;
56d9f0492fSopenharmony_ci            threadForReWatch_ = new (std::nothrow)std::thread([this] {this->ReAddWatcher();});
57d9f0492fSopenharmony_ci            WATCHER_CHECK(threadForReWatch_ != nullptr, return, "Failed to create thread");
58d9f0492fSopenharmony_ci        }
59d9f0492fSopenharmony_ci    }
60d9f0492fSopenharmony_ci}
61d9f0492fSopenharmony_ci
62d9f0492fSopenharmony_cisptr<IWatcherManager> WatcherManagerKits::GetService(void)
63d9f0492fSopenharmony_ci{
64d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
65d9f0492fSopenharmony_ci    if (watcherManager_ != nullptr) {
66d9f0492fSopenharmony_ci        return watcherManager_;
67d9f0492fSopenharmony_ci    }
68d9f0492fSopenharmony_ci
69d9f0492fSopenharmony_ci    sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
70d9f0492fSopenharmony_ci    WATCHER_CHECK(samgr != nullptr, return nullptr, "Get samgr failed");
71d9f0492fSopenharmony_ci    sptr<IRemoteObject> object = samgr->GetSystemAbility(PARAM_WATCHER_DISTRIBUTED_SERVICE_ID);
72d9f0492fSopenharmony_ci    WATCHER_CHECK(object != nullptr, return nullptr, "Get watcher manager object from samgr failed");
73d9f0492fSopenharmony_ci    if (deathRecipient_ == nullptr) {
74d9f0492fSopenharmony_ci        deathRecipient_ = new DeathRecipient();
75d9f0492fSopenharmony_ci    }
76d9f0492fSopenharmony_ci
77d9f0492fSopenharmony_ci    if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
78d9f0492fSopenharmony_ci        WATCHER_LOGE("Failed to add death recipient");
79d9f0492fSopenharmony_ci    }
80d9f0492fSopenharmony_ci    watcherManager_ = iface_cast<IWatcherManager>(object);
81d9f0492fSopenharmony_ci    return watcherManager_;
82d9f0492fSopenharmony_ci}
83d9f0492fSopenharmony_ci
84d9f0492fSopenharmony_civoid WatcherManagerKits::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
85d9f0492fSopenharmony_ci{
86d9f0492fSopenharmony_ci    DelayedRefSingleton<WatcherManagerKits>::GetInstance().ResetService(remote);
87d9f0492fSopenharmony_ci}
88d9f0492fSopenharmony_ci
89d9f0492fSopenharmony_civoid WatcherManagerKits::ReAddWatcher(void)
90d9f0492fSopenharmony_ci{
91d9f0492fSopenharmony_ci    WATCHER_LOGV("ReAddWatcher");
92d9f0492fSopenharmony_ci    int count = 0;
93d9f0492fSopenharmony_ci    const int maxRetryCount = 100;
94d9f0492fSopenharmony_ci    const int sleepTime = 100;
95d9f0492fSopenharmony_ci    auto watcherManager = GetService();
96d9f0492fSopenharmony_ci    while (watcherManager == nullptr && count < maxRetryCount) {
97d9f0492fSopenharmony_ci        if (stop_) {
98d9f0492fSopenharmony_ci            return;
99d9f0492fSopenharmony_ci        }
100d9f0492fSopenharmony_ci        watcherManager = GetService();
101d9f0492fSopenharmony_ci        usleep(sleepTime);
102d9f0492fSopenharmony_ci        count++;
103d9f0492fSopenharmony_ci    }
104d9f0492fSopenharmony_ci    WATCHER_LOGV("ReAddWatcher count %d ", count);
105d9f0492fSopenharmony_ci    WATCHER_CHECK(watcherManager != nullptr, return, "Failed to get watcher manager");
106d9f0492fSopenharmony_ci    // add or get remote agent
107d9f0492fSopenharmony_ci    uint32_t remoteWatcherId = GetRemoteWatcher();
108d9f0492fSopenharmony_ci    WATCHER_CHECK(remoteWatcherId > 0, return, "Failed to get remote agent");
109d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
110d9f0492fSopenharmony_ci    for (auto iter = watchers_.begin(); iter != watchers_.end(); iter++) {
111d9f0492fSopenharmony_ci        WATCHER_LOGI("Add old watcher keyPrefix %s ", iter->first.c_str());
112d9f0492fSopenharmony_ci        int ret = watcherManager->AddWatcher(iter->first, remoteWatcherId);
113d9f0492fSopenharmony_ci        WATCHER_CHECK(ret == 0, continue, "Failed to add watcher for %s", iter->first.c_str());
114d9f0492fSopenharmony_ci    }
115d9f0492fSopenharmony_ci}
116d9f0492fSopenharmony_ci
117d9f0492fSopenharmony_ciWatcherManagerKits::ParamWatcher *WatcherManagerKits::GetParamWatcher(const std::string &keyPrefix)
118d9f0492fSopenharmony_ci{
119d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
120d9f0492fSopenharmony_ci    auto iter = watchers_.find(keyPrefix);
121d9f0492fSopenharmony_ci    if (iter != watchers_.end()) {
122d9f0492fSopenharmony_ci        return iter->second.get();
123d9f0492fSopenharmony_ci    }
124d9f0492fSopenharmony_ci    return nullptr;
125d9f0492fSopenharmony_ci}
126d9f0492fSopenharmony_ci
127d9f0492fSopenharmony_ciuint32_t WatcherManagerKits::GetRemoteWatcher(void)
128d9f0492fSopenharmony_ci{
129d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
130d9f0492fSopenharmony_ci    if (remoteWatcher_ != nullptr) {
131d9f0492fSopenharmony_ci        return remoteWatcherId_;
132d9f0492fSopenharmony_ci    }
133d9f0492fSopenharmony_ci    auto watcherManager = GetService();
134d9f0492fSopenharmony_ci    WATCHER_CHECK(watcherManager != nullptr, return 0, "Failed to get watcher manager");
135d9f0492fSopenharmony_ci    remoteWatcher_  = new RemoteWatcher(this);
136d9f0492fSopenharmony_ci    WATCHER_CHECK(remoteWatcher_ != nullptr, return 0, "Failed to create watcher");
137d9f0492fSopenharmony_ci    remoteWatcherId_ = watcherManager->AddRemoteWatcher(getpid(), remoteWatcher_);
138d9f0492fSopenharmony_ci    WATCHER_CHECK(remoteWatcherId_ != 0, return 0, "Failed to add watcher");
139d9f0492fSopenharmony_ci    return remoteWatcherId_;
140d9f0492fSopenharmony_ci}
141d9f0492fSopenharmony_ci
142d9f0492fSopenharmony_ciint32_t WatcherManagerKits::AddWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context)
143d9f0492fSopenharmony_ci{
144d9f0492fSopenharmony_ci    auto watcherManager = GetService();
145d9f0492fSopenharmony_ci    WATCHER_CHECK(watcherManager != nullptr, return PARAM_WATCHER_GET_SERVICE_FAILED, "Failed to get watcher manager");
146d9f0492fSopenharmony_ci
147d9f0492fSopenharmony_ci    // add or get remote agent
148d9f0492fSopenharmony_ci    uint32_t remoteWatcherId = GetRemoteWatcher();
149d9f0492fSopenharmony_ci    WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent");
150d9f0492fSopenharmony_ci    ParamWatcherKitPtr watcher = nullptr;
151d9f0492fSopenharmony_ci    {
152d9f0492fSopenharmony_ci        std::lock_guard<std::mutex> lock(mutex_);
153d9f0492fSopenharmony_ci        // must check
154d9f0492fSopenharmony_ci        WATCHER_CHECK(remoteWatcherId > 0, return -1, "Failed to get remote agent");
155d9f0492fSopenharmony_ci        if (watchers_.find(keyPrefix) == watchers_.end()) {
156d9f0492fSopenharmony_ci            watcher = std::make_shared<ParamWatcher>(keyPrefix);
157d9f0492fSopenharmony_ci            WATCHER_CHECK(watcher != nullptr, return -1, "Failed to create watcher for %s", keyPrefix.c_str());
158d9f0492fSopenharmony_ci            int ret = watcher->AddParameterListener(callback, context);
159d9f0492fSopenharmony_ci            WATCHER_CHECK(ret == 0, return ret, "Failed to add callback for %s ", keyPrefix.c_str());
160d9f0492fSopenharmony_ci            ret = watcherManager->AddWatcher(keyPrefix, remoteWatcherId);
161d9f0492fSopenharmony_ci            WATCHER_CHECK(ret == 0, return -1, "Failed to add watcher for %s", keyPrefix.c_str());
162d9f0492fSopenharmony_ci            watchers_[keyPrefix] = watcher;
163d9f0492fSopenharmony_ci        } else {
164d9f0492fSopenharmony_ci            watcher = watchers_[keyPrefix];
165d9f0492fSopenharmony_ci            int ret = watcher->AddParameterListener(callback, context);
166d9f0492fSopenharmony_ci            WATCHER_CHECK(ret == 0, return ret, "Failed to add callback for %s ", keyPrefix.c_str());
167d9f0492fSopenharmony_ci            ret = watcherManager->RefreshWatcher(keyPrefix, remoteWatcherId);
168d9f0492fSopenharmony_ci            WATCHER_CHECK(ret == 0, return -1,
169d9f0492fSopenharmony_ci                "Failed to refresh watcher for %s %d", keyPrefix.c_str(), remoteWatcherId);
170d9f0492fSopenharmony_ci        }
171d9f0492fSopenharmony_ci    }
172d9f0492fSopenharmony_ci    WATCHER_LOGI("Add watcher keyPrefix %s remoteWatcherId %u success", keyPrefix.c_str(), remoteWatcherId);
173d9f0492fSopenharmony_ci    return 0;
174d9f0492fSopenharmony_ci}
175d9f0492fSopenharmony_ci
176d9f0492fSopenharmony_ciint32_t WatcherManagerKits::DelWatcher(const std::string &keyPrefix, ParameterChangePtr callback, void *context)
177d9f0492fSopenharmony_ci{
178d9f0492fSopenharmony_ci    auto watcherManager = GetService();
179d9f0492fSopenharmony_ci    WATCHER_CHECK(watcherManager != nullptr, return -1, "Failed to get watcher manager");
180d9f0492fSopenharmony_ci
181d9f0492fSopenharmony_ci    WatcherManagerKits::ParamWatcher *watcher = GetParamWatcher(keyPrefix);
182d9f0492fSopenharmony_ci    WATCHER_CHECK(watcher != nullptr, return -1, "Failed to get watcher");
183d9f0492fSopenharmony_ci
184d9f0492fSopenharmony_ci    int count = watcher->DelParameterListener(callback, context);
185d9f0492fSopenharmony_ci    WATCHER_LOGI("DelWatcher keyPrefix_ %s count %d", keyPrefix.c_str(), count);
186d9f0492fSopenharmony_ci    if (count != 0) {
187d9f0492fSopenharmony_ci        return 0;
188d9f0492fSopenharmony_ci    }
189d9f0492fSopenharmony_ci    // delete watcher
190d9f0492fSopenharmony_ci    int ret = watcherManager->DelWatcher(keyPrefix, remoteWatcherId_);
191d9f0492fSopenharmony_ci    WATCHER_CHECK(ret == 0, return -1, "Failed to delete watcher for %s", keyPrefix.c_str());
192d9f0492fSopenharmony_ci    {
193d9f0492fSopenharmony_ci        std::lock_guard<std::mutex> lock(mutex_);
194d9f0492fSopenharmony_ci        auto it = watchers_.find(keyPrefix); // delete watcher
195d9f0492fSopenharmony_ci        if (it != watchers_.end()) {
196d9f0492fSopenharmony_ci            watchers_.erase(it);
197d9f0492fSopenharmony_ci        }
198d9f0492fSopenharmony_ci        if (watchers_.empty()) { // no watcher, so delete remote agent
199d9f0492fSopenharmony_ci            watcherManager->DelRemoteWatcher(remoteWatcherId_);
200d9f0492fSopenharmony_ci            remoteWatcherId_ = 0;
201d9f0492fSopenharmony_ci            remoteWatcher_ = nullptr;
202d9f0492fSopenharmony_ci        }
203d9f0492fSopenharmony_ci    }
204d9f0492fSopenharmony_ci    return 0;
205d9f0492fSopenharmony_ci}
206d9f0492fSopenharmony_ci
207d9f0492fSopenharmony_ciWatcherManagerKits::ParameterChangeListener *WatcherManagerKits::ParamWatcher::GetParameterListener(uint32_t *idx)
208d9f0492fSopenharmony_ci{
209d9f0492fSopenharmony_ci    uint32_t index = *idx;
210d9f0492fSopenharmony_ci    if (parameterChangeListeners.empty()) {
211d9f0492fSopenharmony_ci        return nullptr;
212d9f0492fSopenharmony_ci    }
213d9f0492fSopenharmony_ci    while (index < listenerId_) {
214d9f0492fSopenharmony_ci        auto it = parameterChangeListeners.find(index);
215d9f0492fSopenharmony_ci        if (it != parameterChangeListeners.end()) {
216d9f0492fSopenharmony_ci            *idx = index;
217d9f0492fSopenharmony_ci            return parameterChangeListeners[index].get();
218d9f0492fSopenharmony_ci        }
219d9f0492fSopenharmony_ci        index++;
220d9f0492fSopenharmony_ci    }
221d9f0492fSopenharmony_ci    return nullptr;
222d9f0492fSopenharmony_ci}
223d9f0492fSopenharmony_ci
224d9f0492fSopenharmony_civoid WatcherManagerKits::ParamWatcher::RemoveParameterListener(uint32_t idx)
225d9f0492fSopenharmony_ci{
226d9f0492fSopenharmony_ci    auto it = parameterChangeListeners.find(idx);
227d9f0492fSopenharmony_ci    if (it != parameterChangeListeners.end()) {
228d9f0492fSopenharmony_ci        parameterChangeListeners.erase(it);
229d9f0492fSopenharmony_ci    }
230d9f0492fSopenharmony_ci}
231d9f0492fSopenharmony_ci
232d9f0492fSopenharmony_ciint WatcherManagerKits::ParamWatcher::AddParameterListener(ParameterChangePtr callback, void *context)
233d9f0492fSopenharmony_ci{
234d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
235d9f0492fSopenharmony_ci    WATCHER_CHECK(callback != nullptr, return -1, "Invalid callback ");
236d9f0492fSopenharmony_ci    WATCHER_LOGV("AddParameterListener %s listenerId_ %d", keyPrefix_.c_str(), listenerId_);
237d9f0492fSopenharmony_ci    for (auto it = parameterChangeListeners.begin(); it != parameterChangeListeners.end(); it++) {
238d9f0492fSopenharmony_ci        if (it->second == nullptr) {
239d9f0492fSopenharmony_ci            continue;
240d9f0492fSopenharmony_ci        }
241d9f0492fSopenharmony_ci        if (it->second->IsEqual(callback, context)) {
242d9f0492fSopenharmony_ci            return PARAM_WATCHER_CALLBACK_EXIST;
243d9f0492fSopenharmony_ci        }
244d9f0492fSopenharmony_ci    }
245d9f0492fSopenharmony_ci    std::shared_ptr<ParameterChangeListener> changeNode =
246d9f0492fSopenharmony_ci        std::make_shared<ParameterChangeListener>(callback, context);
247d9f0492fSopenharmony_ci    WATCHER_CHECK(changeNode != nullptr, return -1, "Failed to create listener");
248d9f0492fSopenharmony_ci    parameterChangeListeners[listenerId_] = changeNode;
249d9f0492fSopenharmony_ci    listenerId_++;
250d9f0492fSopenharmony_ci    return 0;
251d9f0492fSopenharmony_ci}
252d9f0492fSopenharmony_ci
253d9f0492fSopenharmony_ciint WatcherManagerKits::ParamWatcher::DelParameterListener(ParameterChangePtr callback, void *context)
254d9f0492fSopenharmony_ci{
255d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
256d9f0492fSopenharmony_ci    if (callback == nullptr) {
257d9f0492fSopenharmony_ci        parameterChangeListeners.clear();
258d9f0492fSopenharmony_ci        return 0;
259d9f0492fSopenharmony_ci    }
260d9f0492fSopenharmony_ci    uint32_t index = 0;
261d9f0492fSopenharmony_ci    ParameterChangeListener *listener = GetParameterListener(&index);
262d9f0492fSopenharmony_ci    while (listener != nullptr) {
263d9f0492fSopenharmony_ci        if (listener->IsEqual(callback, context)) {
264d9f0492fSopenharmony_ci            WATCHER_LOGV("DelParameterListener listenerId_ %d", index);
265d9f0492fSopenharmony_ci            RemoveParameterListener(index);
266d9f0492fSopenharmony_ci            break;
267d9f0492fSopenharmony_ci        }
268d9f0492fSopenharmony_ci        index++;
269d9f0492fSopenharmony_ci        listener = GetParameterListener(&index);
270d9f0492fSopenharmony_ci    }
271d9f0492fSopenharmony_ci    return static_cast<int>(parameterChangeListeners.size());
272d9f0492fSopenharmony_ci}
273d9f0492fSopenharmony_ci
274d9f0492fSopenharmony_civoid WatcherManagerKits::RemoteWatcher::OnParameterChange(
275d9f0492fSopenharmony_ci    const std::string &prefix, const std::string &name, const std::string &value)
276d9f0492fSopenharmony_ci{
277d9f0492fSopenharmony_ci    Watcher::OnParameterChange(prefix, name, value);
278d9f0492fSopenharmony_ci    // get param watcher
279d9f0492fSopenharmony_ci    WatcherManagerKits::ParamWatcher *watcher = watcherManager_->GetParamWatcher(prefix);
280d9f0492fSopenharmony_ci    WATCHER_CHECK(watcher != nullptr, return, "Failed to get watcher '%s'", prefix.c_str());
281d9f0492fSopenharmony_ci    if (watcher != nullptr) {
282d9f0492fSopenharmony_ci        watcher->OnParameterChange(name, value);
283d9f0492fSopenharmony_ci    }
284d9f0492fSopenharmony_ci}
285d9f0492fSopenharmony_ci
286d9f0492fSopenharmony_civoid WatcherManagerKits::ParamWatcher::OnParameterChange(const std::string &name, const std::string &value)
287d9f0492fSopenharmony_ci{
288d9f0492fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
289d9f0492fSopenharmony_ci    WATCHER_LOGV("OnParameterChange name %s value %s", name.c_str(), value.c_str());
290d9f0492fSopenharmony_ci    uint32_t index = 0;
291d9f0492fSopenharmony_ci    ParameterChangeListener *listener = GetParameterListener(&index);
292d9f0492fSopenharmony_ci    while (listener != nullptr) {
293d9f0492fSopenharmony_ci        if (!listener->CheckValueChange(name, value)) {
294d9f0492fSopenharmony_ci            listener->OnParameterChange(name, value);
295d9f0492fSopenharmony_ci        }
296d9f0492fSopenharmony_ci        index++;
297d9f0492fSopenharmony_ci        listener = GetParameterListener(&index);
298d9f0492fSopenharmony_ci    }
299d9f0492fSopenharmony_ci}
300d9f0492fSopenharmony_ci
301d9f0492fSopenharmony_civoid WatcherManagerKits::ParameterChangeListener::OnParameterChange(const std::string &name, const std::string &value)
302d9f0492fSopenharmony_ci{
303d9f0492fSopenharmony_ci    if (callback_ != nullptr) {
304d9f0492fSopenharmony_ci        callback_(name.c_str(), value.c_str(), context_);
305d9f0492fSopenharmony_ci    }
306d9f0492fSopenharmony_ci}
307d9f0492fSopenharmony_ci} // namespace init_param
308d9f0492fSopenharmony_ci} // namespace OHOS
309d9f0492fSopenharmony_ci
310d9f0492fSopenharmony_cistatic int PreHandleWatchParam(std::string &prefix)
311d9f0492fSopenharmony_ci{
312d9f0492fSopenharmony_ci    // clear space in head or tail
313d9f0492fSopenharmony_ci    prefix.erase(0, prefix.find_first_not_of(" "));
314d9f0492fSopenharmony_ci    prefix.erase(prefix.find_last_not_of(" ") + 1);
315d9f0492fSopenharmony_ci    WATCHER_CHECK(!prefix.empty(), return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
316d9f0492fSopenharmony_ci    int ret = 0;
317d9f0492fSopenharmony_ci    if (prefix.rfind(".*") == prefix.length() - 2) { // 2 last index
318d9f0492fSopenharmony_ci        ret = WatchParamCheck(prefix.substr(0, prefix.length() - 2).c_str()); // 2 last index
319d9f0492fSopenharmony_ci    } else if (prefix.rfind("*") == prefix.length() - 1) {
320d9f0492fSopenharmony_ci        ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
321d9f0492fSopenharmony_ci    } else if (prefix.rfind(".") == prefix.length() - 1) {
322d9f0492fSopenharmony_ci        ret = WatchParamCheck(prefix.substr(0, prefix.length() - 1).c_str());
323d9f0492fSopenharmony_ci    } else {
324d9f0492fSopenharmony_ci        ret = WatchParamCheck(prefix.c_str());
325d9f0492fSopenharmony_ci    }
326d9f0492fSopenharmony_ci    return ret;
327d9f0492fSopenharmony_ci}
328d9f0492fSopenharmony_ci
329d9f0492fSopenharmony_ciint SystemWatchParameter(const char *keyPrefix, ParameterChangePtr callback, void *context)
330d9f0492fSopenharmony_ci{
331d9f0492fSopenharmony_ci    WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
332d9f0492fSopenharmony_ci    std::string key(keyPrefix);
333d9f0492fSopenharmony_ci    int ret = PreHandleWatchParam(key);
334d9f0492fSopenharmony_ci    if (ret != 0) {
335d9f0492fSopenharmony_ci        return ret;
336d9f0492fSopenharmony_ci    }
337d9f0492fSopenharmony_ci    OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
338d9f0492fSopenharmony_ci    if (callback != nullptr) {
339d9f0492fSopenharmony_ci        ret = instance.AddWatcher(keyPrefix, callback, context);
340d9f0492fSopenharmony_ci    } else {
341d9f0492fSopenharmony_ci        ret = instance.DelWatcher(keyPrefix, nullptr, nullptr);
342d9f0492fSopenharmony_ci    }
343d9f0492fSopenharmony_ci
344d9f0492fSopenharmony_ci    if (ret != 0) {
345d9f0492fSopenharmony_ci        WATCHER_LOGE("SystemWatchParameter is failed! keyPrefix is:%s, errNum is:%d", keyPrefix, ret);
346d9f0492fSopenharmony_ci    }
347d9f0492fSopenharmony_ci    return ret;
348d9f0492fSopenharmony_ci}
349d9f0492fSopenharmony_ci
350d9f0492fSopenharmony_ciint RemoveParameterWatcher(const char *keyPrefix, ParameterChgPtr callback, void *context)
351d9f0492fSopenharmony_ci{
352d9f0492fSopenharmony_ci    WATCHER_CHECK(keyPrefix != nullptr, return PARAM_CODE_INVALID_PARAM, "Invalid prefix");
353d9f0492fSopenharmony_ci    std::string key(keyPrefix);
354d9f0492fSopenharmony_ci    int ret = PreHandleWatchParam(key);
355d9f0492fSopenharmony_ci    if (ret != 0) {
356d9f0492fSopenharmony_ci        return ret;
357d9f0492fSopenharmony_ci    }
358d9f0492fSopenharmony_ci    OHOS::init_param::WatcherManagerKits &instance = OHOS::init_param::WatcherManagerKits::GetInstance();
359d9f0492fSopenharmony_ci    ret = instance.DelWatcher(keyPrefix, (ParameterChangePtr)callback, context);
360d9f0492fSopenharmony_ci    if (ret != 0) {
361d9f0492fSopenharmony_ci        WATCHER_LOGE("RemoveParameterWatcher is failed! keyPrefix is:%s, errNum is:%d", keyPrefix, ret);
362d9f0492fSopenharmony_ci    }
363d9f0492fSopenharmony_ci    return ret;
364d9f0492fSopenharmony_ci}