• 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 
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> {
40 };
GetDistributedDataManager(const std::string & bundleName)41 std::shared_ptr<RdbStoreDataServiceProxy> RdbManagerImpl::GetDistributedDataManager(const std::string &bundleName)
42 {
43     auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
44     if (manager == nullptr) {
45         LOG_ERROR("get system ability manager failed");
46         return nullptr;
47     }
48     auto dataMgr = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
49     if (dataMgr == nullptr) {
50         LOG_ERROR("get distributed data manager failed");
51         return nullptr;
52     }
53     sptr<RdbStoreDataServiceProxy> dataService = new (std::nothrow) RdbStoreDataServiceProxy(dataMgr);
54     if (dataService == nullptr) {
55         LOG_ERROR("new RdbStoreDataServiceProxy failed");
56         return nullptr;
57     }
58 
59     sptr<IRemoteObject> observer = new (std::nothrow) DeathStubImpl();
60     dataService->RegisterDeathObserver(bundleName, observer);
61     return std::shared_ptr<RdbStoreDataServiceProxy>(dataService.GetRefPtr(), [dataService, observer](const auto *) {});
62 }
63 
LinkToDeath(const sptr<IRemoteObject> & remote)64 static void LinkToDeath(const sptr<IRemoteObject>& remote)
65 {
66     auto& manager = RdbManagerImpl::GetInstance();
67     sptr<RdbManagerImpl::ServiceDeathRecipient> deathRecipient =
68         new(std::nothrow) RdbManagerImpl::ServiceDeathRecipient(&manager);
69     if (deathRecipient == nullptr) {
70         LOG_ERROR("new ServiceDeathRecipient failed");
71         return;
72     }
73     if (!remote->AddDeathRecipient(deathRecipient)) {
74         LOG_ERROR("add death recipient failed");
75     }
76 }
77 
RdbManagerImpl()78 RdbManagerImpl::RdbManagerImpl()
79 {
80     LOG_INFO("construct");
81 }
82 
~RdbManagerImpl()83 RdbManagerImpl::~RdbManagerImpl()
84 {
85     LOG_INFO("destroy");
86 }
87 
GetInstance()88 RdbManagerImpl& RdbManagerImpl::GetInstance()
89 {
90     static RdbManagerImpl manager;
91     return manager;
92 }
93 
GetRdbService(const RdbSyncerParam & param)94 std::pair<int32_t, std::shared_ptr<RdbService>> RdbManagerImpl::GetRdbService(const RdbSyncerParam &param)
95 {
96     if (param.bundleName_.empty()) {
97         return { E_INVALID_ARGS, nullptr };
98     }
99 
100     std::lock_guard<std::mutex> lock(mutex_);
101     if (rdbService_ != nullptr) {
102         return { E_OK, rdbService_ };
103     }
104 
105     if (distributedDataMgr_ == nullptr) {
106         distributedDataMgr_ = GetDistributedDataManager(param.bundleName_);
107     }
108     if (distributedDataMgr_ == nullptr) {
109         LOG_ERROR("get distributed data manager failed");
110         return { E_ERROR, nullptr };
111     }
112 
113     auto remote = distributedDataMgr_->GetFeatureInterface(DistributedRdb::RdbService::SERVICE_NAME);
114     if (remote == nullptr) {
115         LOG_ERROR("get rdb service failed");
116         return { E_NOT_SUPPORTED, nullptr };
117     }
118     sptr<RdbServiceProxy> rdbService = nullptr;
119     if (remote->IsProxyObject()) {
120         rdbService = iface_cast<RdbServiceProxy>(remote);
121     }
122 
123     if (rdbService == nullptr) {
124         rdbService = new (std::nothrow) RdbServiceProxy(remote);
125     }
126 
127     if (rdbService == nullptr || rdbService->InitNotifier(param) != RDB_OK) {
128         LOG_ERROR("init notifier failed");
129         return { E_ERROR, nullptr };
130     }
131 
132     sptr<IRdbService> serviceBase = rdbService;
133     LinkToDeath(serviceBase->AsObject());
134     // the rdbService is not null, so rdbService.GetRefPtr() is not null;
135     rdbService_ = std::shared_ptr<RdbService>(rdbService.GetRefPtr(), [rdbService](const auto *) {});
136     param_ = param;
137     return { E_OK, rdbService_ };
138 }
139 
OnRemoteDied()140 void RdbManagerImpl::OnRemoteDied()
141 {
142     LOG_INFO("rdb service has dead!!");
143     if (rdbService_ == nullptr) {
144         ResetServiceHandle();
145         return;
146     }
147     auto proxy = std::static_pointer_cast<RdbServiceProxy>(rdbService_);
148     auto observers = proxy->ExportObservers();
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 }
162 
ResetServiceHandle()163 void RdbManagerImpl::ResetServiceHandle()
164 {
165     std::lock_guard<std::mutex> lock(mutex_);
166     distributedDataMgr_ = nullptr;
167     rdbService_ = nullptr;
168 }
169 
RdbStoreDataServiceProxy(const sptr<IRemoteObject> & impl)170 RdbStoreDataServiceProxy::RdbStoreDataServiceProxy(const sptr<IRemoteObject> &impl)
171     : IRemoteProxy<DistributedRdb::IKvStoreDataService>(impl)
172 {
173     LOG_INFO("init data service proxy.");
174 }
175 
GetFeatureInterface(const std::string & name)176 sptr<IRemoteObject> RdbStoreDataServiceProxy::GetFeatureInterface(const std::string &name)
177 {
178     LOG_INFO("%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 = Remote()->SendRequest(
193         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 = Remote()->SendRequest(
223         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