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 #define LOG_TAG "RdbManagerImpl"
16 #include "rdb_manager_impl.h"
17
18 #include <thread>
19
20 #include "ipc_skeleton.h"
21 #include "irdb_service.h"
22 #include "iservice_registry.h"
23 #include "itypes_util.h"
24 #include "logger.h"
25 #include "rdb_errno.h"
26 #include "rdb_service_proxy.h"
27 #include "system_ability_definition.h"
28
29 namespace OHOS::DistributedRdb {
30 using namespace OHOS::Rdb;
31 using RdbServiceProxy = DistributedRdb::RdbServiceProxy;
32 using namespace OHOS::NativeRdb;
33 using namespace OHOS::DistributedRdb::RelationalStore;
34
35 class DeathStub : public IRemoteBroker {
36 public:
37 DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.DistributedRdb.DeathStub");
38 };
39 class DeathStubImpl : public IRemoteStub<DeathStub> {};
GetDistributedDataManager(const std::string & bundleName)40 std::shared_ptr<RdbStoreDataServiceProxy> RdbManagerImpl::GetDistributedDataManager(const std::string &bundleName)
41 {
42 auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
43 if (manager == nullptr) {
44 LOG_ERROR("Get system ability manager failed.");
45 return nullptr;
46 }
47 auto dataMgr = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
48 if (dataMgr == nullptr) {
49 LOG_ERROR("Get distributed data manager failed.");
50 return nullptr;
51 }
52 sptr<RdbStoreDataServiceProxy> dataService = new (std::nothrow) RdbStoreDataServiceProxy(dataMgr);
53 if (dataService == nullptr) {
54 LOG_ERROR("New RdbStoreDataServiceProxy failed.");
55 return nullptr;
56 }
57
58 sptr<IRemoteObject> observer = new (std::nothrow) DeathStubImpl();
59 dataService->RegisterDeathObserver(bundleName, observer);
60 return std::shared_ptr<RdbStoreDataServiceProxy>(dataService.GetRefPtr(), [dataService, observer](const auto *) {});
61 }
62
LinkToDeath(const sptr<IRemoteObject> & remote)63 static void LinkToDeath(const sptr<IRemoteObject> &remote)
64 {
65 auto &manager = RdbManagerImpl::GetInstance();
66 sptr<RdbManagerImpl::ServiceDeathRecipient> deathRecipient = new (std::nothrow)
67 RdbManagerImpl::ServiceDeathRecipient(&manager);
68 if (deathRecipient == nullptr) {
69 LOG_ERROR("New ServiceDeathRecipient failed.");
70 return;
71 }
72 if (!remote->AddDeathRecipient(deathRecipient)) {
73 LOG_ERROR("Add death recipient failed.");
74 }
75 }
76
RdbManagerImpl()77 RdbManagerImpl::RdbManagerImpl()
78 {
79 }
80
~RdbManagerImpl()81 RdbManagerImpl::~RdbManagerImpl()
82 {
83 LOG_INFO("Destroy.");
84 }
85
GetInstance()86 RdbManagerImpl &RdbManagerImpl::GetInstance()
87 {
88 static RdbManagerImpl manager;
89 return manager;
90 }
91
GetRdbService(const RdbSyncerParam & param)92 std::pair<int32_t, std::shared_ptr<RdbService>> RdbManagerImpl::GetRdbService(const RdbSyncerParam ¶m)
93 {
94 if (param.bundleName_.empty()) {
95 return { E_INVALID_ARGS, nullptr };
96 }
97
98 std::lock_guard<std::mutex> lock(mutex_);
99 if (rdbService_ != nullptr) {
100 return { E_OK, rdbService_ };
101 }
102
103 if (distributedDataMgr_ == nullptr) {
104 distributedDataMgr_ = GetDistributedDataManager(param.bundleName_);
105 }
106 if (distributedDataMgr_ == nullptr) {
107 LOG_ERROR("Get distributed data manager failed.");
108 return { E_SERVICE_NOT_FOUND, nullptr };
109 }
110
111 auto remote = distributedDataMgr_->GetFeatureInterface(DistributedRdb::RdbService::SERVICE_NAME);
112 if (remote == nullptr) {
113 LOG_ERROR("Get rdb service failed.");
114 return { E_NOT_SUPPORT, nullptr };
115 }
116
117 if (!remote->IsProxyObject()) {
118 return { E_NOT_SUPPORT, nullptr };
119 }
120
121 sptr<RdbServiceProxy> rdbService = iface_cast<RdbServiceProxy>(remote);
122 if (rdbService == nullptr) {
123 rdbService = new (std::nothrow) RdbServiceProxy(remote);
124 }
125
126 if (rdbService == nullptr || rdbService->InitNotifier(param) != RDB_OK) {
127 LOG_ERROR("Init notifier failed.");
128 return { E_ERROR, nullptr };
129 }
130
131 sptr<IRdbService> serviceBase = rdbService;
132 LinkToDeath(serviceBase->AsObject());
133 // the rdbService is not null, so rdbService.GetRefPtr() is not null;
134 rdbService_ = std::shared_ptr<RdbService>(rdbService.GetRefPtr(), [rdbService](const auto *) {});
135 param_ = param;
136 return { E_OK, rdbService_ };
137 }
138
OnRemoteDied()139 void RdbManagerImpl::OnRemoteDied()
140 {
141 LOG_INFO("Rdb service has dead!");
142 if (rdbService_ == nullptr) {
143 ResetServiceHandle();
144 return;
145 }
146 auto proxy = std::static_pointer_cast<RdbServiceProxy>(rdbService_);
147 auto observers = proxy->ExportObservers();
148 auto syncObservers = proxy->ExportSyncObservers();
149 ResetServiceHandle();
150
151 std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME));
152 auto [errCode, service] = DistributedRdb::RdbManagerImpl::GetInstance().GetRdbService(param_);
153 if (errCode != E_OK) {
154 return;
155 }
156 proxy = std::static_pointer_cast<RdbServiceProxy>(service);
157 if (proxy == nullptr) {
158 return;
159 }
160 proxy->ImportObservers(observers);
161 proxy->ImportSyncObservers(syncObservers);
162 }
163
ResetServiceHandle()164 void RdbManagerImpl::ResetServiceHandle()
165 {
166 std::lock_guard<std::mutex> lock(mutex_);
167 distributedDataMgr_ = nullptr;
168 rdbService_ = nullptr;
169 }
170
RdbStoreDataServiceProxy(const sptr<IRemoteObject> & impl)171 RdbStoreDataServiceProxy::RdbStoreDataServiceProxy(const sptr<IRemoteObject> &impl)
172 : IRemoteProxy<DistributedRdb::IKvStoreDataService>(impl)
173 {
174 }
175
GetFeatureInterface(const std::string & name)176 sptr<IRemoteObject> RdbStoreDataServiceProxy::GetFeatureInterface(const std::string &name)
177 {
178 LOG_DEBUG("%{public}s", name.c_str());
179 MessageParcel data;
180 if (!data.WriteInterfaceToken(RdbStoreDataServiceProxy::GetDescriptor())) {
181 LOG_ERROR("Write descriptor failed.");
182 return nullptr;
183 }
184
185 if (!ITypesUtil::Marshal(data, name)) {
186 LOG_ERROR("Write descriptor failed.");
187 return nullptr;
188 }
189
190 MessageParcel reply;
191 MessageOption mo{ MessageOption::TF_SYNC };
192 int32_t error =
193 Remote()->SendRequest(static_cast<uint32_t>(KvStoreInterfaceCode::GET_FEATURE_INTERFACE), data, reply, mo);
194 if (error != 0) {
195 LOG_ERROR("SendRequest returned %{public}d", error);
196 return nullptr;
197 }
198
199 sptr<IRemoteObject> remoteObject;
200 if (!ITypesUtil::Unmarshal(reply, remoteObject)) {
201 LOG_ERROR("Remote object is nullptr.");
202 return nullptr;
203 }
204 return remoteObject;
205 }
206
RegisterDeathObserver(const std::string & bundleName,sptr<IRemoteObject> observer)207 int32_t RdbStoreDataServiceProxy::RegisterDeathObserver(const std::string &bundleName, sptr<IRemoteObject> observer)
208 {
209 MessageParcel data;
210 if (!data.WriteInterfaceToken(RdbStoreDataServiceProxy::GetDescriptor())) {
211 LOG_ERROR("Write descriptor failed.");
212 return E_ERROR;
213 }
214
215 if (!ITypesUtil::Marshal(data, bundleName, observer)) {
216 LOG_ERROR("Write descriptor failed.");
217 return E_ERROR;
218 }
219
220 MessageParcel reply;
221 MessageOption mo{ MessageOption::TF_SYNC };
222 int32_t error =
223 Remote()->SendRequest(static_cast<uint32_t>(KvStoreInterfaceCode::REGISTER_DEATH_OBSERVER), data, reply, mo);
224 if (error != 0) {
225 LOG_ERROR("SendRequest returned %{public}d", error);
226 return E_ERROR;
227 }
228
229 int32_t status = E_ERROR;
230 ITypesUtil::Unmarshal(reply, status);
231 return status;
232 }
233 } // namespace OHOS::DistributedRdb
234