1 /*
2 * Copyright (c) 2023 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 "general_controller_service_impl.h"
17 #include <thread>
18
19 #include "block_data.h"
20 #include "datashare_common.h"
21 #include "dataobs_mgr_client.h"
22 #include "dataobs_mgr_errors.h"
23 #include "datashare_log.h"
24 #include "datashare_string_utils.h"
25
26 namespace OHOS {
27 namespace DataShare {
GeneralControllerServiceImpl(const std::string & ext)28 GeneralControllerServiceImpl::GeneralControllerServiceImpl(const std::string &ext)
29 {
30 extUri_ = ext;
31 pool_ = std::make_shared<ExecutorPool>(MAX_THREADS, MIN_THREADS, DATASHARE_EXECUTOR_NAME);
32 }
33
~GeneralControllerServiceImpl()34 GeneralControllerServiceImpl::~GeneralControllerServiceImpl()
35 {
36 auto manager = DataShareManagerImpl::GetInstance();
37 manager->RemoveRegisterCallback(this);
38 }
39
Insert(const Uri & uri,const DataShareValuesBucket & value)40 int GeneralControllerServiceImpl::Insert(const Uri &uri, const DataShareValuesBucket &value)
41 {
42 auto manager = DataShareManagerImpl::GetInstance();
43 if (manager == nullptr) {
44 LOG_ERROR("Manager is nullptr");
45 return DATA_SHARE_ERROR;
46 }
47 // the ret of SetCallCount indicates whether the current call exceeds the access threshold, true means excced
48 if (manager->SetCallCount(__FUNCTION__, uri.ToString())) {
49 return DATA_SHARE_ERROR;
50 }
51 auto proxy = DataShareManagerImpl::GetServiceProxy();
52 if (proxy == nullptr) {
53 LOG_ERROR("proxy is nullptr");
54 return DATA_SHARE_ERROR;
55 }
56 return proxy->Insert(uri, Uri(extUri_), value);
57 }
58
Update(const Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value)59 int GeneralControllerServiceImpl::Update(const Uri &uri, const DataSharePredicates &predicates,
60 const DataShareValuesBucket &value)
61 {
62 auto manager = DataShareManagerImpl::GetInstance();
63 if (manager == nullptr) {
64 LOG_ERROR("Manager is nullptr");
65 return DATA_SHARE_ERROR;
66 }
67 // the ret of SetCallCount indicates whether the current call exceeds the access threshold, true means excced
68 if (manager->SetCallCount(__FUNCTION__, uri.ToString())) {
69 return DATA_SHARE_ERROR;
70 }
71 auto proxy = DataShareManagerImpl::GetServiceProxy();
72 if (proxy == nullptr) {
73 LOG_ERROR("proxy is nullptr");
74 return DATA_SHARE_ERROR;
75 }
76 return proxy->Update(uri, Uri(extUri_), predicates, value);
77 }
78
Delete(const Uri & uri,const DataSharePredicates & predicates)79 int GeneralControllerServiceImpl::Delete(const Uri &uri, const DataSharePredicates &predicates)
80 {
81 auto manager = DataShareManagerImpl::GetInstance();
82 if (manager == nullptr) {
83 LOG_ERROR("Manager is nullptr");
84 return DATA_SHARE_ERROR;
85 }
86 // the ret of SetCallCount indicates whether the current call exceeds the access threshold, true means excced
87 if (manager->SetCallCount(__FUNCTION__, uri.ToString())) {
88 return DATA_SHARE_ERROR;
89 }
90 auto proxy = DataShareManagerImpl::GetServiceProxy();
91 if (proxy == nullptr) {
92 LOG_ERROR("proxy is nullptr");
93 return DATA_SHARE_ERROR;
94 }
95 return proxy->Delete(uri, Uri(extUri_), predicates);
96 }
97
InsertEx(const Uri & uri,const DataShareValuesBucket & value)98 std::pair<int32_t, int32_t> GeneralControllerServiceImpl::InsertEx(const Uri &uri, const DataShareValuesBucket &value)
99 {
100 auto manager = DataShareManagerImpl::GetInstance();
101 if (manager == nullptr) {
102 LOG_ERROR("Manager is nullptr");
103 return std::make_pair(DATA_SHARE_ERROR, 0);
104 }
105 // the ret of SetCallCount indicates whether the current call exceeds the access threshold, true means excced
106 if (manager->SetCallCount(__FUNCTION__, uri.ToString())) {
107 return std::make_pair(DATA_SHARE_ERROR, 0);
108 }
109 auto proxy = DataShareManagerImpl::GetServiceProxy();
110 if (proxy == nullptr) {
111 LOG_ERROR("proxy is nullptr");
112 return std::make_pair(DATA_SHARE_ERROR, 0);
113 }
114 return proxy->InsertEx(uri, Uri(extUri_), value);
115 }
116
UpdateEx(const Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value)117 std::pair<int32_t, int32_t> GeneralControllerServiceImpl::UpdateEx(
118 const Uri &uri, const DataSharePredicates &predicates, const DataShareValuesBucket &value)
119 {
120 auto manager = DataShareManagerImpl::GetInstance();
121 if (manager == nullptr) {
122 LOG_ERROR("Manager is nullptr");
123 return std::make_pair(DATA_SHARE_ERROR, 0);
124 }
125 // the ret of SetCallCount indicates whether the current call exceeds the access threshold, true means excced
126 if (manager->SetCallCount(__FUNCTION__, uri.ToString())) {
127 return std::make_pair(DATA_SHARE_ERROR, 0);
128 }
129 auto proxy = DataShareManagerImpl::GetServiceProxy();
130 if (proxy == nullptr) {
131 LOG_ERROR("proxy is nullptr");
132 return std::make_pair(DATA_SHARE_ERROR, 0);
133 }
134 return proxy->UpdateEx(uri, Uri(extUri_), predicates, value);
135 }
136
DeleteEx(const Uri & uri,const DataSharePredicates & predicates)137 std::pair<int32_t, int32_t> GeneralControllerServiceImpl::DeleteEx(const Uri &uri,
138 const DataSharePredicates &predicates)
139 {
140 auto manager = DataShareManagerImpl::GetInstance();
141 if (manager == nullptr) {
142 LOG_ERROR("Manager is nullptr");
143 return std::make_pair(DATA_SHARE_ERROR, 0);
144 }
145 // the ret of SetCallCount indicates whether the current call exceeds the access threshold, true means excced
146 if (manager->SetCallCount(__FUNCTION__, uri.ToString())) {
147 return std::make_pair(DATA_SHARE_ERROR, 0);
148 }
149 auto proxy = DataShareManagerImpl::GetServiceProxy();
150 if (proxy == nullptr) {
151 LOG_ERROR("proxy is nullptr");
152 return std::make_pair(DATA_SHARE_ERROR, 0);
153 }
154 return proxy->DeleteEx(uri, Uri(extUri_), predicates);
155 }
156
Query(const Uri & uri,const DataSharePredicates & predicates,std::vector<std::string> & columns,DatashareBusinessError & businessError,DataShareOption & option)157 std::shared_ptr<DataShareResultSet> GeneralControllerServiceImpl::Query(const Uri &uri,
158 const DataSharePredicates &predicates, std::vector<std::string> &columns,
159 DatashareBusinessError &businessError, DataShareOption &option)
160 {
161 auto manager = DataShareManagerImpl::GetInstance();
162 if (manager == nullptr) {
163 LOG_ERROR("Manager is nullptr");
164 return nullptr;
165 }
166 // the ret of SetCallCount indicates whether the current call exceeds the access threshold, true means excced
167 if (manager->SetCallCount(__FUNCTION__, uri.ToString())) {
168 return nullptr;
169 }
170 auto proxy = DataShareManagerImpl::GetServiceProxy();
171 if (proxy == nullptr) {
172 LOG_ERROR("proxy is nullptr");
173 return nullptr;
174 }
175
176 if (option.timeout > 0) {
177 UriInfo uriInfo = {
178 .uri = uri.ToString(),
179 .extUri = extUri_,
180 .option = { .timeout = option.timeout },
181 };
182
183 auto [resultSet, err] = TimedQuery(proxy, uriInfo, predicates, columns);
184 businessError = err;
185 return resultSet;
186 }
187
188 auto resultSet = proxy->Query(uri, Uri(extUri_), predicates, columns, businessError);
189 int retryCount = 0;
190 while (resultSet == nullptr && businessError.GetCode() == E_RESULTSET_BUSY && retryCount++ < MAX_RETRY_COUNT) {
191 LOG_ERROR("resultSet busy retry, uri: %{public}s", DataShareStringUtils::Anonymous(uri.ToString()).c_str());
192 std::this_thread::sleep_for(std::chrono::milliseconds(
193 DataShareStringUtils::GetRandomNumber(RANDOM_MIN, RANDOM_MAX)));
194 resultSet = proxy->Query(uri, Uri(extUri_), predicates, columns, businessError);
195 }
196 return resultSet;
197 }
198
RegisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)199 int GeneralControllerServiceImpl::RegisterObserver(const Uri &uri,
200 const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
201 {
202 auto manager = DataShareManagerImpl::GetInstance();
203 if (manager == nullptr) {
204 LOG_ERROR("Manager is nullptr");
205 return E_DATA_SHARE_NOT_READY;
206 }
207 manager->SetCallCount(__FUNCTION__, uri.ToString());
208 auto obsMgrClient = OHOS::AAFwk::DataObsMgrClient::GetInstance();
209 if (obsMgrClient == nullptr) {
210 LOG_ERROR("get DataObsMgrClient failed");
211 return E_DATA_OBS_NOT_READY;
212 }
213 bool isSystem = DataShareServiceProxy::IsSystem();
214 ErrCode ret = obsMgrClient->RegisterObserver(uri, dataObserver, -1, AAFwk::DataObsOption(isSystem));
215 LOG_INFO("Register silent observer ret: %{public}d, uri: %{public}s", ret,
216 DataShareStringUtils::Anonymous(uri.ToString()).c_str());
217 return ret;
218 }
219
UnregisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)220 int GeneralControllerServiceImpl::UnregisterObserver(const Uri &uri,
221 const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
222 {
223 auto obsMgrClient = OHOS::AAFwk::DataObsMgrClient::GetInstance();
224 if (obsMgrClient == nullptr) {
225 LOG_ERROR("get DataObsMgrClient failed");
226 return E_DATA_OBS_NOT_READY;
227 }
228 bool isSystem = DataShareServiceProxy::IsSystem();
229 ErrCode ret = obsMgrClient->UnregisterObserver(uri, dataObserver, -1, AAFwk::DataObsOption(isSystem));
230 LOG_INFO("Unregister silent observer ret: %{public}d, uri: %{public}s", ret,
231 DataShareStringUtils::Anonymous(uri.ToString()).c_str());
232 return ret;
233 }
234
NotifyChange(const Uri & uri)235 void GeneralControllerServiceImpl::NotifyChange(const Uri &uri)
236 {
237 auto proxy = DataShareManagerImpl::GetServiceProxy();
238 if (proxy == nullptr) {
239 LOG_ERROR("proxy is nullptr");
240 return;
241 }
242 proxy->Notify(uri.ToString());
243 }
244
245 // This function is supported only when using non-silent DataShareHelper
RegisterObserverExtProvider(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver,bool isDescendants)246 int GeneralControllerServiceImpl::RegisterObserverExtProvider(const Uri &uri,
247 const sptr<AAFwk::IDataAbilityObserver> &dataObserver, bool isDescendants)
248 {
249 return DATA_SHARE_ERROR;
250 }
251
252 // This function is supported only when using non-silent DataShareHelper
UnregisterObserverExtProvider(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)253 int GeneralControllerServiceImpl::UnregisterObserverExtProvider(const Uri &uri,
254 const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
255 {
256 return DATA_SHARE_ERROR;
257 }
258
259 // This function is supported only when using non-silent DataShareHelper
NotifyChangeExtProvider(const ChangeInfo & changeInfo)260 int GeneralControllerServiceImpl::NotifyChangeExtProvider(const ChangeInfo &changeInfo)
261 {
262 return DATA_SHARE_ERROR;
263 }
264
SetRegisterCallback()265 void GeneralControllerServiceImpl::SetRegisterCallback()
266 {
267 auto manager = DataShareManagerImpl::GetInstance();
268 if (manager == nullptr) {
269 LOG_ERROR("Manager is nullptr");
270 return;
271 }
272 auto registerCallback = [this]() {
273 ReRegisterObserver();
274 };
275 manager->SetRegisterCallback(this, registerCallback);
276 }
277
ReRegisterObserver()278 void GeneralControllerServiceImpl::ReRegisterObserver()
279 {
280 LOG_INFO("Distributeddata service on start, reRegister observer.");
281 decltype(observers_) observers(std::move(observers_));
282 observers_.Clear();
283 observers.ForEach([this](const auto &key, const auto &value) {
284 for (const auto &uri : value) {
285 RegisterObserver(uri, key);
286 }
287 return false;
288 });
289 }
290
TimedQuery(std::shared_ptr<DataShareServiceProxy> proxy,const UriInfo & uriInfo,const DataSharePredicates & predicates,const std::vector<std::string> & columns)291 std::pair<std::shared_ptr<DataShareResultSet>, DatashareBusinessError> GeneralControllerServiceImpl::TimedQuery(
292 std::shared_ptr<DataShareServiceProxy> proxy, const UriInfo &uriInfo,
293 const DataSharePredicates &predicates, const std::vector<std::string> &columns)
294 {
295 DatashareBusinessError businessError;
296 if (pool_ == nullptr) {
297 LOG_ERROR("pool is nullptr");
298 businessError.SetCode(E_EXECUTOR_POOL_IS_NULL);
299 businessError.SetMessage("pool is nullptr");
300 return std::make_pair(nullptr, businessError);
301 }
302
303 auto timedQueryResult = std::make_shared<OHOS::BlockData<TimedQueryResult, std::chrono::milliseconds>>(
304 uriInfo.option.timeout, TimedQueryResult{false, DatashareBusinessError(), nullptr});
305
306 auto task = [proxy, uriInfo, predicates, columns, timedQueryResult]() {
307 DatashareBusinessError businessError;
308 auto ncolumns = columns;
309 auto resultSet = proxy->Query(Uri(uriInfo.uri), Uri(uriInfo.extUri), predicates,
310 ncolumns, businessError);
311 int retryCount = 0;
312 while (resultSet == nullptr && businessError.GetCode() == E_RESULTSET_BUSY && retryCount++ < MAX_RETRY_COUNT) {
313 LOG_ERROR("resultSet busy retry, uri: %{public}s", DataShareStringUtils::Anonymous(uriInfo.uri).c_str());
314 std::this_thread::sleep_for(std::chrono::milliseconds(
315 DataShareStringUtils::GetRandomNumber(RANDOM_MIN, RANDOM_MAX)));
316 resultSet = proxy->Query(Uri(uriInfo.uri), Uri(uriInfo.extUri), predicates,
317 ncolumns, businessError);
318 }
319
320 timedQueryResult->SetValue(TimedQueryResult{true, businessError, std::move(resultSet)});
321 };
322 auto taskId = pool_->Execute(task);
323 auto res = timedQueryResult->GetValue();
324 if (!res.isFinish_) {
325 LOG_ERROR("query time out, waited time: %{public}d, uri: %{public}s", uriInfo.option.timeout,
326 DataShareStringUtils::Anonymous(uriInfo.uri).c_str());
327 pool_->Remove(taskId);
328 businessError.SetCode(E_TIMEOUT_ERROR);
329 businessError.SetMessage("query time out");
330 return std::make_pair(nullptr, businessError);
331 }
332 return std::make_pair(res.resultSet_, res.businessError_);
333 }
334 } // namespace DataShare
335 } // namespace OHOS