• 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 #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