1 /*
2 * Copyright (c) 2022 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 "datashare_stub_impl.h"
17 #include <memory>
18
19 #include "accesstoken_kit.h"
20 #include "datashare_log.h"
21 #include "datashare_string_utils.h"
22 #include "ipc_skeleton.h"
23
24 namespace OHOS {
25 namespace DataShare {
26 using OHOS::Security::AccessToken::AccessTokenKit;
27
28 constexpr int DEFAULT_NUMBER = -1;
29 constexpr int PERMISSION_ERROR_NUMBER = -2;
GetOwner()30 std::shared_ptr<JsDataShareExtAbility> DataShareStubImpl::GetOwner()
31 {
32 if (extension_ == nullptr) {
33 LOG_ERROR("extension_ is nullptr.");
34 }
35 return extension_;
36 }
37
CheckCallingPermission(const std::string & permission)38 bool DataShareStubImpl::CheckCallingPermission(const std::string &permission)
39 {
40 if (!permission.empty() && AccessTokenKit::VerifyAccessToken(IPCSkeleton::GetCallingTokenID(), permission)
41 != AppExecFwk::Constants::PERMISSION_GRANTED) {
42 LOG_ERROR("permission not granted.");
43 return false;
44 }
45 return true;
46 }
47
GetFileTypes(const Uri & uri,const std::string & mimeTypeFilter)48 std::vector<std::string> DataShareStubImpl::GetFileTypes(const Uri &uri, const std::string &mimeTypeFilter)
49 {
50 CallingInfo info;
51 GetCallingInfo(info);
52 std::vector<std::string> ret;
53 auto client = sptr<DataShareStubImpl>(this);
54 auto extension = client->GetOwner();
55 if (extension == nullptr) {
56 return ret;
57 }
58 auto result = std::make_shared<JsResult>();
59 std::function<void()> syncTaskFunc = [extension, info, uri, mimeTypeFilter, result]() {
60 extension->SetCallingInfo(info);
61 extension->InitResult(result);
62 extension->GetFileTypes(uri, mimeTypeFilter);
63 };
64 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
65 if (result == nullptr) {
66 return false;
67 }
68 bool isRecvReply = result->GetRecvReply();
69 result->GetResult(ret);
70 return isRecvReply;
71 };
72 std::lock_guard<std::mutex> lock(mutex_);
73 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
74 return ret;
75 }
76
OpenFile(const Uri & uri,const std::string & mode)77 int DataShareStubImpl::OpenFile(const Uri &uri, const std::string &mode)
78 {
79 CallingInfo info;
80 GetCallingInfo(info);
81 auto client = sptr<DataShareStubImpl>(this);
82 auto extension = client->GetOwner();
83 if (extension == nullptr) {
84 return DEFAULT_NUMBER;
85 }
86 auto result = std::make_shared<JsResult>();
87 int ret = -1;
88 std::function<void()> syncTaskFunc = [extension, info, uri, mode, result]() {
89 extension->SetCallingInfo(info);
90 extension->InitResult(result);
91 extension->OpenFile(uri, mode);
92 };
93 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
94 if (result == nullptr) {
95 return false;
96 }
97 bool isRecvReply = result->GetRecvReply();
98 result->GetResult(ret);
99 return isRecvReply;
100 };
101 std::lock_guard<std::mutex> lock(mutex_);
102 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
103 return ret;
104 }
105
OpenRawFile(const Uri & uri,const std::string & mode)106 int DataShareStubImpl::OpenRawFile(const Uri &uri, const std::string &mode)
107 {
108 CallingInfo info;
109 GetCallingInfo(info);
110 auto client = sptr<DataShareStubImpl>(this);
111 auto extension = client->GetOwner();
112 if (extension == nullptr) {
113 return DEFAULT_NUMBER;
114 }
115
116 std::shared_ptr<int> ret = std::make_shared<int>(-1);
117 std::function<void()> syncTaskFunc = [extension, ret, info, uri, mode]() {
118 extension->SetCallingInfo(info);
119 *ret = extension->OpenRawFile(uri, mode);
120 };
121 std::lock_guard<std::mutex> lock(mutex_);
122 uvQueue_->SyncCall(syncTaskFunc);
123 return *ret;
124 }
125
Insert(const Uri & uri,const DataShareValuesBucket & value)126 int DataShareStubImpl::Insert(const Uri &uri, const DataShareValuesBucket &value)
127 {
128 CallingInfo info;
129 GetCallingInfo(info);
130
131 auto client = sptr<DataShareStubImpl>(this);
132 auto extension = client->GetOwner();
133 if (extension == nullptr) {
134 return DEFAULT_NUMBER;
135 }
136
137 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
138 LOG_ERROR("Check calling permission failed.");
139 return PERMISSION_ERROR_NUMBER;
140 }
141
142 auto result = std::make_shared<JsResult>();
143 int ret = 0;
144 std::function<void()> syncTaskFunc = [extension, info, uri, value, result]() {
145 extension->SetCallingInfo(info);
146 extension->InitResult(result);
147 extension->Insert(uri, value);
148 };
149 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
150 if (result == nullptr) {
151 return false;
152 }
153 bool isRecvReply = result->GetRecvReply();
154 result->GetResult(ret);
155 return isRecvReply;
156 };
157 std::lock_guard<std::mutex> lock(mutex_);
158 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
159 return ret;
160 }
161
Update(const Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value)162 int DataShareStubImpl::Update(const Uri &uri, const DataSharePredicates &predicates,
163 const DataShareValuesBucket &value)
164 {
165 CallingInfo info;
166 GetCallingInfo(info);
167
168 auto client = sptr<DataShareStubImpl>(this);
169 auto extension = client->GetOwner();
170 if (extension == nullptr) {
171 return DEFAULT_NUMBER;
172 }
173
174 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
175 LOG_ERROR("Check calling permission failed.");
176 return PERMISSION_ERROR_NUMBER;
177 }
178
179 auto result = std::make_shared<JsResult>();
180 int ret = 0;
181 std::function<void()> syncTaskFunc = [extension, info, uri, predicates, value, result]() {
182 extension->SetCallingInfo(info);
183 extension->InitResult(result);
184 extension->Update(uri, predicates, value);
185 };
186 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
187 if (result == nullptr) {
188 return false;
189 }
190 bool isRecvReply = result->GetRecvReply();
191 result->GetResult(ret);
192 return isRecvReply;
193 };
194 std::lock_guard<std::mutex> lock(mutex_);
195 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
196 return ret;
197 }
198
BatchUpdate(const UpdateOperations & operations,std::vector<BatchUpdateResult> & results)199 int DataShareStubImpl::BatchUpdate(const UpdateOperations &operations, std::vector<BatchUpdateResult> &results)
200 {
201 CallingInfo info;
202 GetCallingInfo(info);
203 auto client = sptr<DataShareStubImpl>(this);
204 auto extension = client->GetOwner();
205 if (extension == nullptr) {
206 return DEFAULT_NUMBER;
207 }
208 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
209 LOG_ERROR("Check calling permission failed.");
210 return PERMISSION_ERROR_NUMBER;
211 }
212 auto result = std::make_shared<JsResult>();
213 int ret = 0;
214 std::function<void()> syncTaskFunc = [extension, operations, info, result]() {
215 extension->SetCallingInfo(info);
216 extension->InitResult(result);
217 std::vector<BatchUpdateResult> tmp;
218 extension->BatchUpdate(operations, tmp);
219 };
220 std::function<bool()> getRetFunc = [&results, result, &ret]() -> bool {
221 if (result == nullptr) {
222 return false;
223 }
224 bool isRecvReply = result->GetRecvReply();
225 result->GetResult(results);
226 result->GetResult(ret);
227 return isRecvReply;
228 };
229 std::lock_guard<std::mutex> lock(mutex_);
230 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
231 return ret;
232 }
233
Delete(const Uri & uri,const DataSharePredicates & predicates)234 int DataShareStubImpl::Delete(const Uri &uri, const DataSharePredicates &predicates)
235 {
236 CallingInfo info;
237 GetCallingInfo(info);
238
239 auto client = sptr<DataShareStubImpl>(this);
240 auto extension = client->GetOwner();
241 if (extension == nullptr) {
242 return DEFAULT_NUMBER;
243 }
244
245 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
246 LOG_ERROR("Check calling permission failed.");
247 return PERMISSION_ERROR_NUMBER;
248 }
249
250 auto result = std::make_shared<JsResult>();
251 int ret = 0;
252 std::function<void()> syncTaskFunc = [extension, info, uri, predicates, result]() {
253 extension->SetCallingInfo(info);
254 extension->InitResult(result);
255 extension->Delete(uri, predicates);
256 };
257 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
258 if (result == nullptr) {
259 return false;
260 }
261 bool isRecvReply = result->GetRecvReply();
262 result->GetResult(ret);
263 return isRecvReply;
264 };
265 std::lock_guard<std::mutex> lock(mutex_);
266 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
267 return ret;
268 }
269
InsertEx(const Uri & uri,const DataShareValuesBucket & value)270 std::pair<int32_t, int32_t> DataShareStubImpl::InsertEx(const Uri &uri, const DataShareValuesBucket &value)
271 {
272 CallingInfo info;
273 GetCallingInfo(info);
274
275 auto client = sptr<DataShareStubImpl>(this);
276 auto extension = client->GetOwner();
277 if (extension == nullptr) {
278 return std::make_pair(DATA_SHARE_ERROR, 0);
279 }
280
281 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
282 LOG_ERROR("Check calling permission failed.");
283 return std::make_pair(PERMISSION_ERROR_NUMBER, 0);
284 }
285
286 auto result = std::make_shared<JsResult>();
287 int ret = 0;
288 std::function<void()> syncTaskFunc = [extension, info, uri, value, result]() {
289 extension->SetCallingInfo(info);
290 extension->InitResult(result);
291 extension->Insert(uri, value);
292 };
293 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
294 if (result == nullptr) {
295 return false;
296 }
297 bool isRecvReply = result->GetRecvReply();
298 result->GetResult(ret);
299 return isRecvReply;
300 };
301 std::lock_guard<std::mutex> lock(mutex_);
302 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
303 return std::make_pair(E_OK, ret);
304 }
305
UpdateEx(const Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value)306 std::pair<int32_t, int32_t> DataShareStubImpl::UpdateEx(const Uri &uri, const DataSharePredicates &predicates,
307 const DataShareValuesBucket &value)
308 {
309 CallingInfo info;
310 GetCallingInfo(info);
311
312 auto client = sptr<DataShareStubImpl>(this);
313 auto extension = client->GetOwner();
314 if (extension == nullptr) {
315 return std::make_pair(DATA_SHARE_ERROR, 0);
316 }
317
318 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
319 LOG_ERROR("Check calling permission failed.");
320 return std::make_pair(PERMISSION_ERROR_NUMBER, 0);
321 }
322
323 auto result = std::make_shared<JsResult>();
324 int ret = 0;
325 std::function<void()> syncTaskFunc = [extension, info, uri, predicates, value, result]() {
326 extension->SetCallingInfo(info);
327 extension->InitResult(result);
328 extension->Update(uri, predicates, value);
329 };
330 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
331 if (result == nullptr) {
332 return false;
333 }
334 bool isRecvReply = result->GetRecvReply();
335 result->GetResult(ret);
336 return isRecvReply;
337 };
338 std::lock_guard<std::mutex> lock(mutex_);
339 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
340 return std::make_pair(E_OK, ret);
341 }
342
DeleteEx(const Uri & uri,const DataSharePredicates & predicates)343 std::pair<int32_t, int32_t> DataShareStubImpl::DeleteEx(const Uri &uri, const DataSharePredicates &predicates)
344 {
345 CallingInfo info;
346 GetCallingInfo(info);
347
348 auto client = sptr<DataShareStubImpl>(this);
349 auto extension = client->GetOwner();
350 if (extension == nullptr) {
351 return std::make_pair(DATA_SHARE_ERROR, 0);
352 }
353
354 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
355 LOG_ERROR("Check calling permission failed.");
356 return std::make_pair(PERMISSION_ERROR_NUMBER, 0);
357 }
358
359 int ret = 0;
360 auto result = std::make_shared<JsResult>();
361 std::function<void()> syncTaskFunc = [extension, info, uri, predicates, result]() {
362 extension->SetCallingInfo(info);
363 extension->InitResult(result);
364 extension->Delete(uri, predicates);
365 };
366 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
367 if (result == nullptr) {
368 return false;
369 }
370 bool isRecvReply = result->GetRecvReply();
371 result->GetResult(ret);
372 return isRecvReply;
373 };
374 std::lock_guard<std::mutex> lock(mutex_);
375 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
376 return std::make_pair(E_OK, ret);
377 }
378
Query(const Uri & uri,const DataSharePredicates & predicates,std::vector<std::string> & columns,DatashareBusinessError & businessError)379 std::shared_ptr<DataShareResultSet> DataShareStubImpl::Query(const Uri &uri,
380 const DataSharePredicates &predicates, std::vector<std::string> &columns, DatashareBusinessError &businessError)
381 {
382 CallingInfo info;
383 GetCallingInfo(info);
384 std::shared_ptr<DataShareResultSet> resultSet = nullptr;
385 auto client = sptr<DataShareStubImpl>(this);
386 auto extension = client->GetOwner();
387 if (extension == nullptr) {
388 return resultSet;
389 }
390
391 if (!CheckCallingPermission(extension->abilityInfo_->readPermission)) {
392 LOG_ERROR("Check calling permission failed.");
393 businessError.SetCode(PERMISSION_ERROR_NUMBER);
394 return resultSet;
395 }
396 auto result = std::make_shared<JsResult>();
397 std::function<void()> syncTaskFunc = [extension, info, uri, predicates, columns, result]() mutable {
398 extension->SetCallingInfo(info);
399 extension->InitResult(result);
400 DatashareBusinessError businessErr;
401 extension->Query(uri, predicates, columns, businessErr);
402 };
403 std::function<bool()> getRetFunc = [result, &resultSet, &businessError]() -> bool {
404 if (result == nullptr) {
405 return false;
406 }
407 auto isRecvReply = result->GetRecvReply();
408 result->GetResultSet(resultSet);
409 result->GetBusinessError(businessError);
410 return isRecvReply;
411 };
412 std::lock_guard<std::mutex> lock(mutex_);
413 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
414 return resultSet;
415 }
416
GetType(const Uri & uri)417 std::string DataShareStubImpl::GetType(const Uri &uri)
418 {
419 CallingInfo info;
420 GetCallingInfo(info);
421 std::string ret = "";
422 auto client = sptr<DataShareStubImpl>(this);
423 auto extension = client->GetOwner();
424 if (extension == nullptr) {
425 return ret;
426 }
427 auto result = std::make_shared<JsResult>();
428 std::function<void()> syncTaskFunc = [extension, info, uri, result]() {
429 if (extension == nullptr) {
430 return;
431 }
432 extension->SetCallingInfo(info);
433 extension->InitResult(result);
434 extension->GetType(uri);
435 };
436 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
437 if (result == nullptr) {
438 return false;
439 }
440 bool isRecvReply = result->GetRecvReply();
441 result->GetResult(ret);
442 return isRecvReply;
443 };
444 std::lock_guard<std::mutex> lock(mutex_);
445 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
446 return ret;
447 }
448
BatchInsert(const Uri & uri,const std::vector<DataShareValuesBucket> & values)449 int DataShareStubImpl::BatchInsert(const Uri &uri, const std::vector<DataShareValuesBucket> &values)
450 {
451 CallingInfo info;
452 GetCallingInfo(info);
453 auto client = sptr<DataShareStubImpl>(this);
454 auto extension = client->GetOwner();
455 if (extension == nullptr) {
456 return DEFAULT_NUMBER;
457 }
458
459 if (!CheckCallingPermission(extension->abilityInfo_->writePermission)) {
460 LOG_ERROR("Check calling permission failed.");
461 return PERMISSION_ERROR_NUMBER;
462 }
463
464 auto result = std::make_shared<JsResult>();
465 int ret = 0;
466 std::function<void()> syncTaskFunc = [extension, info, uri, values, result]() {
467 extension->SetCallingInfo(info);
468 extension->InitResult(result);
469 extension->BatchInsert(uri, values);
470 };
471 std::function<bool()> getRetFunc = [result, &ret]() -> bool {
472 if (result == nullptr) {
473 return false;
474 }
475 bool isRecvReply = result->GetRecvReply();
476 result->GetResult(ret);
477 return isRecvReply;
478 };
479 std::lock_guard<std::mutex> lock(mutex_);
480 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
481 return ret;
482 }
483
RegisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)484 bool DataShareStubImpl::RegisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
485 {
486 auto extension = GetOwner();
487 if (extension == nullptr) {
488 return false;
489 }
490 if (!CheckCallingPermission(extension->abilityInfo_->readPermission)) {
491 LOG_ERROR("Register observer check permission failed. uri: %{public}s",
492 DataShareStringUtils::Anonymous(uri.ToString()).c_str());
493 return false;
494 }
495 return extension->RegisterObserver(uri, dataObserver);
496 }
497
UnregisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)498 bool DataShareStubImpl::UnregisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
499 {
500 auto extension = GetOwner();
501 if (extension == nullptr) {
502 return false;
503 }
504 if (!CheckCallingPermission(extension->abilityInfo_->readPermission)) {
505 LOG_ERROR("UnRegister observer check permission failed. uri: %{public}s",
506 DataShareStringUtils::Anonymous(uri.ToString()).c_str());
507 return false;
508 }
509 return extension->UnregisterObserver(uri, dataObserver);
510 }
511
NotifyChange(const Uri & uri)512 bool DataShareStubImpl::NotifyChange(const Uri &uri)
513 {
514 std::shared_ptr<bool> ret = std::make_shared<bool>(false);
515 auto client = sptr<DataShareStubImpl>(this);
516 auto extension = client->GetOwner();
517 if (extension == nullptr) {
518 return *ret;
519 }
520
521 std::function<void()> syncTaskFunc = [extension, ret, uri]() {
522 *ret = extension->NotifyChange(uri);
523 };
524 std::lock_guard<std::mutex> lock(mutex_);
525 uvQueue_->SyncCall(syncTaskFunc);
526 return *ret;
527 }
528
NormalizeUri(const Uri & uri)529 Uri DataShareStubImpl::NormalizeUri(const Uri &uri)
530 {
531 CallingInfo info;
532 GetCallingInfo(info);
533 Uri normalizeUri("");
534 auto client = sptr<DataShareStubImpl>(this);
535 auto extension = client->GetOwner();
536 if (extension == nullptr) {
537 return normalizeUri;
538 }
539
540 auto result = std::make_shared<JsResult>();
541 std::function<void()> syncTaskFunc = [extension, info, uri, result]() {
542 extension->SetCallingInfo(info);
543 extension->InitResult(result);
544 extension->NormalizeUri(uri);
545 };
546 std::function<bool()> getRetFunc = [result, &normalizeUri]() -> bool {
547 if (result == nullptr) {
548 return false;
549 }
550 bool isRecvReply = result->GetRecvReply();
551 std::string ret;
552 result->GetResult(ret);
553 Uri tmp(ret);
554 normalizeUri = tmp;
555 return isRecvReply;
556 };
557 std::lock_guard<std::mutex> lock(mutex_);
558 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
559 return normalizeUri;
560 }
561
DenormalizeUri(const Uri & uri)562 Uri DataShareStubImpl::DenormalizeUri(const Uri &uri)
563 {
564 CallingInfo info;
565 GetCallingInfo(info);
566 Uri denormalizedUri("");
567 auto client = sptr<DataShareStubImpl>(this);
568 auto extension = client->GetOwner();
569 if (extension == nullptr) {
570 return denormalizedUri;
571 }
572 auto result = std::make_shared<JsResult>();
573 std::function<void()> syncTaskFunc = [extension, info, uri, result]() {
574 extension->SetCallingInfo(info);
575 extension->InitResult(result);
576 extension->DenormalizeUri(uri);
577 };
578 std::function<bool()> getRetFunc = [result, &denormalizedUri]() -> bool {
579 if (result == nullptr) {
580 return false;
581 }
582 bool isRecvReply = result->GetRecvReply();
583 std::string ret;
584 result->GetResult(ret);
585 Uri tmp(ret);
586 denormalizedUri = tmp;
587 return isRecvReply;
588 };
589 std::lock_guard<std::mutex> lock(mutex_);
590 uvQueue_->SyncCall(syncTaskFunc, getRetFunc);
591 return denormalizedUri;
592 }
593
GetCallingInfo(CallingInfo & callingInfo)594 void DataShareStubImpl::GetCallingInfo(CallingInfo& callingInfo)
595 {
596 callingInfo.callingTokenId = GetCallingTokenID();
597 callingInfo.callingPid = GetCallingPid();
598 callingInfo.callingUid = GetCallingUid();
599 }
600 } // namespace DataShare
601 } // namespace OHOS