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 "client_adaptor.h"
17
18 #include <thread>
19
20 #include "logger.h"
21 #include "iservice_registry.h"
22 #include "itypes_util.h"
23 #include "objectstore_errors.h"
24
25 namespace OHOS::ObjectStore {
26 std::shared_ptr<ObjectStoreDataServiceProxy> ClientAdaptor::distributedDataMgr_ = nullptr;
27
28 using KvStoreCode = OHOS::DistributedObject::ObjectStoreService::KvStoreServiceInterfaceCode;
29
GetObjectService()30 sptr<OHOS::DistributedObject::IObjectService> ClientAdaptor::GetObjectService()
31 {
32 if (distributedDataMgr_ == nullptr) {
33 distributedDataMgr_ = GetDistributedDataManager();
34 }
35 if (distributedDataMgr_ == nullptr) {
36 LOG_ERROR("get distributed data manager failed");
37 return nullptr;
38 }
39
40 auto remote = distributedDataMgr_->GetFeatureInterface("data_object");
41 if (remote == nullptr) {
42 LOG_ERROR("get object service failed");
43 return nullptr;
44 }
45 return iface_cast<DistributedObject::IObjectService>(remote);
46 }
47
GetDistributedDataManager()48 std::shared_ptr<ObjectStoreDataServiceProxy> ClientAdaptor::GetDistributedDataManager()
49 {
50 int retry = 0;
51 while (++retry <= GET_SA_RETRY_TIMES) {
52 auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
53 if (manager == nullptr) {
54 LOG_ERROR("get system ability manager failed");
55 return nullptr;
56 }
57 LOG_INFO("get distributed data manager %{public}d", retry);
58 auto remoteObject = manager->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
59 if (remoteObject == nullptr) {
60 std::this_thread::sleep_for(std::chrono::seconds(RETRY_INTERVAL));
61 continue;
62 }
63 LOG_INFO("get distributed data manager success");
64 sptr<ObjectStoreDataServiceProxy> proxy = new (std::nothrow)ObjectStoreDataServiceProxy(remoteObject);
65 if (proxy == nullptr) {
66 LOG_ERROR("new ObjectStoreDataServiceProxy fail.");
67 return nullptr;
68 }
69 return std::shared_ptr<ObjectStoreDataServiceProxy>(proxy.GetRefPtr(), [holder = proxy](const auto *) {});
70 }
71
72 LOG_ERROR("get distributed data manager failed");
73 return nullptr;
74 }
75
RegisterClientDeathListener(const std::string & appId,sptr<IRemoteObject> remoteObject)76 uint32_t ClientAdaptor::RegisterClientDeathListener(const std::string &appId, sptr<IRemoteObject> remoteObject)
77 {
78 if (distributedDataMgr_ == nullptr) {
79 distributedDataMgr_ = GetDistributedDataManager();
80 }
81 if (distributedDataMgr_ == nullptr) {
82 LOG_ERROR("get distributed data manager failed");
83 return ERR_EXIST;
84 }
85
86 auto status = distributedDataMgr_->RegisterClientDeathObserver(appId, remoteObject);
87 if (status != SUCCESS) {
88 LOG_ERROR("RegisterClientDeathObserver failed");
89 return ERR_EXIST;
90 }
91 return SUCCESS;
92 }
93
ObjectStoreDataServiceProxy(const sptr<IRemoteObject> & impl)94 ObjectStoreDataServiceProxy::ObjectStoreDataServiceProxy(const sptr<IRemoteObject> &impl)
95 : IRemoteProxy<DistributedObject::IKvStoreDataService>(impl)
96 {
97 LOG_INFO("init data service proxy.");
98 }
99
GetFeatureInterface(const std::string & name)100 sptr<IRemoteObject> ObjectStoreDataServiceProxy::GetFeatureInterface(const std::string &name)
101 {
102 MessageParcel data;
103 if (!data.WriteInterfaceToken(ObjectStoreDataServiceProxy::GetDescriptor())) {
104 LOG_ERROR("write descriptor failed");
105 return nullptr;
106 }
107
108 if (!ITypesUtil::Marshal(data, name)) {
109 LOG_ERROR("write name failed");
110 return nullptr;
111 }
112
113 MessageParcel reply;
114 MessageOption mo { MessageOption::TF_SYNC };
115 sptr<IRemoteObject> remote = Remote();
116 if (remote == nullptr) {
117 LOG_ERROR("SendRequest remote is nullptr.");
118 return nullptr;
119 }
120 int32_t error =
121 remote->SendRequest(static_cast<uint32_t>(KvStoreCode::GET_FEATURE_INTERFACE), data, reply, mo);
122 if (error != 0) {
123 LOG_ERROR("SendRequest returned %{public}d", error);
124 return nullptr;
125 }
126
127 sptr<IRemoteObject> remoteObject;
128 if (!ITypesUtil::Unmarshal(reply, remoteObject)) {
129 LOG_ERROR("remote object is nullptr");
130 return nullptr;
131 }
132 return remoteObject;
133 }
134
RegisterClientDeathObserver(const std::string & appId,sptr<IRemoteObject> observer)135 uint32_t ObjectStoreDataServiceProxy::RegisterClientDeathObserver(
136 const std::string &appId, sptr<IRemoteObject> observer)
137 {
138 MessageParcel data;
139 MessageParcel reply;
140 if (!data.WriteInterfaceToken(ObjectStoreDataServiceProxy::GetDescriptor())) {
141 LOG_ERROR("write descriptor failed");
142 return ERR_IPC;
143 }
144 if (observer == nullptr) {
145 return ERR_INVALID_ARGS;
146 }
147 if (!ITypesUtil::Marshal(data, appId, observer)) {
148 LOG_ERROR("remote observer fail");
149 return ERR_IPC;
150 }
151
152 MessageOption mo { MessageOption::TF_SYNC };
153 sptr<IRemoteObject> remoteObject = Remote();
154 if (remoteObject == nullptr) {
155 LOG_ERROR("SendRequest remoteObject is nullptr.");
156 return ERR_IPC;
157 }
158 int32_t error =
159 remoteObject->SendRequest(static_cast<uint32_t>(KvStoreCode::REGISTERCLIENTDEATHOBSERVER), data, reply, mo);
160 if (error != 0) {
161 LOG_WARN("failed during IPC. errCode %d", error);
162 return ERR_IPC;
163 }
164 return static_cast<uint32_t>(reply.ReadInt32());
165 }
166 }