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