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 "data_share_manager_impl.h"
17
18 #include <thread>
19
20 #include "datashare_log.h"
21 #include "ikvstore_data_service.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 #include "executor_pool.h"
26 #include "rdb_subscriber_manager.h"
27 #include "published_data_subscriber_manager.h"
28
29 namespace OHOS {
30 namespace DataShare {
GetInstance()31 DataShareManagerImpl& DataShareManagerImpl::GetInstance()
32 {
33 static DataShareManagerImpl manager;
34 return manager;
35 }
36
GetDistributedDataManager()37 std::shared_ptr<DataShareKvServiceProxy> DataShareManagerImpl::GetDistributedDataManager()
38 {
39 int retry = 0;
40 while (++retry <= GET_SA_RETRY_TIMES) {
41 auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
42 if (manager == nullptr) {
43 LOG_ERROR("get system ability manager failed");
44 return nullptr;
45 }
46 LOG_INFO("get distributed data manager %{public}d", retry);
47 auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
48 if (remoteObject == nullptr) {
49 std::this_thread::sleep_for(std::chrono::seconds(RETRY_INTERVAL));
50 continue;
51 }
52 LOG_INFO("get distributed data manager success");
53 return std::make_shared<DataShareKvServiceProxy>(remoteObject);
54 }
55
56 LOG_ERROR("get distributed data manager failed");
57 return nullptr;
58 }
59
LinkToDeath(const sptr<IRemoteObject> remote)60 void DataShareManagerImpl::LinkToDeath(const sptr<IRemoteObject> remote)
61 {
62 sptr<DataShareManagerImpl::ServiceDeathRecipient> deathRecipient = new (std::nothrow)
63 DataShareManagerImpl::ServiceDeathRecipient(this);
64 if (deathRecipient == nullptr) {
65 LOG_ERROR("DataShareManagerImpl::LinkToDeath new ServiceDeathRecipient error.");
66 return;
67 }
68 if (!remote->AddDeathRecipient(deathRecipient)) {
69 LOG_ERROR("add death recipient failed");
70 }
71 LOG_ERROR("link to death success");
72 }
73
GetDataShareServiceProxy()74 sptr<DataShareServiceProxy> DataShareManagerImpl::GetDataShareServiceProxy()
75 {
76 if (dataMgrService_ == nullptr) {
77 dataMgrService_ = GetDistributedDataManager();
78 }
79 if (dataMgrService_ == nullptr) {
80 LOG_ERROR("Get distributed data manager failed!");
81 return nullptr;
82 }
83 auto remote = dataMgrService_->GetFeatureInterface("data_share");
84 if (remote == nullptr) {
85 LOG_ERROR("Get DataShare service failed!");
86 return nullptr;
87 }
88 RegisterClientDeathObserver();
89 return iface_cast<DataShareServiceProxy>(remote);
90 }
91
RegisterClientDeathObserver()92 void DataShareManagerImpl::RegisterClientDeathObserver()
93 {
94 if (dataMgrService_ == nullptr || bundleName_.empty()) {
95 return;
96 }
97 LOG_INFO("RegisterClientDeathObserver bundleName is %{public}s", bundleName_.c_str());
98 if (clientDeathObserverPtr_ == nullptr) {
99 clientDeathObserverPtr_ = new (std::nothrow) DataShareClientDeathObserverStub();
100 }
101 if (clientDeathObserverPtr_ == nullptr) {
102 LOG_WARN("new KvStoreClientDeathObserver failed");
103 return;
104 }
105 dataMgrService_->RegisterClientDeathObserver(bundleName_, clientDeathObserverPtr_);
106 }
107
DataShareManagerImpl()108 DataShareManagerImpl::DataShareManagerImpl()
109 {
110 LOG_INFO("construct");
111 pool_ = std::make_shared<ExecutorPool>(MAX_THREADS, MIN_THREADS);
112 SetDeathCallback([](std::shared_ptr<DataShareServiceProxy> proxy) {
113 LOG_INFO("RecoverObs start");
114 RdbSubscriberManager::GetInstance().RecoverObservers(proxy);
115 PublishedDataSubscriberManager::GetInstance().RecoverObservers(proxy);
116 });
117 }
118
~DataShareManagerImpl()119 DataShareManagerImpl::~DataShareManagerImpl()
120 {
121 LOG_INFO("destroy");
122 }
123
GetServiceProxy()124 std::shared_ptr<DataShareServiceProxy> DataShareManagerImpl::GetServiceProxy()
125 {
126 if (dataShareService_ != nullptr) {
127 return dataShareService_;
128 }
129
130 std::lock_guard<std::mutex> lock(mutex_);
131 if (dataShareService_ != nullptr) {
132 return dataShareService_;
133 }
134
135 auto service = GetDataShareServiceProxy();
136 if (service == nullptr) {
137 return nullptr;
138 }
139 sptr<IDataShareService> serviceBase = service;
140 LinkToDeath(serviceBase->AsObject().GetRefPtr());
141 dataShareService_ = std::shared_ptr<DataShareServiceProxy>(
142 service.GetRefPtr(), [holder = service](const auto *) {});
143 return dataShareService_;
144 }
145
ResetServiceHandle()146 void DataShareManagerImpl::ResetServiceHandle()
147 {
148 LOG_INFO("enter");
149 std::lock_guard<std::mutex> lock(mutex_);
150 dataMgrService_ = nullptr;
151 dataShareService_ = nullptr;
152 }
153
SetDeathCallback(std::function<void (std::shared_ptr<DataShareServiceProxy>)> deathCallback)154 void DataShareManagerImpl::SetDeathCallback(std::function<void(std::shared_ptr<DataShareServiceProxy>)> deathCallback)
155 {
156 deathCallback_ = deathCallback;
157 }
158
SetBundleName(const std::string & bundleName)159 void DataShareManagerImpl::SetBundleName(const std::string &bundleName)
160 {
161 bundleName_ = bundleName;
162 }
163
OnRemoteDied()164 void DataShareManagerImpl::OnRemoteDied()
165 {
166 LOG_INFO("#######datashare service has dead");
167 ResetServiceHandle();
168 auto taskid = pool_->Schedule(std::chrono::seconds(WAIT_TIME), [this]() {
169 if (GetServiceProxy() != nullptr) {
170 deathCallback_(dataShareService_);
171 }
172 });
173 if (taskid == ExecutorPool::INVALID_TASK_ID) {
174 LOG_ERROR("create scheduler failed, over the max capacity");
175 return;
176 }
177 LOG_DEBUG("create scheduler success");
178 }
179 }
180 }