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 "data_share_manager_impl.h"
17
18 #include <thread>
19
20 #include "data_share_manager.h"
21 #include "data_share_service_proxy.h"
22 #include "datashare_log.h"
23 #include "idata_share_service.h"
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27
28 namespace OHOS::DataShare {
GetDistributedDataManager()29 std::shared_ptr<DataShareKvServiceProxy> DataShareManagerImpl::GetDistributedDataManager()
30 {
31 int retry = 0;
32 while (++retry <= GET_SA_RETRY_TIMES) {
33 auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
34 if (manager == nullptr) {
35 LOG_ERROR("get system ability manager failed");
36 return nullptr;
37 }
38 LOG_INFO("get distributed data manager %{public}d", retry);
39 auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
40 if (remoteObject == nullptr) {
41 std::this_thread::sleep_for(std::chrono::seconds(RETRY_INTERVAL));
42 continue;
43 }
44 LOG_INFO("get distributed data manager success");
45 return std::make_shared<DataShareKvServiceProxy>(remoteObject);
46 }
47
48 LOG_ERROR("get distributed data manager failed");
49 return nullptr;
50 }
51
LinkToDeath(const sptr<IRemoteObject> & remote)52 static void LinkToDeath(const sptr<IRemoteObject> &remote)
53 {
54 auto &manager = DataShareManagerImpl::GetInstance();
55 sptr<DataShareManagerImpl::ServiceDeathRecipient> deathRecipient = new (std::nothrow)
56 DataShareManagerImpl::ServiceDeathRecipient(&manager);
57 if (deathRecipient == nullptr) {
58 LOG_ERROR("DataShareManagerImpl::LinkToDeath new ServiceDeathRecipient error.");
59 return;
60 }
61 if (!remote->AddDeathRecipient(deathRecipient)) {
62 LOG_ERROR("add death recipient failed");
63 }
64 LOG_ERROR("link to death success");
65 }
66
GetDataShareServiceProxy()67 sptr<DataShareServiceProxy> DataShareManagerImpl::GetDataShareServiceProxy()
68 {
69 if (dataMgrService_ == nullptr) {
70 dataMgrService_ = GetDistributedDataManager();
71 }
72 if (dataMgrService_ == nullptr) {
73 LOG_ERROR("Get distributed data manager failed!");
74 return nullptr;
75 }
76 auto remote = dataMgrService_->GetFeatureInterface("data_share");
77 if (remote == nullptr) {
78 LOG_ERROR("Get DataShare service failed!");
79 return nullptr;
80 }
81 return iface_cast<DataShareServiceProxy>(remote);
82 }
83
GetDataShareService()84 std::shared_ptr<IDataShareService> DataShareManagerImpl::GetDataShareService()
85 {
86 std::lock_guard<std::mutex> lock(mutex_);
87 if (dataShareService_ != nullptr) {
88 return dataShareService_;
89 }
90 auto service = GetDataShareServiceProxy();
91 if (service == nullptr) {
92 return nullptr;
93 }
94 sptr<IDataShareService> serviceBase = service;
95 LinkToDeath(serviceBase->AsObject().GetRefPtr());
96 dataShareService_ =
97 std::shared_ptr<DataShareServiceProxy>(service.GetRefPtr(), [holder = service](const auto *) {});
98 return dataShareService_;
99 }
100
GetInstance()101 DataShareManagerImpl& DataShareManagerImpl::GetInstance()
102 {
103 static DataShareManagerImpl manager;
104 return manager;
105 }
106
DataShareManagerImpl()107 DataShareManagerImpl::DataShareManagerImpl()
108 {
109 LOG_INFO("construct");
110 }
111
~DataShareManagerImpl()112 DataShareManagerImpl::~DataShareManagerImpl()
113 {
114 LOG_INFO("destroy");
115 }
116
ResetServiceHandle()117 void DataShareManagerImpl::ResetServiceHandle()
118 {
119 LOG_INFO("enter");
120 std::lock_guard<std::mutex> lock(mutex_);
121 dataMgrService_ = nullptr;
122 dataShareService_ = nullptr;
123 }
OnRemoteDied()124 void DataShareManagerImpl::OnRemoteDied()
125 {
126 LOG_INFO("datashare service has dead");
127 ResetServiceHandle();
128 }
129
DataShareKvServiceProxy(const sptr<IRemoteObject> & impl)130 DataShareKvServiceProxy::DataShareKvServiceProxy(const sptr<IRemoteObject> &impl)
131 : IRemoteProxy<DataShare::IKvStoreDataService>(impl)
132 {
133 LOG_DEBUG("Init data service proxy.");
134 }
135
GetFeatureInterface(const std::string & name)136 sptr<IRemoteObject> DataShareKvServiceProxy::GetFeatureInterface(const std::string &name)
137 {
138 LOG_INFO("GetDataShareService enter.");
139 MessageParcel data;
140 if (!data.WriteInterfaceToken(DataShareKvServiceProxy::GetDescriptor())) {
141 LOG_ERROR("Write descriptor failed");
142 return nullptr;
143 }
144 if (!data.WriteString(name)) {
145 LOG_ERROR("Write name failed");
146 return nullptr;
147 }
148
149 MessageParcel reply;
150 MessageOption mo { MessageOption::TF_SYNC };
151 int32_t error = Remote()->SendRequest(GET_FEATURE_INTERFACE, data, reply, mo);
152 if (error != 0) {
153 LOG_ERROR("SendRequest returned %{public}d", error);
154 return nullptr;
155 }
156 auto remoteObject = reply.ReadRemoteObject();
157 if (remoteObject == nullptr) {
158 LOG_ERROR("Remote object is nullptr!");
159 return nullptr;
160 }
161 return remoteObject;
162 }
163
164 } // namespace OHOS::DataShare