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 ¶m) {
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 ¶m : value) {
273 RegisterObserverExt(param.uri, key, param.isDescendants);
274 }
275 return false;
276 });
277 }
278 } // namespace AAFwk
279 } // namespace OHOS
280