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