1 /*
2 * Copyright (c) 2021-2023 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 <mutex>
17
18 #include <hdf_base.h>
19 #include <hdf_core_log.h>
20 #include <iproxy_broker.h>
21 #include <iremote_stub.h>
22 #include <iservice_registry.h>
23 #include <object_collector.h>
24 #include <string_ex.h>
25
26 #include "hdf_device_manager_interface_code.h"
27 #include "iservmgr_hdi.h"
28
29 #define HDF_LOG_TAG hdi_servmgr_client
30
31 using OHOS::HDI::HdfDeviceManager::HdfDeviceManagerInterfaceCode;
32
33 namespace OHOS {
34 namespace HDI {
35 namespace ServiceManager {
36 namespace V1_0 {
37 constexpr int DEVICE_SERVICE_MANAGER_SA_ID = 5100;
38 std::mutex g_remoteMutex;
39
40 class ServiceManagerProxy : public IProxyBroker<IServiceManager> {
41 public:
ServiceManagerProxy(const sptr<IRemoteObject> & impl)42 explicit ServiceManagerProxy(const sptr<IRemoteObject> &impl) : IProxyBroker<IServiceManager>(impl) {}
~ServiceManagerProxy()43 ~ServiceManagerProxy() {}
44
45 sptr<IRemoteObject> GetService(const char *serviceName) override;
46 int32_t ListAllService(std::vector<HdiServiceInfo> &serviceInfos) override;
47 int32_t RegisterServiceStatusListener(sptr<IServStatListener> listener, uint16_t deviceClass) override;
48 int32_t UnregisterServiceStatusListener(sptr<IServStatListener> listener) override;
49 int32_t ListServiceByInterfaceDesc(std::vector<std::string> &serviceNames, const char *interfaceDesc) override;
50
51 private:
52 static inline BrokerDelegator<ServiceManagerProxy> delegator_;
53 };
54
Get()55 sptr<IServiceManager> IServiceManager::Get()
56 {
57 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
58 if (saManager == nullptr) {
59 HDF_LOGE("failed to get sa manager");
60 return nullptr;
61 }
62
63 std::unique_lock<std::mutex> lock(g_remoteMutex);
64 sptr<IRemoteObject> remote = saManager->GetSystemAbility(DEVICE_SERVICE_MANAGER_SA_ID);
65 if (remote != nullptr) {
66 return new ServiceManagerProxy(remote);
67 }
68
69 HDF_LOGE("failed to get sa hdf service manager");
70 return nullptr;
71 }
72
RegisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener,uint16_t deviceClass)73 int32_t ServiceManagerProxy::RegisterServiceStatusListener(
74 ::OHOS::sptr<IServStatListener> listener, uint16_t deviceClass)
75 {
76 MessageParcel data;
77 MessageParcel reply;
78 MessageOption option;
79
80 if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteUint16(deviceClass) ||
81 !data.WriteRemoteObject(listener->AsObject())) {
82 return HDF_FAILURE;
83 }
84
85 std::unique_lock<std::mutex> lock(g_remoteMutex);
86 if (Remote() == nullptr) {
87 HDF_LOGE("invalid param Remote()");
88 return HDF_ERR_INVALID_PARAM;
89 }
90 int status = Remote()->SendRequest(
91 static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_REGISTER_SVCLISTENER), data, reply, option);
92 lock.unlock();
93 if (status) {
94 HDF_LOGE("failed to register servstat listener, %{public}d", status);
95 }
96 return status;
97 }
98
UnregisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener)99 int32_t ServiceManagerProxy::UnregisterServiceStatusListener(::OHOS::sptr<IServStatListener> listener)
100 {
101 MessageParcel data;
102 MessageParcel reply;
103 MessageOption option;
104
105 if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteRemoteObject(listener->AsObject())) {
106 return HDF_FAILURE;
107 }
108
109 std::unique_lock<std::mutex> lock(g_remoteMutex);
110 if (Remote() == nullptr) {
111 HDF_LOGE("invalid param Remote()");
112 return HDF_ERR_INVALID_PARAM;
113 }
114 int status = Remote()->SendRequest(
115 static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_UNREGISTER_SVCLISTENER), data, reply,
116 option);
117 lock.unlock();
118 if (status) {
119 HDF_LOGE("failed to unregister servstat listener, %{public}d", status);
120 }
121 return status;
122 }
123
GetService(const char * serviceName)124 sptr<IRemoteObject> ServiceManagerProxy::GetService(const char *serviceName)
125 {
126 if (nullptr == serviceName) {
127 HDF_LOGE("serviceName is nullptr");
128 return nullptr;
129 }
130
131 MessageParcel data;
132 MessageParcel reply;
133 if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteCString(serviceName)) {
134 return nullptr;
135 }
136
137 MessageOption option;
138 std::unique_lock<std::mutex> lock(g_remoteMutex);
139 if (Remote() == nullptr) {
140 HDF_LOGE("invalid param Remote()");
141 return nullptr;
142 }
143 int status = Remote()->SendRequest(
144 static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_GET_SERVICE), data, reply, option);
145 lock.unlock();
146 if (status) {
147 HDF_LOGE("get hdi service %{public}s failed, %{public}d", serviceName, status);
148 return nullptr;
149 }
150 HDF_LOGD("get hdi service %{public}s success ", serviceName);
151 return reply.ReadRemoteObject();
152 }
153
HdfDevMgrDbgFillServiceInfo(std::vector<HdiServiceInfo> & serviceInfos,MessageParcel & reply)154 static void HdfDevMgrDbgFillServiceInfo(std::vector<HdiServiceInfo> &serviceInfos, MessageParcel &reply)
155 {
156 while (true) {
157 HdiServiceInfo info;
158 const char *servName = reply.ReadCString();
159 if (servName == nullptr) {
160 break;
161 }
162 info.serviceName = servName;
163 info.devClass = reply.ReadUint16();
164 info.devId = reply.ReadUint32();
165 serviceInfos.push_back(info);
166 }
167 return;
168 }
169
ListAllService(std::vector<HdiServiceInfo> & serviceInfos)170 int32_t ServiceManagerProxy::ListAllService(std::vector<HdiServiceInfo> &serviceInfos)
171 {
172 MessageParcel data;
173 MessageParcel reply;
174 if (!data.WriteInterfaceToken(GetDescriptor())) {
175 return HDF_FAILURE;
176 }
177
178 MessageOption option;
179 std::unique_lock<std::mutex> lock(g_remoteMutex);
180 if (Remote() == nullptr) {
181 HDF_LOGE("invalid param Remote()");
182 return HDF_ERR_INVALID_PARAM;
183 }
184 int status = Remote()->SendRequest(
185 static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_LIST_ALL_SERVICE), data, reply, option);
186 lock.unlock();
187 if (status != HDF_SUCCESS) {
188 HDF_LOGE("list all service info failed, %{public}d", status);
189 return status;
190 } else {
191 HdfDevMgrDbgFillServiceInfo(serviceInfos, reply);
192 }
193 HDF_LOGD("get all service info success");
194 return status;
195 }
196
ListServiceByInterfaceDesc(std::vector<std::string> & serviceNames,const char * interfaceDesc)197 int32_t ServiceManagerProxy::ListServiceByInterfaceDesc(
198 std::vector<std::string> &serviceNames, const char *interfaceDesc)
199 {
200 MessageParcel data;
201 MessageParcel reply;
202 if (interfaceDesc == nullptr || strlen(interfaceDesc) == 0) {
203 HDF_LOGE("%{public}s: invalid parameter, interfaceDesc is null or empty", __func__);
204 return HDF_ERR_INVALID_PARAM;
205 }
206 if (!data.WriteInterfaceToken(GetDescriptor()) || !data.WriteCString(interfaceDesc)) {
207 return HDF_FAILURE;
208 }
209
210 MessageOption option;
211 std::unique_lock<std::mutex> lock(g_remoteMutex);
212 if (Remote() == nullptr) {
213 HDF_LOGE("invalid param Remote()");
214 return HDF_ERR_INVALID_PARAM;
215 }
216 int status = Remote()->SendRequest(
217 static_cast<uint32_t>(HdfDeviceManagerInterfaceCode::DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC), data, reply,
218 option);
219 lock.unlock();
220 if (status != HDF_SUCCESS) {
221 HDF_LOGE("get hdi service collection by %{public}s failed, %{public}d", interfaceDesc, status);
222 return status;
223 }
224
225 uint32_t serviceNum = 0;
226 if (!reply.ReadUint32(serviceNum)) {
227 HDF_LOGE("failed to read number of service");
228 return HDF_ERR_INVALID_PARAM;
229 }
230
231 if (serviceNum > serviceNames.max_size()) {
232 HDF_LOGE("invalid len of serviceNames");
233 return HDF_ERR_INVALID_PARAM;
234 }
235
236 for (uint32_t i = 0; i < serviceNum; i++) {
237 if (reply.GetReadableBytes() == 0) {
238 HDF_LOGE("no enough data to read");
239 return HDF_ERR_INVALID_PARAM;
240 }
241
242 const char *serviceName = reply.ReadCString();
243 if (serviceName == NULL) {
244 break;
245 }
246 serviceNames.push_back(serviceName);
247 }
248
249 HDF_LOGD("get hdi service collection by %{public}s successfully", interfaceDesc);
250 return status;
251 }
252 } // namespace V1_0
253 } // namespace ServiceManager
254 } // namespace HDI
255 } // namespace OHOS