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