• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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