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 ¶m) {
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 ¶m : value) {
267 RegisterObserverExt(param.uri, key, param.isDescendants);
268 }
269 return false;
270 });
271 }
272 } // namespace AAFwk
273 } // namespace OHOS
274