1eace7efcSopenharmony_ci/*
2eace7efcSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3eace7efcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4eace7efcSopenharmony_ci * you may not use this file except in compliance with the License.
5eace7efcSopenharmony_ci * You may obtain a copy of the License at
6eace7efcSopenharmony_ci *
7eace7efcSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8eace7efcSopenharmony_ci *
9eace7efcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10eace7efcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11eace7efcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12eace7efcSopenharmony_ci * See the License for the specific language governing permissions and
13eace7efcSopenharmony_ci * limitations under the License.
14eace7efcSopenharmony_ci */
15eace7efcSopenharmony_ci
16eace7efcSopenharmony_ci#include <thread>
17eace7efcSopenharmony_ci#include "dataobs_mgr_client.h"
18eace7efcSopenharmony_ci
19eace7efcSopenharmony_ci#include "hilog_tag_wrapper.h"
20eace7efcSopenharmony_ci#include "if_system_ability_manager.h"
21eace7efcSopenharmony_ci#include "iservice_registry.h"
22eace7efcSopenharmony_ci#include "system_ability_definition.h"
23eace7efcSopenharmony_ci#include "system_ability_status_change_stub.h"
24eace7efcSopenharmony_ci
25eace7efcSopenharmony_cinamespace OHOS {
26eace7efcSopenharmony_cinamespace AAFwk {
27eace7efcSopenharmony_cistd::mutex DataObsMgrClient::mutex_;
28eace7efcSopenharmony_ci
29eace7efcSopenharmony_ciclass DataObsMgrClient::SystemAbilityStatusChangeListener
30eace7efcSopenharmony_ci    : public SystemAbilityStatusChangeStub {
31eace7efcSopenharmony_cipublic:
32eace7efcSopenharmony_ci    SystemAbilityStatusChangeListener()
33eace7efcSopenharmony_ci    {
34eace7efcSopenharmony_ci    }
35eace7efcSopenharmony_ci    ~SystemAbilityStatusChangeListener() = default;
36eace7efcSopenharmony_ci    void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override;
37eace7efcSopenharmony_ci    void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override
38eace7efcSopenharmony_ci    {
39eace7efcSopenharmony_ci    }
40eace7efcSopenharmony_ci};
41eace7efcSopenharmony_ci
42eace7efcSopenharmony_civoid DataObsMgrClient::SystemAbilityStatusChangeListener::OnAddSystemAbility(
43eace7efcSopenharmony_ci    int32_t systemAbilityId, const std::string &deviceId)
44eace7efcSopenharmony_ci{
45eace7efcSopenharmony_ci    TAG_LOGI(AAFwkTag::DBOBSMGR, "called");
46eace7efcSopenharmony_ci    if (systemAbilityId != DATAOBS_MGR_SERVICE_SA_ID) {
47eace7efcSopenharmony_ci        return;
48eace7efcSopenharmony_ci    }
49eace7efcSopenharmony_ci    GetInstance()->ReRegister();
50eace7efcSopenharmony_ci}
51eace7efcSopenharmony_ci
52eace7efcSopenharmony_cistd::shared_ptr<DataObsMgrClient> DataObsMgrClient::GetInstance()
53eace7efcSopenharmony_ci{
54eace7efcSopenharmony_ci    static std::shared_ptr<DataObsMgrClient> proxy = std::make_shared<DataObsMgrClient>();
55eace7efcSopenharmony_ci    return proxy;
56eace7efcSopenharmony_ci}
57eace7efcSopenharmony_ci
58eace7efcSopenharmony_ciDataObsMgrClient::DataObsMgrClient()
59eace7efcSopenharmony_ci{
60eace7efcSopenharmony_ci    callback_ = new SystemAbilityStatusChangeListener();
61eace7efcSopenharmony_ci}
62eace7efcSopenharmony_ci
63eace7efcSopenharmony_ciDataObsMgrClient::~DataObsMgrClient()
64eace7efcSopenharmony_ci{}
65eace7efcSopenharmony_ci
66eace7efcSopenharmony_ci/**
67eace7efcSopenharmony_ci * Registers an observer to DataObsMgr specified by the given Uri.
68eace7efcSopenharmony_ci *
69eace7efcSopenharmony_ci * @param uri, Indicates the path of the data to operate.
70eace7efcSopenharmony_ci * @param dataObserver, Indicates the IDataAbilityObserver object.
71eace7efcSopenharmony_ci *
72eace7efcSopenharmony_ci * @return Returns ERR_OK on success, others on failure.
73eace7efcSopenharmony_ci */
74eace7efcSopenharmony_ciErrCode DataObsMgrClient::RegisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
75eace7efcSopenharmony_ci{
76eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
77eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
78eace7efcSopenharmony_ci        return DATAOBS_SERVICE_NOT_CONNECTED;
79eace7efcSopenharmony_ci    }
80eace7efcSopenharmony_ci    auto status = dataObsManger->RegisterObserver(uri, dataObserver);
81eace7efcSopenharmony_ci    if (status != NO_ERROR) {
82eace7efcSopenharmony_ci        return status;
83eace7efcSopenharmony_ci    }
84eace7efcSopenharmony_ci    observers_.Compute(dataObserver, [&uri](const auto &key, auto &value) {
85eace7efcSopenharmony_ci        value.emplace_back(uri);
86eace7efcSopenharmony_ci        return true;
87eace7efcSopenharmony_ci    });
88eace7efcSopenharmony_ci    return status;
89eace7efcSopenharmony_ci}
90eace7efcSopenharmony_ci
91eace7efcSopenharmony_ci/**
92eace7efcSopenharmony_ci * Deregisters an observer used for DataObsMgr specified by the given Uri.
93eace7efcSopenharmony_ci *
94eace7efcSopenharmony_ci * @param uri, Indicates the path of the data to operate.
95eace7efcSopenharmony_ci * @param dataObserver, Indicates the IDataAbilityObserver object.
96eace7efcSopenharmony_ci *
97eace7efcSopenharmony_ci * @return Returns ERR_OK on success, others on failure.
98eace7efcSopenharmony_ci */
99eace7efcSopenharmony_ciErrCode DataObsMgrClient::UnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
100eace7efcSopenharmony_ci{
101eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
102eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
103eace7efcSopenharmony_ci        return DATAOBS_SERVICE_NOT_CONNECTED;
104eace7efcSopenharmony_ci    }
105eace7efcSopenharmony_ci    auto status = dataObsManger->UnregisterObserver(uri, dataObserver);
106eace7efcSopenharmony_ci    if (status != NO_ERROR) {
107eace7efcSopenharmony_ci        return status;
108eace7efcSopenharmony_ci    }
109eace7efcSopenharmony_ci    observers_.Compute(dataObserver, [&uri](const auto &key, auto &value) {
110eace7efcSopenharmony_ci        value.remove_if([&uri](const auto &val) {
111eace7efcSopenharmony_ci            return uri == val;
112eace7efcSopenharmony_ci        });
113eace7efcSopenharmony_ci        return !value.empty();
114eace7efcSopenharmony_ci    });
115eace7efcSopenharmony_ci    return status;
116eace7efcSopenharmony_ci}
117eace7efcSopenharmony_ci
118eace7efcSopenharmony_ci/**
119eace7efcSopenharmony_ci * Notifies the registered observers of a change to the data resource specified by Uri.
120eace7efcSopenharmony_ci *
121eace7efcSopenharmony_ci * @param uri, Indicates the path of the data to operate.
122eace7efcSopenharmony_ci *
123eace7efcSopenharmony_ci * @return Returns ERR_OK on success, others on failure.
124eace7efcSopenharmony_ci */
125eace7efcSopenharmony_ciErrCode DataObsMgrClient::NotifyChange(const Uri &uri)
126eace7efcSopenharmony_ci{
127eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
128eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
129eace7efcSopenharmony_ci        return DATAOBS_SERVICE_NOT_CONNECTED;
130eace7efcSopenharmony_ci    }
131eace7efcSopenharmony_ci    return dataObsManger->NotifyChange(uri);
132eace7efcSopenharmony_ci}
133eace7efcSopenharmony_ci
134eace7efcSopenharmony_ci/**
135eace7efcSopenharmony_ci * Connect dataobs manager service.
136eace7efcSopenharmony_ci *
137eace7efcSopenharmony_ci * @return Returns SUCCESS on success, others on failure.
138eace7efcSopenharmony_ci */
139eace7efcSopenharmony_ci__attribute__ ((no_sanitize("cfi"))) std::pair<Status, sptr<IDataObsMgr>> DataObsMgrClient::GetObsMgr()
140eace7efcSopenharmony_ci{
141eace7efcSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
142eace7efcSopenharmony_ci
143eace7efcSopenharmony_ci    if (dataObsManger_ != nullptr) {
144eace7efcSopenharmony_ci        return std::make_pair(SUCCESS, dataObsManger_);
145eace7efcSopenharmony_ci    }
146eace7efcSopenharmony_ci
147eace7efcSopenharmony_ci    sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
148eace7efcSopenharmony_ci    if (systemManager == nullptr) {
149eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::DBOBSMGR, "registry failed");
150eace7efcSopenharmony_ci        return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr);
151eace7efcSopenharmony_ci    }
152eace7efcSopenharmony_ci
153eace7efcSopenharmony_ci    auto remoteObject = systemManager->CheckSystemAbility(DATAOBS_MGR_SERVICE_SA_ID);
154eace7efcSopenharmony_ci    if (remoteObject == nullptr) {
155eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::DBOBSMGR, "systemAbility failed");
156eace7efcSopenharmony_ci        return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr);
157eace7efcSopenharmony_ci    }
158eace7efcSopenharmony_ci
159eace7efcSopenharmony_ci    dataObsManger_ = iface_cast<IDataObsMgr>(remoteObject);
160eace7efcSopenharmony_ci    if (dataObsManger_ == nullptr) {
161eace7efcSopenharmony_ci        TAG_LOGE(AAFwkTag::DBOBSMGR, "iDataObsMgr failed");
162eace7efcSopenharmony_ci        return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr);
163eace7efcSopenharmony_ci    }
164eace7efcSopenharmony_ci    sptr<ServiceDeathRecipient> serviceDeathRecipient(new (std::nothrow) ServiceDeathRecipient(GetInstance()));
165eace7efcSopenharmony_ci    dataObsManger_->AsObject()->AddDeathRecipient(serviceDeathRecipient);
166eace7efcSopenharmony_ci    return std::make_pair(SUCCESS, dataObsManger_);
167eace7efcSopenharmony_ci}
168eace7efcSopenharmony_ci
169eace7efcSopenharmony_ciStatus DataObsMgrClient::RegisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver,
170eace7efcSopenharmony_ci    bool isDescendants)
171eace7efcSopenharmony_ci{
172eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
173eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
174eace7efcSopenharmony_ci        return DATAOBS_SERVICE_NOT_CONNECTED;
175eace7efcSopenharmony_ci    }
176eace7efcSopenharmony_ci    auto status = dataObsManger->RegisterObserverExt(uri, dataObserver, isDescendants);
177eace7efcSopenharmony_ci    if (status != SUCCESS) {
178eace7efcSopenharmony_ci        return status;
179eace7efcSopenharmony_ci    }
180eace7efcSopenharmony_ci    observerExts_.Compute(dataObserver, [&uri, isDescendants](const auto &key, auto &value) {
181eace7efcSopenharmony_ci        value.emplace_back(uri, isDescendants);
182eace7efcSopenharmony_ci        return true;
183eace7efcSopenharmony_ci    });
184eace7efcSopenharmony_ci    return status;
185eace7efcSopenharmony_ci}
186eace7efcSopenharmony_ci
187eace7efcSopenharmony_ciStatus DataObsMgrClient::UnregisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
188eace7efcSopenharmony_ci{
189eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
190eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
191eace7efcSopenharmony_ci        return DATAOBS_SERVICE_NOT_CONNECTED;
192eace7efcSopenharmony_ci    }
193eace7efcSopenharmony_ci    auto status = dataObsManger->UnregisterObserverExt(uri, dataObserver);
194eace7efcSopenharmony_ci    if (status != SUCCESS) {
195eace7efcSopenharmony_ci        return status;
196eace7efcSopenharmony_ci    }
197eace7efcSopenharmony_ci    observerExts_.Compute(dataObserver, [&uri](const auto &key, auto &value) {
198eace7efcSopenharmony_ci        value.remove_if([&uri](const auto &param) {
199eace7efcSopenharmony_ci            return uri == param.uri;
200eace7efcSopenharmony_ci        });
201eace7efcSopenharmony_ci        return !value.empty();
202eace7efcSopenharmony_ci    });
203eace7efcSopenharmony_ci    return status;
204eace7efcSopenharmony_ci}
205eace7efcSopenharmony_ci
206eace7efcSopenharmony_ciStatus DataObsMgrClient::UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver)
207eace7efcSopenharmony_ci{
208eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
209eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
210eace7efcSopenharmony_ci        return DATAOBS_SERVICE_NOT_CONNECTED;
211eace7efcSopenharmony_ci    }
212eace7efcSopenharmony_ci    auto status = dataObsManger->UnregisterObserverExt(dataObserver);
213eace7efcSopenharmony_ci    if (status != SUCCESS) {
214eace7efcSopenharmony_ci        return status;
215eace7efcSopenharmony_ci    }
216eace7efcSopenharmony_ci    observerExts_.Erase(dataObserver);
217eace7efcSopenharmony_ci    return status;
218eace7efcSopenharmony_ci}
219eace7efcSopenharmony_ci
220eace7efcSopenharmony_ciStatus DataObsMgrClient::NotifyChangeExt(const ChangeInfo &changeInfo)
221eace7efcSopenharmony_ci{
222eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
223eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
224eace7efcSopenharmony_ci        return DATAOBS_SERVICE_NOT_CONNECTED;
225eace7efcSopenharmony_ci    }
226eace7efcSopenharmony_ci    return dataObsManger->NotifyChangeExt(changeInfo);
227eace7efcSopenharmony_ci}
228eace7efcSopenharmony_ci
229eace7efcSopenharmony_civoid DataObsMgrClient::ResetService()
230eace7efcSopenharmony_ci{
231eace7efcSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
232eace7efcSopenharmony_ci    dataObsManger_ = nullptr;
233eace7efcSopenharmony_ci}
234eace7efcSopenharmony_ci
235eace7efcSopenharmony_civoid DataObsMgrClient::OnRemoteDied()
236eace7efcSopenharmony_ci{
237eace7efcSopenharmony_ci    std::this_thread::sleep_for(std::chrono::seconds(RESUB_INTERVAL));
238eace7efcSopenharmony_ci    ResetService();
239eace7efcSopenharmony_ci    auto [errCode, dataObsManger] = GetObsMgr();
240eace7efcSopenharmony_ci    if (errCode != SUCCESS) {
241eace7efcSopenharmony_ci        sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
242eace7efcSopenharmony_ci        if (systemManager == nullptr) {
243eace7efcSopenharmony_ci            TAG_LOGE(AAFwkTag::DBOBSMGR, "null systemmgr");
244eace7efcSopenharmony_ci            return;
245eace7efcSopenharmony_ci        }
246eace7efcSopenharmony_ci        systemManager->SubscribeSystemAbility(DATAOBS_MGR_SERVICE_SA_ID, callback_);
247eace7efcSopenharmony_ci        return;
248eace7efcSopenharmony_ci    }
249eace7efcSopenharmony_ci    ReRegister();
250eace7efcSopenharmony_ci}
251eace7efcSopenharmony_ci
252eace7efcSopenharmony_civoid DataObsMgrClient::ReRegister()
253eace7efcSopenharmony_ci{
254eace7efcSopenharmony_ci    decltype(observers_) observers(std::move(observers_));
255eace7efcSopenharmony_ci    observers_.Clear();
256eace7efcSopenharmony_ci    observers.ForEach([this](const auto &key, const auto &value) {
257eace7efcSopenharmony_ci        for (const auto &uri : value) {
258eace7efcSopenharmony_ci            RegisterObserver(uri, key);
259eace7efcSopenharmony_ci        }
260eace7efcSopenharmony_ci        return false;
261eace7efcSopenharmony_ci    });
262eace7efcSopenharmony_ci
263eace7efcSopenharmony_ci    decltype(observerExts_) observerExts(std::move(observerExts_));
264eace7efcSopenharmony_ci    observerExts_.Clear();
265eace7efcSopenharmony_ci    observerExts.ForEach([this](const auto &key, const auto &value) {
266eace7efcSopenharmony_ci        for (const auto &param : value) {
267eace7efcSopenharmony_ci            RegisterObserverExt(param.uri, key, param.isDescendants);
268eace7efcSopenharmony_ci        }
269eace7efcSopenharmony_ci        return false;
270eace7efcSopenharmony_ci    });
271eace7efcSopenharmony_ci}
272eace7efcSopenharmony_ci}  // namespace AAFwk
273eace7efcSopenharmony_ci}  // namespace OHOS
274