1 /*
2 * Copyright (c) 2021-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 "devsvc_manager_stub.h"
17
18 #ifdef WITH_SELINUX
19 #include <hdf_service_checker.h>
20 #endif
21
22 #include "devmgr_service_stub.h"
23 #include "devsvc_listener_holder.h"
24 #include "devsvc_manager_proxy.h"
25 #include "hdf_cstring.h"
26 #include "hdf_log.h"
27 #include "hdf_remote_service.h"
28 #include "hdf_sbuf.h"
29 #include "hdf_slist.h"
30 #include "osal_mem.h"
31 #include "securec.h"
32
33 #define HDF_LOG_TAG devsvc_manager_stub
34
AddServicePermCheck(const char * servName)35 static int32_t AddServicePermCheck(const char *servName)
36 {
37 #ifdef WITH_SELINUX
38 pid_t callingPid = HdfRemoteGetCallingPid();
39 if (HdfAddServiceCheck(callingPid, servName) != 0) {
40 HDF_LOGE("[selinux] %{public}d haven't \"add service\" permission to %{public}s", callingPid, servName);
41 return HDF_ERR_NOPERM;
42 }
43 #endif
44 return HDF_SUCCESS;
45 }
46
GetServicePermCheck(const char * servName)47 static int32_t GetServicePermCheck(const char *servName)
48 {
49 #ifdef WITH_SELINUX
50 pid_t callingPid = HdfRemoteGetCallingPid();
51 if (HdfGetServiceCheck(callingPid, servName) != 0) {
52 HDF_LOGE("[selinux] %{public}d haven't \"get service\" permission to %{public}s", callingPid, servName);
53 return HDF_ERR_NOPERM;
54 }
55 #endif
56
57 return HDF_SUCCESS;
58 }
59
ListServicePermCheck(void)60 static int32_t ListServicePermCheck(void)
61 {
62 #ifdef WITH_SELINUX
63 pid_t callingPid = HdfRemoteGetCallingPid();
64 if (HdfListServiceCheck(callingPid) != 0) {
65 HDF_LOGE("[selinux] %{public}d haven't \"list service\" permission", callingPid);
66 return HDF_ERR_NOPERM;
67 }
68 #endif
69
70 return HDF_SUCCESS;
71 }
72
CheckServiceObjectValidNoLock(const struct DevSvcManagerStub * stub,const struct HdfDeviceObject * service)73 static bool CheckServiceObjectValidNoLock(const struct DevSvcManagerStub *stub, const struct HdfDeviceObject *service)
74 {
75 if (service == NULL) {
76 HDF_LOGW("%{public}s service object is null", __func__);
77 return false;
78 }
79
80 struct HdfSListIterator it;
81 HdfSListIteratorInit(&it, &stub->devObjHolderList);
82 while (HdfSListIteratorHasNext(&it)) {
83 struct HdfSListNode *node = HdfSListIteratorNext(&it);
84 struct HdfDeviceObjectHolder *holder =
85 HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
86
87 if (((uintptr_t)(&holder->devObj) == (uintptr_t)service) && (holder->serviceName != NULL) &&
88 (service->priv != NULL) && (strcmp(holder->serviceName, (char *)service->priv) == 0)) {
89 HDF_LOGD("%{public}s %{public}s service object is valid", __func__, holder->serviceName);
90 return true;
91 }
92 }
93
94 HDF_LOGW("%{public}s service object is invalid", __func__);
95 return false;
96 }
97
CheckRemoteObjectValidNoLock(const struct DevSvcManagerStub * stub,const struct HdfRemoteService * service)98 static bool CheckRemoteObjectValidNoLock(const struct DevSvcManagerStub *stub, const struct HdfRemoteService *service)
99 {
100 if (service == NULL) {
101 HDF_LOGW("%{public}s remote object is null", __func__);
102 return false;
103 }
104
105 struct HdfSListIterator it;
106 HdfSListIteratorInit(&it, &stub->devObjHolderList);
107 while (HdfSListIteratorHasNext(&it)) {
108 struct HdfSListNode *node = HdfSListIteratorNext(&it);
109 struct HdfDeviceObjectHolder *holder =
110 HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
111
112 if (holder->remoteSvcAddr == (uintptr_t)service) {
113 HDF_LOGD("%{public}s remote object is valid", __func__);
114 return true;
115 }
116 }
117
118 HDF_LOGW("%{public}s remote object is invalid", __func__);
119 return false;
120 }
121
ReleaseServiceObjectHolder(struct DevSvcManagerStub * stub,struct HdfDeviceObjectHolder * devObjHolder)122 static void ReleaseServiceObjectHolder(struct DevSvcManagerStub *stub, struct HdfDeviceObjectHolder *devObjHolder)
123 {
124 if (devObjHolder != NULL) {
125 struct HdfDeviceObject *serviceObject = &devObjHolder->devObj;
126 struct HdfRemoteService *serviceRemote = (struct HdfRemoteService *)serviceObject->service;
127 HdfRemoteServiceRemoveDeathRecipient(serviceRemote, &stub->recipient);
128 HdfRemoteServiceRecycle((struct HdfRemoteService *)serviceObject->service);
129 serviceObject->service = NULL;
130 OsalMemFree(serviceObject->priv);
131 serviceObject->priv = NULL;
132 OsalMemFree(devObjHolder->serviceName);
133 devObjHolder->serviceName = NULL;
134 OsalMemFree(devObjHolder);
135 }
136 }
137
ObtainServiceObject(struct DevSvcManagerStub * stub,const char * name,struct HdfRemoteService * service)138 static struct HdfDeviceObject *ObtainServiceObject(
139 struct DevSvcManagerStub *stub, const char *name, struct HdfRemoteService *service)
140 {
141 struct HdfDeviceObjectHolder *serviceObjectHolder = OsalMemCalloc(sizeof(*serviceObjectHolder));
142 if (serviceObjectHolder == NULL) {
143 return NULL;
144 }
145
146 serviceObjectHolder->remoteSvcAddr = (uintptr_t)service;
147 serviceObjectHolder->serviceName = (void *)HdfStringCopy(name);
148 if (serviceObjectHolder->serviceName == NULL) {
149 OsalMemFree(serviceObjectHolder);
150 return NULL;
151 }
152
153 struct HdfDeviceObject *serviceObject = &serviceObjectHolder->devObj;
154 serviceObject->priv = (void *)HdfStringCopy(name);
155 if (serviceObject->priv == NULL) {
156 OsalMemFree(serviceObjectHolder->serviceName);
157 OsalMemFree(serviceObjectHolder);
158 return NULL;
159 }
160 serviceObject->service = (struct IDeviceIoService *)service;
161 service->target = (struct HdfObject *)serviceObject;
162
163 OsalMutexLock(&stub->devSvcStubMutex);
164 HdfSListAdd(&stub->devObjHolderList, &serviceObjectHolder->entry);
165 OsalMutexUnlock(&stub->devSvcStubMutex);
166
167 HdfRemoteServiceAddDeathRecipient(service, &stub->recipient);
168
169 return serviceObject;
170 }
171
ReleaseServiceObject(struct DevSvcManagerStub * stub,struct HdfDeviceObject * serviceObject)172 static void ReleaseServiceObject(struct DevSvcManagerStub *stub, struct HdfDeviceObject *serviceObject)
173 {
174 OsalMutexLock(&stub->devSvcStubMutex);
175 if (serviceObject == NULL) {
176 OsalMutexUnlock(&stub->devSvcStubMutex);
177 return;
178 }
179
180 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
181 OsalMutexUnlock(&stub->devSvcStubMutex);
182 return;
183 }
184
185 struct HdfRemoteService *serviceRemote = (struct HdfRemoteService *)serviceObject->service;
186 HdfRemoteServiceRemoveDeathRecipient(serviceRemote, &stub->recipient);
187
188 struct HdfDeviceObjectHolder *serviceObjectHolder = (struct HdfDeviceObjectHolder *)serviceObject;
189 HdfSListRemove(&stub->devObjHolderList, &serviceObjectHolder->entry);
190 ReleaseServiceObjectHolder(stub, serviceObjectHolder);
191
192 OsalMutexUnlock(&stub->devSvcStubMutex);
193 }
194
DevSvcMgrStubGetPara(struct HdfSBuf * data,struct HdfServiceInfo * info,struct HdfRemoteService ** service)195 static int32_t DevSvcMgrStubGetPara(
196 struct HdfSBuf *data, struct HdfServiceInfo *info, struct HdfRemoteService **service)
197 {
198 int ret = HDF_FAILURE;
199 info->servName = HdfSbufReadString(data);
200 if (info->servName == NULL) {
201 HDF_LOGE("%{public}s failed, name is null", __func__);
202 return ret;
203 }
204 ret = AddServicePermCheck(info->servName);
205 if (ret != HDF_SUCCESS) {
206 return ret;
207 }
208
209 info->devClass = DEVICE_CLASS_DEFAULT;
210 if (!HdfSbufReadUint16(data, &info->devClass)) {
211 HDF_LOGE("%{public}s failed, devClass invalid", __func__);
212 return HDF_FAILURE;
213 }
214 if (!HdfSbufReadUint32(data, &info->devId)) {
215 HDF_LOGE("%{public}s failed, devId invalid", __func__);
216 return HDF_FAILURE;
217 }
218
219 *service = HdfSbufReadRemoteService(data);
220 if (*service == NULL) {
221 HDF_LOGE("%{public}s failed, service is null", __func__);
222 return HDF_FAILURE;
223 }
224 info->servInfo = HdfSbufReadString(data);
225 info->interfaceDesc = HdfSbufReadString(data);
226 return HDF_SUCCESS;
227 }
228
DevSvcManagerStubAddService(struct IDevSvcManager * super,struct HdfSBuf * data)229 static int32_t DevSvcManagerStubAddService(struct IDevSvcManager *super, struct HdfSBuf *data)
230 {
231 int ret = HDF_FAILURE;
232 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
233 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
234 HDF_LOGE("%{public}s: invalid interface token", __func__);
235 return HDF_ERR_INVALID_PARAM;
236 }
237 struct HdfServiceInfo info;
238 struct HdfRemoteService *service = NULL;
239 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
240 if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) {
241 return ret;
242 }
243
244 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
245 if (serviceObject == NULL) {
246 return HDF_ERR_MALLOC_FAIL;
247 }
248
249 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
250 ret = super->AddService(super, serviceObject, &info);
251 if (ret != HDF_SUCCESS) {
252 ReleaseServiceObject(stub, serviceObject);
253 } else {
254 ReleaseServiceObject(stub, oldServiceObject);
255 }
256 HDF_LOGI("add service %{public}s, %{public}d", info.servName, ret);
257 return ret;
258 }
259
DevSvcManagerStubUpdateService(struct IDevSvcManager * super,struct HdfSBuf * data)260 static int32_t DevSvcManagerStubUpdateService(struct IDevSvcManager *super, struct HdfSBuf *data)
261 {
262 int ret = HDF_FAILURE;
263 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
264 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
265 HDF_LOGE("%{public}s: invalid interface token", __func__);
266 return HDF_ERR_INVALID_PARAM;
267 }
268
269 struct HdfRemoteService *service = NULL;
270 struct HdfServiceInfo info;
271 (void)memset_s(&info, sizeof(info), 0, sizeof(info));
272 if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) {
273 return ret;
274 }
275
276 struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
277 if (oldServiceObject == NULL) {
278 HDF_LOGE("update service %{public}s not exist", info.servName);
279 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
280 }
281
282 struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
283 if (serviceObject == NULL) {
284 return HDF_ERR_MALLOC_FAIL;
285 }
286
287 ret = super->UpdateService(super, serviceObject, &info);
288 if (ret != HDF_SUCCESS) {
289 ReleaseServiceObject(stub, serviceObject);
290 } else {
291 ReleaseServiceObject(stub, oldServiceObject);
292 }
293 HDF_LOGI("update service %{public}s, %{public}d", info.servName, ret);
294 return ret;
295 }
296
DevSvcManagerStubGetService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)297 static int32_t DevSvcManagerStubGetService(struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
298 {
299 int ret = HDF_FAILURE;
300 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
301 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
302 HDF_LOGE("%{public}s: invalid interface token", __func__);
303 return HDF_ERR_INVALID_PARAM;
304 }
305 const char *name = HdfSbufReadString(data);
306 if (name == NULL) {
307 HDF_LOGE("%{public}s failed, name is null", __func__);
308 return ret;
309 }
310 ret = GetServicePermCheck(name);
311 if (ret != HDF_SUCCESS) {
312 return ret;
313 }
314 struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
315 if (serviceObject == NULL) {
316 HDF_LOGE("StubGetService service %{public}s not found", name);
317 return HDF_FAILURE;
318 }
319
320 const char *svcMgrName = "hdf_device_manager";
321 if (strcmp(name, svcMgrName) != 0) {
322 OsalMutexLock(&stub->devSvcStubMutex);
323 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
324 OsalMutexUnlock(&stub->devSvcStubMutex);
325 HDF_LOGE("StubGetService service %{public}s is invalid", name);
326 return HDF_FAILURE;
327 }
328 }
329 struct HdfRemoteService *remoteService = (struct HdfRemoteService *)serviceObject->service;
330 if (remoteService != NULL) {
331 HdfSbufWriteRemoteService(reply, remoteService);
332 ret = HDF_SUCCESS;
333 HDF_LOGI("StubGetService service %{public}s found", name);
334 } else {
335 HDF_LOGE("StubGetService %{public}s remoteService is null", name);
336 ret = HDF_FAILURE;
337 }
338
339 if (strcmp(name, svcMgrName) != 0) {
340 OsalMutexUnlock(&stub->devSvcStubMutex);
341 }
342
343 return ret;
344 }
345
DevSvcManagerStubListAllService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)346 static int32_t DevSvcManagerStubListAllService(
347 struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
348 {
349 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
350 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
351 HDF_LOGE("%{public}s: invalid interface token", __func__);
352 return HDF_ERR_INVALID_PARAM;
353 }
354 int ret = ListServicePermCheck();
355 if (ret != HDF_SUCCESS) {
356 return ret;
357 }
358 super->ListAllService(super, reply);
359
360 return HDF_SUCCESS;
361 }
362
DevSvcManagerStubListServiceByInterfaceDesc(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)363 static int32_t DevSvcManagerStubListServiceByInterfaceDesc(
364 struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
365 {
366 int ret;
367 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
368 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
369 HDF_LOGE("%{public}s: invalid interface token", __func__);
370 return HDF_ERR_INVALID_PARAM;
371 }
372 const char *interfaceDesc = HdfSbufReadString(data);
373 if (interfaceDesc == NULL) {
374 HDF_LOGE("%{public}s failed, interfaceDesc is null", __func__);
375 return HDF_FAILURE;
376 }
377 ret = ListServicePermCheck();
378 if (ret != HDF_SUCCESS) {
379 return ret;
380 }
381 ret = super->ListServiceByInterfaceDesc(super, interfaceDesc, reply);
382
383 return ret;
384 }
385
DevSvcManagerStubRemoveService(struct IDevSvcManager * super,struct HdfSBuf * data)386 static int32_t DevSvcManagerStubRemoveService(struct IDevSvcManager *super, struct HdfSBuf *data)
387 {
388 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
389 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
390 HDF_LOGE("%{public}s: invalid interface token", __func__);
391 return HDF_ERR_INVALID_PARAM;
392 }
393 const char *name = HdfSbufReadString(data);
394 if (name == NULL) {
395 HDF_LOGE("%{public}s failed, name is null", __func__);
396 return HDF_FAILURE;
397 }
398 int32_t ret = AddServicePermCheck(name);
399 if (ret != HDF_SUCCESS) {
400 return ret;
401 }
402 struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
403 if (serviceObject == NULL) {
404 HDF_LOGE("remove service %{public}s not exist", name);
405 return HDF_DEV_ERR_NO_DEVICE_SERVICE;
406 }
407
408 OsalMutexLock(&stub->devSvcStubMutex);
409 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
410 OsalMutexUnlock(&stub->devSvcStubMutex);
411 HDF_LOGI("StubRemoveService service %{public}s is invalid", name);
412 return HDF_FAILURE;
413 }
414
415 const char *servName = (const char *)serviceObject->priv;
416 if (servName == NULL) {
417 OsalMutexUnlock(&stub->devSvcStubMutex);
418 HDF_LOGE("remove service %{public}s is broken object", name);
419 return HDF_ERR_INVALID_OBJECT;
420 }
421
422 if (strcmp(name, servName) != 0) {
423 OsalMutexUnlock(&stub->devSvcStubMutex);
424 HDF_LOGE("remove service %{public}s name mismatch with %{public}s", name, servName);
425 return HDF_ERR_INVALID_OBJECT;
426 }
427 OsalMutexUnlock(&stub->devSvcStubMutex);
428 super->RemoveService(super, name, serviceObject);
429 HDF_LOGI("service %{public}s removed", name);
430
431 ReleaseServiceObject(stub, serviceObject);
432 return HDF_SUCCESS;
433 }
DevSvcManagerStubRegisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)434 static int32_t DevSvcManagerStubRegisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
435 {
436 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
437 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
438 HDF_LOGE("%{public}s: invalid interface token", __func__);
439 return HDF_ERR_INVALID_PARAM;
440 }
441 uint16_t listenClass = DEVICE_CLASS_DEFAULT;
442 if (!HdfSbufReadUint16(data, &listenClass)) {
443 return HDF_ERR_INVALID_PARAM;
444 }
445 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
446 if (listenerRemote == NULL) {
447 return HDF_ERR_INVALID_PARAM;
448 }
449
450 struct ServStatListenerHolder *listenerHolder =
451 ServStatListenerHolderCreate((uintptr_t)listenerRemote, listenClass);
452 if (listenerHolder == NULL) {
453 HdfRemoteServiceRecycle(listenerRemote);
454 return HDF_ERR_MALLOC_FAIL;
455 }
456
457 int ret = super->RegsterServListener(super, listenerHolder);
458 if (ret != HDF_SUCCESS) {
459 ServStatListenerHolderRelease(listenerHolder);
460 } else {
461 HDF_LOGI("register servstat listener success");
462 }
463
464 return HDF_SUCCESS;
465 }
466
DevSvcManagerStubUnregisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)467 static int32_t DevSvcManagerStubUnregisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
468 {
469 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
470 if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
471 HDF_LOGE("%{public}s: invalid interface token", __func__);
472 return HDF_ERR_INVALID_PARAM;
473 }
474 struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
475 if (listenerRemote == NULL) {
476 return HDF_ERR_INVALID_PARAM;
477 }
478 struct ServStatListenerHolder *listenerHolder = ServStatListenerHolderGet(listenerRemote->index);
479 if (listenerHolder == NULL) {
480 HDF_LOGE("failed to unregister svcstat listener, unknown listener");
481 HdfRemoteServiceRecycle(listenerRemote);
482 return HDF_ERR_INVALID_OBJECT;
483 }
484 super->UnregsterServListener(super, listenerHolder);
485 ServStatListenerHolderRelease(listenerHolder);
486 HdfRemoteServiceRecycle(listenerRemote);
487 HDF_LOGI("unregister servstat listener success");
488 return HDF_SUCCESS;
489 }
490
DevSvcManagerStubDispatch(struct HdfRemoteService * service,int code,struct HdfSBuf * data,struct HdfSBuf * reply)491 int DevSvcManagerStubDispatch(struct HdfRemoteService *service, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
492 {
493 int ret = HDF_FAILURE;
494 struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)service;
495 if (stub == NULL) {
496 HDF_LOGE("DevSvcManagerStubDispatch failed, object is null, code is %{public}d", code);
497 return ret;
498 }
499 struct IDevSvcManager *super = (struct IDevSvcManager *)&stub->super;
500 HDF_LOGD("DevSvcManagerStubDispatch called: code=%{public}d", code);
501 switch (code) {
502 case DEVSVC_MANAGER_ADD_SERVICE:
503 ret = DevSvcManagerStubAddService(super, data);
504 break;
505 case DEVSVC_MANAGER_UPDATE_SERVICE:
506 ret = DevSvcManagerStubUpdateService(super, data);
507 break;
508 case DEVSVC_MANAGER_GET_SERVICE:
509 ret = DevSvcManagerStubGetService(super, data, reply);
510 break;
511 case DEVSVC_MANAGER_REMOVE_SERVICE:
512 ret = DevSvcManagerStubRemoveService(super, data);
513 break;
514 case DEVSVC_MANAGER_REGISTER_SVCLISTENER:
515 ret = DevSvcManagerStubRegisterServListener(super, data);
516 break;
517 case DEVSVC_MANAGER_UNREGISTER_SVCLISTENER:
518 ret = DevSvcManagerStubUnregisterServListener(super, data);
519 break;
520 case DEVSVC_MANAGER_LIST_ALL_SERVICE:
521 ret = DevSvcManagerStubListAllService(super, data, reply);
522 break;
523 case DEVSVC_MANAGER_LIST_SERVICE_BY_INTERFACEDESC:
524 ret = DevSvcManagerStubListServiceByInterfaceDesc(super, data, reply);
525 break;
526 default:
527 ret = HdfRemoteServiceDefaultDispatch(stub->remote, code, data, reply);
528 break;
529 }
530 return ret;
531 }
532
DevSvcManagerOnServiceDied(struct HdfDeathRecipient * recipient,struct HdfRemoteService * remote)533 void DevSvcManagerOnServiceDied(struct HdfDeathRecipient *recipient, struct HdfRemoteService *remote)
534 {
535 struct DevSvcManagerStub *stub =
536 HDF_SLIST_CONTAINER_OF(struct HdfDeathRecipient, recipient, struct DevSvcManagerStub, recipient);
537 if (stub == NULL) {
538 return;
539 }
540
541 struct IDevSvcManager *iSvcMgr = &stub->super.super;
542 if (iSvcMgr->GetService == NULL || iSvcMgr->RemoveService == NULL) {
543 HDF_LOGI("%{public}s:invalid svcmgr object", __func__);
544 return;
545 }
546
547 OsalMutexLock(&stub->devSvcStubMutex);
548 if (!CheckRemoteObjectValidNoLock(stub, remote)) {
549 OsalMutexUnlock(&stub->devSvcStubMutex);
550 return;
551 }
552 struct HdfDeviceObject *serviceObject = (struct HdfDeviceObject *)remote->target;
553
554 if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
555 OsalMutexUnlock(&stub->devSvcStubMutex);
556 return;
557 }
558
559 char *serviceName = HdfStringCopy((char *)serviceObject->priv);
560 OsalMutexUnlock(&stub->devSvcStubMutex);
561 if (serviceName == NULL) {
562 HDF_LOGI("%{public}s HdfStringCopy fail", __func__);
563 return;
564 }
565
566 HDF_LOGI("service %{public}s died", serviceName);
567 iSvcMgr->RemoveService(iSvcMgr, serviceName, serviceObject);
568
569 ReleaseServiceObject(stub, serviceObject);
570 OsalMemFree(serviceName);
571 }
572
DevSvcManagerStubStart(struct IDevSvcManager * svcmgr)573 int DevSvcManagerStubStart(struct IDevSvcManager *svcmgr)
574 {
575 struct DevSvcManagerStub *inst = (struct DevSvcManagerStub *)svcmgr;
576 if (inst == NULL) {
577 return HDF_ERR_INVALID_PARAM;
578 }
579 if (inst->started) {
580 return HDF_SUCCESS;
581 }
582
583 ServStatListenerHolderinit();
584
585 static struct HdfRemoteDispatcher dispatcher = {.Dispatch = DevSvcManagerStubDispatch};
586 inst->remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher);
587 if (inst->remote == NULL) {
588 HDF_LOGE("failed to obtain device service manager remote service");
589 return HDF_ERR_MALLOC_FAIL;
590 }
591 if (!HdfRemoteServiceSetInterfaceDesc(inst->remote, "HDI.IServiceManager.V1_0")) {
592 HDF_LOGE("%{public}s: failed to init interface desc", __func__);
593 HdfRemoteServiceRecycle(inst->remote);
594 return HDF_ERR_INVALID_OBJECT;
595 }
596
597 inst->recipient.OnRemoteDied = DevSvcManagerOnServiceDied;
598 int ret = HdfRemoteServiceRegister(DEVICE_SERVICE_MANAGER_SA_ID, inst->remote);
599 if (ret != 0) {
600 HDF_LOGE("failed to publish device service manager, %{public}d", ret);
601 HdfRemoteServiceRecycle(inst->remote);
602 inst->remote = NULL;
603 } else {
604 HDF_LOGI("publish device service manager success");
605 inst->started = true;
606 }
607
608 return ret;
609 }
610
DevSvcManagerStubConstruct(struct DevSvcManagerStub * inst)611 static bool DevSvcManagerStubConstruct(struct DevSvcManagerStub *inst)
612 {
613 if (inst == NULL) {
614 return false;
615 }
616 if (!DevSvcManagerConstruct(&inst->super)) {
617 HDF_LOGE("failed to construct device service manager");
618 return false;
619 }
620 inst->super.super.StartService = DevSvcManagerStubStart;
621 OsalMutexInit(&inst->devSvcStubMutex);
622 HdfSListInit(&inst->devObjHolderList);
623
624 return true;
625 }
626
DevSvcManagerStubCreate(void)627 struct HdfObject *DevSvcManagerStubCreate(void)
628 {
629 static struct DevSvcManagerStub *instance;
630 if (instance != NULL) {
631 return (struct HdfObject *)instance;
632 }
633
634 instance = OsalMemCalloc(sizeof(struct DevSvcManagerStub));
635 if (!DevSvcManagerStubConstruct(instance)) {
636 OsalMemFree(instance);
637 instance = NULL;
638 }
639
640 return (struct HdfObject *)instance;
641 }
642
DevObjHolderListReleaseNoLock(struct DevSvcManagerStub * stub)643 static void DevObjHolderListReleaseNoLock(struct DevSvcManagerStub *stub)
644 {
645 struct HdfSListIterator it;
646 HdfSListIteratorInit(&it, &stub->devObjHolderList);
647 while (HdfSListIteratorHasNext(&it)) {
648 struct HdfSListNode *node = HdfSListIteratorNext(&it);
649 HdfSListIteratorRemove(&it);
650 struct HdfDeviceObjectHolder *holder =
651 HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
652
653 ReleaseServiceObjectHolder(stub, holder);
654 }
655 }
656
DevSvcManagerStubRelease(struct HdfObject * object)657 void DevSvcManagerStubRelease(struct HdfObject *object)
658 {
659 struct DevSvcManagerStub *instance = (struct DevSvcManagerStub *)object;
660 if (instance != NULL) {
661 if (instance->remote != NULL) {
662 HdfRemoteServiceRecycle(instance->remote);
663 instance->remote = NULL;
664 }
665 OsalMutexLock(&instance->devSvcStubMutex);
666 DevObjHolderListReleaseNoLock(instance);
667 OsalMutexUnlock(&instance->devSvcStubMutex);
668 OsalMutexDestroy(&instance->devSvcStubMutex);
669 }
670 }
671