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