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 #define LOG_TAG "RdbManagerImpl"
17
18 #include "rdb_manager_impl.h"
19
20 #include <thread>
21 #include "iservice_registry.h"
22 #include "ipc_skeleton.h"
23 #include "system_ability_definition.h"
24
25 #include "log_print.h"
26 #include "ikvstore_data_service.h"
27 #include "irdb_service.h"
28 #include "rdb_service_proxy.h"
29
30 namespace OHOS::DistributedRdb {
GetDistributedDataManager()31 static sptr<DistributedKv::KvStoreDataServiceProxy> GetDistributedDataManager()
32 {
33 int retry = 0;
34 while (++retry <= RdbManagerImpl::GET_SA_RETRY_TIMES) {
35 auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
36 if (manager == nullptr) {
37 ZLOGE("get system ability manager failed");
38 return nullptr;
39 }
40 ZLOGI("get distributed data manager %{public}d", retry);
41 auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
42 if (remoteObject == nullptr) {
43 std::this_thread::sleep_for(std::chrono::seconds(RdbManagerImpl::RETRY_INTERVAL));
44 continue;
45 }
46 ZLOGI("get distributed data manager success");
47 return iface_cast<DistributedKv::KvStoreDataServiceProxy>(remoteObject);
48 }
49
50 ZLOGE("get distributed data manager failed");
51 return nullptr;
52 }
53
LinkToDeath(const sptr<IRemoteObject> & remote)54 static void LinkToDeath(const sptr<IRemoteObject>& remote)
55 {
56 auto& manager = RdbManagerImpl::GetInstance();
57 sptr<RdbManagerImpl::ServiceDeathRecipient> deathRecipient =
58 new(std::nothrow) RdbManagerImpl::ServiceDeathRecipient(&manager);
59 if (!remote->AddDeathRecipient(deathRecipient)) {
60 ZLOGE("add death recipient failed");
61 }
62 ZLOGE("success");
63 }
64
RdbManagerImpl()65 RdbManagerImpl::RdbManagerImpl()
66 {
67 ZLOGI("construct");
68 }
69
~RdbManagerImpl()70 RdbManagerImpl::~RdbManagerImpl()
71 {
72 ZLOGI("destroy");
73 }
74
GetInstance()75 RdbManagerImpl& RdbManagerImpl::GetInstance()
76 {
77 static RdbManagerImpl manager;
78 return manager;
79 }
80
GetRdbService(const RdbSyncerParam & param,std::shared_ptr<RdbService> & service)81 int RdbManagerImpl::GetRdbService(const RdbSyncerParam& param, std::shared_ptr<RdbService> &service)
82 {
83 std::lock_guard<std::mutex> lock(mutex_);
84 if (rdbService_ != nullptr) {
85 service = rdbService_;
86 return RDB_OK;
87 }
88 if (distributedDataMgr_ == nullptr) {
89 distributedDataMgr_ = GetDistributedDataManager();
90 }
91 if (distributedDataMgr_ == nullptr) {
92 ZLOGE("get distributed data manager failed");
93 return RDB_ERROR;
94 }
95
96 auto remote = distributedDataMgr_->GetFeatureInterface("relational_store");
97 if (remote == nullptr) {
98 ZLOGE("get rdb service failed");
99 return RDB_NOT_SUPPORTED;
100 }
101 sptr<RdbServiceProxy> serviceProxy = iface_cast<DistributedRdb::RdbServiceProxy>(remote);
102 if (serviceProxy->InitNotifier(param) != RDB_OK) {
103 ZLOGE("init notifier failed");
104 return RDB_ERROR;
105 }
106 sptr<IRdbService> serviceBase = serviceProxy;
107 LinkToDeath(serviceBase->AsObject().GetRefPtr());
108 rdbService_ = std::shared_ptr<RdbService>(serviceProxy.GetRefPtr(), [holder = serviceProxy] (const auto*) {});
109 if (rdbService_ == nullptr) {
110 ZLOGE("RdbService is nullptr.");
111 return RDB_ERROR;
112 }
113 bundleName_ = param.bundleName_;
114 service = rdbService_;
115 return RDB_OK;
116 }
117
OnRemoteDied()118 void RdbManagerImpl::OnRemoteDied()
119 {
120 ZLOGI("rdb service has dead!!");
121 auto proxy = std::static_pointer_cast<RdbServiceProxy>(rdbService_);
122 auto observers = proxy->ExportObservers();
123 ResetServiceHandle();
124
125 std::this_thread::sleep_for(std::chrono::seconds(WAIT_TIME));
126 RdbSyncerParam param;
127 param.bundleName_ = bundleName_;
128 std::shared_ptr<DistributedRdb::RdbService> service = nullptr;
129 int errCode = GetRdbService(param, service);
130 if (errCode != RDB_OK) {
131 ZLOGI("GetRdbService failed, err is %{public}d.", errCode);
132 return;
133 }
134 proxy = std::static_pointer_cast<RdbServiceProxy>(service);
135 if (proxy == nullptr) {
136 return;
137 }
138 ZLOGI("restore observer");
139 proxy->ImportObservers(observers);
140 }
141
ResetServiceHandle()142 void RdbManagerImpl::ResetServiceHandle()
143 {
144 ZLOGI("enter");
145 std::lock_guard<std::mutex> lock(mutex_);
146 distributedDataMgr_ = nullptr;
147 rdbService_ = nullptr;
148 }
149 } // namespace OHOS::DistributedRdb
150