• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param)
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