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 <iservice_registry.h>
22 #include <object_collector.h>
23
24 #include "idevmgr_hdi.h"
25 #include "iservmgr_hdi.h"
26
27 #define HDF_LOG_TAG idevmgr_client
28
29 namespace OHOS {
30 namespace HDI {
31 namespace DeviceManager {
32 namespace V1_0 {
33 #define HDF_MAX_HOST_COUNT 0xFF
34
35 std::mutex g_remoteMutex;
36
37 enum DevmgrCmdId : uint32_t {
38 DEVMGR_SERVICE_ATTACH_DEVICE_HOST = 1,
39 DEVMGR_SERVICE_ATTACH_DEVICE,
40 DEVMGR_SERVICE_DETACH_DEVICE,
41 DEVMGR_SERVICE_LOAD_DEVICE,
42 DEVMGR_SERVICE_UNLOAD_DEVICE,
43 DEVMGR_SERVICE_QUERY_DEVICE,
44 DEVMGR_SERVICE_LIST_ALL_DEVICE,
45 DEVMGR_SERVICE_LIST_ALL_HOST,
46 };
47
48 class DeviceManagerProxy : public IProxyBroker<IDeviceManager> {
49 public:
DeviceManagerProxy(const sptr<IRemoteObject> & impl)50 explicit DeviceManagerProxy(const sptr<IRemoteObject> &impl) : IProxyBroker<IDeviceManager>(impl) {}
~DeviceManagerProxy()51 ~DeviceManagerProxy() {}
52 int32_t LoadDevice(const std::string &serviceName) override;
53 int32_t UnloadDevice(const std::string &serviceName) override;
54 int32_t ListAllDevice(std::vector<HdiDevHostInfo> &deviceInfos) override;
55 int32_t ListAllHost(std::vector<int> &pidList) override;
56
57 private:
58 static inline BrokerDelegator<DeviceManagerProxy> delegator_;
59 };
60
LoadDevice(const std::string & serviceName)61 int32_t DeviceManagerProxy::LoadDevice(const std::string &serviceName)
62 {
63 MessageParcel data;
64 MessageParcel reply;
65 MessageOption option;
66 HDF_LOGI("load device: %{public}s", serviceName.data());
67 if (!data.WriteInterfaceToken(GetDescriptor())) {
68 return HDF_FAILURE;
69 }
70 if (!data.WriteCString(serviceName.data())) {
71 return HDF_FAILURE;
72 }
73
74 std::unique_lock<std::mutex> lock(g_remoteMutex);
75 if (Remote() == nullptr) {
76 HDF_LOGE("invalid param Remote()");
77 return HDF_ERR_INVALID_PARAM;
78 }
79 int status = Remote()->SendRequest(DEVMGR_SERVICE_LOAD_DEVICE, data, reply, option);
80 lock.unlock();
81 if (status != HDF_SUCCESS) {
82 HDF_LOGE("load device failed, %{public}d", status);
83 }
84 return status;
85 }
86
UnloadDevice(const std::string & serviceName)87 int32_t DeviceManagerProxy::UnloadDevice(const std::string &serviceName)
88 {
89 MessageParcel data;
90 MessageParcel reply;
91 MessageOption option;
92 HDF_LOGI("unload device: %{public}s", serviceName.data());
93 if (!data.WriteInterfaceToken(DeviceManagerProxy::GetDescriptor())) {
94 return HDF_FAILURE;
95 }
96 if (!data.WriteCString(serviceName.data())) {
97 return HDF_FAILURE;
98 }
99
100 std::unique_lock<std::mutex> lock(g_remoteMutex);
101 if (Remote() == nullptr) {
102 HDF_LOGE("invalid param Remote()");
103 return HDF_ERR_INVALID_PARAM;
104 }
105 int status = Remote()->SendRequest(DEVMGR_SERVICE_UNLOAD_DEVICE, data, reply, option);
106 lock.unlock();
107 if (status != HDF_SUCCESS) {
108 HDF_LOGE("unload device failed, %{public}d", status);
109 }
110 return status;
111 }
112
HdfDevMgrDbgFillDeviceInfo(std::vector<HdiDevHostInfo> & hostInfos,MessageParcel & reply)113 static bool HdfDevMgrDbgFillDeviceInfo(std::vector<HdiDevHostInfo> &hostInfos, MessageParcel &reply)
114 {
115 while (true) {
116 struct DevInfo devInfo;
117 uint32_t devCnt;
118 struct HdiDevHostInfo hostInfo;
119 const char *name = reply.ReadCString();
120 if (name == nullptr) {
121 break;
122 }
123 hostInfo.hostName = name;
124 if (!reply.ReadUint32(hostInfo.hostId)) {
125 HDF_LOGE("failed to read hostId of DevInfo");
126 return false;
127 }
128
129 if (!reply.ReadUint32(devCnt)) {
130 HDF_LOGE("failed to read size of DevInfo");
131 return false;
132 }
133
134 if (devCnt > hostInfo.devInfo.max_size()) {
135 HDF_LOGE("invalid len of device info");
136 return false;
137 }
138
139 for (uint32_t i = 0; i < devCnt; i++) {
140 if (reply.GetReadableBytes() == 0) {
141 HDF_LOGE("no enough data to read");
142 return false;
143 }
144
145 name = reply.ReadCString();
146 devInfo.deviceName = (name == nullptr) ? "" : name;
147 if (!reply.ReadUint32(devInfo.devId)) {
148 HDF_LOGE("failed to read devId of DevInfo");
149 return false;
150 }
151
152 name = reply.ReadCString();
153 devInfo.servName = (name == nullptr) ? "" : name;
154 hostInfo.devInfo.push_back(devInfo);
155 }
156 hostInfos.push_back(hostInfo);
157 }
158 return true;
159 }
160
ListAllDevice(std::vector<HdiDevHostInfo> & deviceInfos)161 int32_t DeviceManagerProxy::ListAllDevice(std::vector<HdiDevHostInfo> &deviceInfos)
162 {
163 MessageParcel data;
164 MessageParcel reply;
165
166 if (!data.WriteInterfaceToken(GetDescriptor())) {
167 return HDF_FAILURE;
168 }
169
170 MessageOption option;
171 std::unique_lock<std::mutex> lock(g_remoteMutex);
172 if (Remote() == nullptr) {
173 HDF_LOGE("invalid param Remote()");
174 return HDF_ERR_INVALID_PARAM;
175 }
176 int status = Remote()->SendRequest(DEVMGR_SERVICE_LIST_ALL_DEVICE, data, reply, option);
177 lock.unlock();
178 if (status != HDF_SUCCESS) {
179 HDF_LOGE("list all device info failed, %{public}d", status);
180 return status;
181 }
182
183 if (!HdfDevMgrDbgFillDeviceInfo(deviceInfos, reply)) {
184 HDF_LOGE("failed to read all device info");
185 return HDF_ERR_INVALID_PARAM;
186 }
187 return status;
188 }
189
HdfDevMgrFillPidList(std::vector<int> & pidList,MessageParcel & reply)190 static int32_t HdfDevMgrFillPidList(std::vector<int> &pidList, MessageParcel &reply)
191 {
192 uint32_t pidCount = 0;
193 if (!reply.ReadUint32(pidCount)) {
194 HDF_LOGE("failed to read pid count");
195 return HDF_FAILURE;
196 }
197
198 if (pidCount >= HDF_MAX_HOST_COUNT) {
199 HDF_LOGE("invalid host count, %{public}d", pidCount);
200 return HDF_ERR_OUT_OF_RANGE;
201 }
202
203 int pid = -1;
204 for (uint32_t i = 0; i < pidCount; ++i) {
205 if (!reply.ReadInt32(pid)) {
206 HDF_LOGE("failed to read pid");
207 return HDF_FAILURE;
208 }
209 pidList.push_back(pid);
210 }
211
212 return HDF_SUCCESS;
213 }
214
ListAllHost(std::vector<int> & pidList)215 int32_t DeviceManagerProxy::ListAllHost(std::vector<int> &pidList)
216 {
217 MessageParcel data;
218 MessageParcel reply;
219 if (!data.WriteInterfaceToken(GetDescriptor())) {
220 return HDF_FAILURE;
221 }
222
223 MessageOption option;
224 std::unique_lock<std::mutex> lock(g_remoteMutex);
225 if (Remote() == nullptr) {
226 HDF_LOGE("invalid param Remote()");
227 return HDF_ERR_INVALID_PARAM;
228 }
229 int status = Remote()->SendRequest(
230 static_cast<uint32_t>(DEVMGR_SERVICE_LIST_ALL_HOST), data, reply, option);
231 lock.unlock();
232 if (status != HDF_SUCCESS) {
233 HDF_LOGE("list all host failed, %{public}d", status);
234 return status;
235 }
236
237 int32_t ret = HdfDevMgrFillPidList(pidList, reply);
238 if (ret != HDF_SUCCESS) {
239 HDF_LOGE("fill pid list failed");
240 }
241
242 return ret;
243 }
244
Get()245 sptr<IDeviceManager> IDeviceManager::Get()
246 {
247 auto servmgr = ServiceManager::V1_0::IServiceManager::Get();
248 if (servmgr == nullptr) {
249 HDF_LOGE("failed to get hdi service manager");
250 return nullptr;
251 }
252
253 std::unique_lock<std::mutex> lock(g_remoteMutex);
254 sptr<IRemoteObject> remote = servmgr->GetService("hdf_device_manager");
255 if (remote != nullptr) {
256 return hdi_facecast<IDeviceManager>(remote);
257 }
258
259 HDF_LOGE("hdf device manager not exist");
260 return nullptr;
261 }
262 } // namespace V1_0
263 } // namespace DeviceManager
264 } // namespace HDI
265 } // namespace OHOS
266