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