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