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 #define LOG_TAG "DataShareServiceImpl"
17
18 #include "data_share_service_impl.h"
19
20 #include "accesstoken_kit.h"
21 #include "account/account_delegate.h"
22 #include "app_connect_manager.h"
23 #include "common_event_manager.h"
24 #include "common_event_support.h"
25 #include "dataobs_mgr_client.h"
26 #include "datashare_errno.h"
27 #include "datashare_template.h"
28 #include "directory/directory_manager.h"
29 #include "hap_token_info.h"
30 #include "ipc_skeleton.h"
31 #include "log_print.h"
32 #include "matching_skills.h"
33 #include "scheduler_manager.h"
34 #include "subscriber_managers/published_data_subscriber_manager.h"
35 #include "template_data.h"
36 #include "utils/anonymous.h"
37
38 namespace OHOS::DataShare {
39 using FeatureSystem = DistributedData::FeatureSystem;
40 __attribute__((used)) DataShareServiceImpl::Factory DataShareServiceImpl::factory_;
Factory()41 DataShareServiceImpl::Factory::Factory()
42 {
43 FeatureSystem::GetInstance().RegisterCreator("data_share", []() {
44 return std::make_shared<DataShareServiceImpl>();
45 });
46 }
47
~Factory()48 DataShareServiceImpl::Factory::~Factory() {}
49
Insert(const std::string & uri,const DataShareValuesBucket & valuesBucket)50 int32_t DataShareServiceImpl::Insert(const std::string &uri, const DataShareValuesBucket &valuesBucket)
51 {
52 ZLOGD("Insert enter.");
53 auto context = std::make_shared<Context>(uri);
54 auto ret = insertStrategy_.Execute(context, valuesBucket);
55 if (ret) {
56 NotifyChange(uri);
57 RdbSubscriberManager::GetInstance().Emit(uri, context);
58 }
59 return ret;
60 }
61
NotifyChange(const std::string & uri)62 bool DataShareServiceImpl::NotifyChange(const std::string &uri)
63 {
64 auto obsMgrClient = AAFwk::DataObsMgrClient::GetInstance();
65 if (obsMgrClient == nullptr) {
66 ZLOGE("obsMgrClient is nullptr");
67 return false;
68 }
69
70 ErrCode ret = obsMgrClient->NotifyChange(Uri(uri));
71 if (ret != ERR_OK) {
72 ZLOGE("obsMgrClient->NotifyChange error return %{public}d", ret);
73 return false;
74 }
75 return true;
76 }
77
Update(const std::string & uri,const DataSharePredicates & predicate,const DataShareValuesBucket & valuesBucket)78 int32_t DataShareServiceImpl::Update(const std::string &uri, const DataSharePredicates &predicate,
79 const DataShareValuesBucket &valuesBucket)
80 {
81 ZLOGD("Update enter.");
82 auto context = std::make_shared<Context>(uri);
83 auto ret = updateStrategy_.Execute(context, predicate, valuesBucket);
84 if (ret) {
85 NotifyChange(uri);
86 RdbSubscriberManager::GetInstance().Emit(uri, context);
87 }
88 return ret;
89 }
90
Delete(const std::string & uri,const DataSharePredicates & predicate)91 int32_t DataShareServiceImpl::Delete(const std::string &uri, const DataSharePredicates &predicate)
92 {
93 ZLOGD("Delete enter.");
94 auto context = std::make_shared<Context>(uri);
95 auto ret = deleteStrategy_.Execute(context, predicate);
96 if (ret) {
97 NotifyChange(uri);
98 RdbSubscriberManager::GetInstance().Emit(uri, context);
99 }
100 return ret;
101 }
102
Query(const std::string & uri,const DataSharePredicates & predicates,const std::vector<std::string> & columns,int & errCode)103 std::shared_ptr<DataShareResultSet> DataShareServiceImpl::Query(const std::string &uri,
104 const DataSharePredicates &predicates, const std::vector<std::string> &columns, int &errCode)
105 {
106 ZLOGD("Query enter.");
107 auto context = std::make_shared<Context>(uri);
108 return queryStrategy_.Execute(context, predicates, columns, errCode);
109 }
110
AddTemplate(const std::string & uri,const int64_t subscriberId,const Template & tplt)111 int32_t DataShareServiceImpl::AddTemplate(const std::string &uri, const int64_t subscriberId, const Template &tplt)
112 {
113 auto context = std::make_shared<Context>(uri);
114 TemplateId tpltId;
115 tpltId.subscriberId_ = subscriberId;
116 if (!GetCallerBundleName(tpltId.bundleName_)) {
117 ZLOGE("get bundleName error, %{public}s", DistributedData::Anonymous::Change(uri).c_str());
118 return ERROR;
119 }
120 return templateStrategy_.Execute(context, [&uri, &tpltId, &tplt, &context]() -> int32_t {
121 auto result = TemplateManager::GetInstance().Add(
122 Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId, tplt);
123 RdbSubscriberManager::GetInstance().Emit(context->uri, tpltId.subscriberId_, context);
124 return result;
125 });
126 }
127
DelTemplate(const std::string & uri,const int64_t subscriberId)128 int32_t DataShareServiceImpl::DelTemplate(const std::string &uri, const int64_t subscriberId)
129 {
130 auto context = std::make_shared<Context>(uri);
131 TemplateId tpltId;
132 tpltId.subscriberId_ = subscriberId;
133 if (!GetCallerBundleName(tpltId.bundleName_)) {
134 ZLOGE("get bundleName error, %{public}s", DistributedData::Anonymous::Change(uri).c_str());
135 return ERROR;
136 }
137
138 return templateStrategy_.Execute(context, [&uri, &tpltId, &context]() -> int32_t {
139 return TemplateManager::GetInstance().Delete(
140 Key(uri, tpltId.subscriberId_, tpltId.bundleName_), context->currentUserId);
141 });
142 }
143
GetCallerBundleName(std::string & bundleName)144 bool DataShareServiceImpl::GetCallerBundleName(std::string &bundleName)
145 {
146 auto tokenId = IPCSkeleton::GetCallingTokenID();
147 auto type = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
148 if (type == Security::AccessToken::TOKEN_NATIVE) {
149 return true;
150 }
151 if (type != Security::AccessToken::TOKEN_HAP) {
152 return false;
153 }
154 Security::AccessToken::HapTokenInfo tokenInfo;
155 auto result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
156 if (result != Security::AccessToken::RET_SUCCESS) {
157 ZLOGE("token:0x%{public}x, result:%{public}d", tokenId, result);
158 return false;
159 }
160 bundleName = tokenInfo.bundleName;
161 return true;
162 }
163
Publish(const Data & data,const std::string & bundleNameOfProvider)164 std::vector<OperationResult> DataShareServiceImpl::Publish(const Data &data, const std::string &bundleNameOfProvider)
165 {
166 std::vector<OperationResult> results;
167 std::vector<PublishedDataKey> publishedData;
168 std::string callerBundleName;
169 if (!GetCallerBundleName(callerBundleName)) {
170 ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str());
171 return results;
172 }
173 int32_t userId = -1;
174 PublishedData::ClearAging();
175 for (const auto &item : data.datas_) {
176 auto context = std::make_shared<Context>(item.key_);
177 context->version = data.version_;
178 context->callerBundleName = callerBundleName;
179 context->calledBundleName = bundleNameOfProvider;
180 int32_t result = publishStrategy_.Execute(context, item);
181 results.emplace_back(item.key_, result);
182 if (result != EOK) {
183 ZLOGE("publish error, key is %{public}s", DistributedData::Anonymous::Change(item.key_).c_str());
184 continue;
185 }
186 publishedData.emplace_back(context->uri, context->calledBundleName, item.subscriberId_);
187 userId = context->currentUserId;
188 }
189 if (!publishedData.empty()) {
190 PublishedDataSubscriberManager::GetInstance().Emit(publishedData, userId, callerBundleName);
191 PublishedDataSubscriberManager::GetInstance().SetObserversNotifiedOnEnabled(publishedData);
192 }
193 return results;
194 }
195
GetData(const std::string & bundleNameOfProvider,int & errorCode)196 Data DataShareServiceImpl::GetData(const std::string &bundleNameOfProvider, int &errorCode)
197 {
198 std::string callerBundleName;
199 if (!GetCallerBundleName(callerBundleName)) {
200 ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str());
201 return Data();
202 }
203 auto context = std::make_shared<Context>();
204 context->callerBundleName = callerBundleName;
205 context->calledBundleName = bundleNameOfProvider;
206 return getDataStrategy_.Execute(context, errorCode);
207 }
208
SubscribeRdbData(const std::vector<std::string> & uris,const TemplateId & id,const sptr<IDataProxyRdbObserver> observer)209 std::vector<OperationResult> DataShareServiceImpl::SubscribeRdbData(
210 const std::vector<std::string> &uris, const TemplateId &id, const sptr<IDataProxyRdbObserver> observer)
211 {
212 std::vector<OperationResult> results;
213 for (const auto &uri : uris) {
214 auto context = std::make_shared<Context>(uri);
215 results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &observer, &context, this]() {
216 return RdbSubscriberManager::GetInstance().Add(
217 Key(context->uri, id.subscriberId_, id.bundleName_), observer, context, binderInfo_.executors);
218 }));
219 }
220 return results;
221 }
222
UnsubscribeRdbData(const std::vector<std::string> & uris,const TemplateId & id)223 std::vector<OperationResult> DataShareServiceImpl::UnsubscribeRdbData(
224 const std::vector<std::string> &uris, const TemplateId &id)
225 {
226 std::vector<OperationResult> results;
227 for (const auto &uri : uris) {
228 auto context = std::make_shared<Context>(uri);
229 results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &context]() {
230 return RdbSubscriberManager::GetInstance().Delete(
231 Key(context->uri, id.subscriberId_, id.bundleName_), context->callerTokenId);
232 }));
233 }
234 return results;
235 }
236
EnableRdbSubs(const std::vector<std::string> & uris,const TemplateId & id)237 std::vector<OperationResult> DataShareServiceImpl::EnableRdbSubs(
238 const std::vector<std::string> &uris, const TemplateId &id)
239 {
240 std::vector<OperationResult> results;
241 for (const auto &uri : uris) {
242 auto context = std::make_shared<Context>(uri);
243 results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &context]() {
244 return RdbSubscriberManager::GetInstance().Enable(
245 Key(context->uri, id.subscriberId_, id.bundleName_), context);
246 }));
247 }
248 return results;
249 }
250
DisableRdbSubs(const std::vector<std::string> & uris,const TemplateId & id)251 std::vector<OperationResult> DataShareServiceImpl::DisableRdbSubs(
252 const std::vector<std::string> &uris, const TemplateId &id)
253 {
254 std::vector<OperationResult> results;
255 for (const auto &uri : uris) {
256 auto context = std::make_shared<Context>(uri);
257 results.emplace_back(uri, subscribeStrategy_.Execute(context, [&id, &context]() {
258 return RdbSubscriberManager::GetInstance().Disable(
259 Key(context->uri, id.subscriberId_, id.bundleName_), context->callerTokenId);
260 }));
261 }
262 return results;
263 }
264
SubscribePublishedData(const std::vector<std::string> & uris,const int64_t subscriberId,const sptr<IDataProxyPublishedDataObserver> observer)265 std::vector<OperationResult> DataShareServiceImpl::SubscribePublishedData(const std::vector<std::string> &uris,
266 const int64_t subscriberId, const sptr<IDataProxyPublishedDataObserver> observer)
267 {
268 std::vector<OperationResult> results;
269 std::string callerBundleName;
270 if (!GetCallerBundleName(callerBundleName)) {
271 ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str());
272 return results;
273 }
274 std::vector<PublishedDataKey> publishedKeys;
275 int32_t result;
276 int32_t userId;
277 for (const auto &uri : uris) {
278 auto context = std::make_shared<Context>(uri);
279 PublishedDataKey key(uri, callerBundleName, subscriberId);
280 context->callerBundleName = callerBundleName;
281 context->calledBundleName = key.bundleName;
282 result = subscribeStrategy_.Execute(context, [&subscriberId, &observer, &context]() {
283 return PublishedDataSubscriberManager::GetInstance().Add(
284 PublishedDataKey(context->uri, context->callerBundleName, subscriberId), observer,
285 context->callerTokenId);
286 });
287 results.emplace_back(uri, result);
288 if (result == E_OK) {
289 publishedKeys.emplace_back(context->uri, context->callerBundleName, subscriberId);
290 if (binderInfo_.executors != nullptr) {
291 binderInfo_.executors->Execute([context, subscriberId]() {
292 PublishedData::UpdateTimestamp(
293 context->uri, context->calledBundleName, subscriberId, context->currentUserId);
294 });
295 }
296 userId = context->currentUserId;
297 }
298 }
299 if (!publishedKeys.empty()) {
300 PublishedDataSubscriberManager::GetInstance().Emit(publishedKeys, userId, callerBundleName, observer);
301 }
302 return results;
303 }
304
UnsubscribePublishedData(const std::vector<std::string> & uris,const int64_t subscriberId)305 std::vector<OperationResult> DataShareServiceImpl::UnsubscribePublishedData(const std::vector<std::string> &uris,
306 const int64_t subscriberId)
307 {
308 std::vector<OperationResult> results;
309 std::string callerBundleName;
310 if (!GetCallerBundleName(callerBundleName)) {
311 ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str());
312 return results;
313 }
314 for (const auto &uri : uris) {
315 auto context = std::make_shared<Context>(uri);
316 PublishedDataKey key(uri, callerBundleName, subscriberId);
317 context->callerBundleName = callerBundleName;
318 context->calledBundleName = key.bundleName;
319 results.emplace_back(uri, subscribeStrategy_.Execute(context, [&subscriberId, &context, this]() {
320 auto result = PublishedDataSubscriberManager::GetInstance().Delete(
321 PublishedDataKey(context->uri, context->callerBundleName, subscriberId), context->callerTokenId);
322 if (result == E_OK && binderInfo_.executors != nullptr) {
323 binderInfo_.executors->Execute([context, subscriberId]() {
324 PublishedData::UpdateTimestamp(
325 context->uri, context->calledBundleName, subscriberId, context->currentUserId);
326 });
327 }
328 return result;
329 }));
330 }
331 return results;
332 }
333
EnablePubSubs(const std::vector<std::string> & uris,const int64_t subscriberId)334 std::vector<OperationResult> DataShareServiceImpl::EnablePubSubs(const std::vector<std::string> &uris,
335 const int64_t subscriberId)
336 {
337 std::vector<OperationResult> results;
338 std::string callerBundleName;
339 if (!GetCallerBundleName(callerBundleName)) {
340 ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str());
341 return results;
342 }
343 std::vector<PublishedDataKey> publishedKeys;
344 int32_t result;
345 int32_t userId = -1;
346 for (const auto &uri : uris) {
347 auto context = std::make_shared<Context>(uri);
348 PublishedDataKey key(uri, callerBundleName, subscriberId);
349 context->callerBundleName = callerBundleName;
350 context->calledBundleName = key.bundleName;
351 result = subscribeStrategy_.Execute(context, [&subscriberId, &context]() {
352 return PublishedDataSubscriberManager::GetInstance().Enable(
353 PublishedDataKey(context->uri, context->callerBundleName, subscriberId), context->callerTokenId);
354 });
355 if (result == E_OK && binderInfo_.executors != nullptr) {
356 binderInfo_.executors->Execute([context, subscriberId]() {
357 PublishedData::UpdateTimestamp(
358 context->uri, context->calledBundleName, subscriberId, context->currentUserId);
359 });
360 }
361 results.emplace_back(uri, result);
362 if (result == E_OK) {
363 PublishedDataKey pKey(context->uri, context->callerBundleName, subscriberId);
364 if (PublishedDataSubscriberManager::GetInstance().IsNotifyOnEnabled(pKey, context->callerTokenId)) {
365 publishedKeys.emplace_back(pKey);
366 }
367 userId = context->currentUserId;
368 }
369 }
370 if (!publishedKeys.empty()) {
371 PublishedDataSubscriberManager::GetInstance().Emit(publishedKeys, userId, callerBundleName);
372 }
373 return results;
374 }
375
DisablePubSubs(const std::vector<std::string> & uris,const int64_t subscriberId)376 std::vector<OperationResult> DataShareServiceImpl::DisablePubSubs(const std::vector<std::string> &uris,
377 const int64_t subscriberId)
378 {
379 std::vector<OperationResult> results;
380 std::string callerBundleName;
381 if (!GetCallerBundleName(callerBundleName)) {
382 ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str());
383 return results;
384 }
385 for (const auto &uri : uris) {
386 auto context = std::make_shared<Context>(uri);
387 PublishedDataKey key(uri, callerBundleName, subscriberId);
388 context->callerBundleName = callerBundleName;
389 context->calledBundleName = key.bundleName;
390 results.emplace_back(uri, subscribeStrategy_.Execute(context, [&subscriberId, &context, this]() {
391 auto result = PublishedDataSubscriberManager::GetInstance().Disable(
392 PublishedDataKey(context->uri, context->callerBundleName, subscriberId), context->callerTokenId);
393 if (result == E_OK && binderInfo_.executors != nullptr) {
394 binderInfo_.executors->Execute([context, subscriberId]() {
395 PublishedData::UpdateTimestamp(
396 context->uri, context->calledBundleName, subscriberId, context->currentUserId);
397 });
398 }
399 return result;
400 }));
401 }
402 return results;
403 }
404
405 enum DataShareKvStoreType : int32_t {
406 DATA_SHARE_SINGLE_VERSION = 0,
407 DISTRIBUTED_TYPE_BUTT
408 };
409
OnBind(const BindInfo & binderInfo)410 int32_t DataShareServiceImpl::OnBind(const BindInfo &binderInfo)
411 {
412 binderInfo_ = binderInfo;
413 const std::string accountId = DistributedKv::AccountDelegate::GetInstance()->GetCurrentAccountId();
414 const auto userId = DistributedKv::AccountDelegate::GetInstance()->GetUserByToken(binderInfo.selfTokenId);
415 DistributedData::StoreMetaData saveMeta;
416 saveMeta.appType = "default";
417 saveMeta.storeId = "data_share_data_";
418 saveMeta.isAutoSync = false;
419 saveMeta.isBackup = false;
420 saveMeta.isEncrypt = false;
421 saveMeta.bundleName = binderInfo.selfName;
422 saveMeta.appId = binderInfo.selfName;
423 saveMeta.user = std::to_string(userId);
424 saveMeta.account = accountId;
425 saveMeta.tokenId = binderInfo.selfTokenId;
426 saveMeta.securityLevel = DistributedKv::SecurityLevel::S1;
427 saveMeta.area = 1;
428 saveMeta.uid = IPCSkeleton::GetCallingUid();
429 saveMeta.storeType = DATA_SHARE_SINGLE_VERSION;
430 saveMeta.dataDir = DistributedData::DirectoryManager::GetInstance().GetStorePath(saveMeta);
431 KvDBDelegate::GetInstance(false, saveMeta.dataDir, binderInfo.executors);
432 SchedulerManager::GetInstance().SetExecutorPool(binderInfo.executors);
433 SubscribeTimeChanged();
434 return EOK;
435 }
436
OnConnectDone()437 void DataShareServiceImpl::OnConnectDone()
438 {
439 std::string callerBundleName;
440 if (!GetCallerBundleName(callerBundleName)) {
441 ZLOGE("get bundleName error, %{public}s", callerBundleName.c_str());
442 return;
443 }
444 AppConnectManager::Notify(callerBundleName);
445 }
446
OnAppUninstall(const std::string & bundleName,int32_t user,int32_t index)447 int32_t DataShareServiceImpl::OnAppUninstall(
448 const std::string &bundleName, int32_t user, int32_t index)
449 {
450 ZLOGI("%{public}s uninstalled", bundleName.c_str());
451 PublishedData::Delete(bundleName, user);
452 PublishedData::ClearAging();
453 TemplateData::Delete(bundleName, user);
454 RdbHelper::ClearCache();
455 return EOK;
456 }
457
OnAppExit(pid_t uid,pid_t pid,uint32_t tokenId,const std::string & bundleName)458 int32_t DataShareServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, const std::string &bundleName)
459 {
460 ZLOGI("AppExit uid=%{public}d, pid=%{public}d, tokenId=0x%{public}x, bundleName=%{public}s",
461 uid, pid, tokenId, bundleName.c_str());
462 RdbSubscriberManager::GetInstance().Delete(tokenId);
463 PublishedDataSubscriberManager::GetInstance().Delete(tokenId);
464 return EOK;
465 }
466
NotifyObserver(const std::string & uri)467 void DataShareServiceImpl::NotifyObserver(const std::string &uri)
468 {
469 ZLOGD("%{private}s try notified", uri.c_str());
470 auto context = std::make_shared<Context>(uri);
471 if (!GetCallerBundleName(context->callerBundleName)) {
472 ZLOGE("get bundleName error, %{private}s", uri.c_str());
473 return;
474 }
475 auto ret = rdbNotifyStrategy_.Execute(context);
476 if (ret) {
477 ZLOGI("%{private}s start notified", uri.c_str());
478 RdbSubscriberManager::GetInstance().Emit(uri, context);
479 }
480 }
481
SubscribeTimeChanged()482 bool DataShareServiceImpl::SubscribeTimeChanged()
483 {
484 ZLOGD("start");
485 EventFwk::MatchingSkills matchingSkills;
486 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
487 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
488 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
489 subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::COMMON);
490 timerReceiver_ = std::make_shared<TimerReceiver>(subscribeInfo);
491 auto result = EventFwk::CommonEventManager::SubscribeCommonEvent(timerReceiver_);
492 if (!result) {
493 ZLOGE("SubscribeCommonEvent err");
494 }
495 return result;
496 }
497
OnReceiveEvent(const EventFwk::CommonEventData & eventData)498 void DataShareServiceImpl::TimerReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
499 {
500 AAFwk::Want want = eventData.GetWant();
501 std::string action = want.GetAction();
502 ZLOGI("action:%{public}s.", action.c_str());
503 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED
504 || action == EventFwk::CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED) {
505 SchedulerManager::GetInstance().ReExecuteAll();
506 }
507 }
508
TimerReceiver(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)509 DataShareServiceImpl::TimerReceiver::TimerReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
510 : CommonEventSubscriber(subscriberInfo)
511 {
512 }
513 } // namespace OHOS::DataShare
514