• 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_adapter_if.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()60 static int32_t ListServicePermCheck()
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 || service->priv == 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             (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 %{public}s service object is invalid", __func__, (char *)service->priv);
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 (serviceObject->priv == NULL) {
181         OsalMutexUnlock(&stub->devSvcStubMutex);
182         HDF_LOGW("release service object has empty name, may broken object");
183         return;
184     }
185 
186     if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
187         OsalMutexUnlock(&stub->devSvcStubMutex);
188         return;
189     }
190 
191     struct HdfRemoteService *serviceRemote = (struct HdfRemoteService *)serviceObject->service;
192     HdfRemoteServiceRemoveDeathRecipient(serviceRemote, &stub->recipient);
193 
194     struct HdfDeviceObjectHolder *serviceObjectHolder = (struct HdfDeviceObjectHolder *)serviceObject;
195     HdfSListRemove(&stub->devObjHolderList, &serviceObjectHolder->entry);
196     ReleaseServiceObjectHolder(stub, serviceObjectHolder);
197 
198     OsalMutexUnlock(&stub->devSvcStubMutex);
199 }
200 
DevSvcMgrStubGetPara(struct HdfSBuf * data,struct HdfServiceInfo * info,struct HdfRemoteService ** service)201 static int32_t DevSvcMgrStubGetPara(
202     struct HdfSBuf *data, struct HdfServiceInfo *info, struct HdfRemoteService **service)
203 {
204     int ret = HDF_FAILURE;
205     info->servName = HdfSbufReadString(data);
206     if (info->servName == NULL) {
207         HDF_LOGE("%{public}s failed, name is null", __func__);
208         return ret;
209     }
210     ret = AddServicePermCheck(info->servName);
211     if (ret != HDF_SUCCESS) {
212         return ret;
213     }
214 
215     info->devClass = DEVICE_CLASS_DEFAULT;
216     if (!HdfSbufReadUint16(data, &info->devClass)) {
217         HDF_LOGE("%{public}s failed, devClass invalid", __func__);
218         return HDF_FAILURE;
219     }
220     if (!HdfSbufReadUint32(data, &info->devId)) {
221         HDF_LOGE("%{public}s failed, devId invalid", __func__);
222         return HDF_FAILURE;
223     }
224 
225     *service = HdfSbufReadRemoteService(data);
226     if (*service == NULL) {
227         HDF_LOGE("%{public}s failed, service is null", __func__);
228         return HDF_FAILURE;
229     }
230     info->servInfo = HdfSbufReadString(data);
231     return HDF_SUCCESS;
232 }
233 
DevSvcManagerStubAddService(struct IDevSvcManager * super,struct HdfSBuf * data)234 static int32_t DevSvcManagerStubAddService(struct IDevSvcManager *super, struct HdfSBuf *data)
235 {
236     int ret = HDF_FAILURE;
237     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
238     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
239         HDF_LOGE("%{public}s: invalid interface token", __func__);
240         return HDF_ERR_INVALID_PARAM;
241     }
242     struct HdfServiceInfo info;
243     struct HdfRemoteService *service = NULL;
244     (void)memset_s(&info, sizeof(info), 0, sizeof(info));
245     if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) {
246         return ret;
247     }
248 
249     struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
250     if (serviceObject == NULL) {
251         return HDF_ERR_MALLOC_FAIL;
252     }
253 
254     struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
255     ret = super->AddService(super, serviceObject, &info);
256     if (ret != HDF_SUCCESS) {
257         ReleaseServiceObject(stub, serviceObject);
258     } else {
259         ReleaseServiceObject(stub, oldServiceObject);
260     }
261     HDF_LOGI("add service %{public}s, %{public}d", info.servName, ret);
262     return ret;
263 }
264 
DevSvcManagerStubUpdateService(struct IDevSvcManager * super,struct HdfSBuf * data)265 static int32_t DevSvcManagerStubUpdateService(struct IDevSvcManager *super, struct HdfSBuf *data)
266 {
267     int ret = HDF_FAILURE;
268     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
269     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
270         HDF_LOGE("%{public}s: invalid interface token", __func__);
271         return HDF_ERR_INVALID_PARAM;
272     }
273 
274     struct HdfRemoteService *service = NULL;
275     struct HdfServiceInfo info;
276     (void)memset_s(&info, sizeof(info), 0, sizeof(info));
277     if (DevSvcMgrStubGetPara(data, &info, &service) != HDF_SUCCESS) {
278         return ret;
279     }
280 
281     struct HdfDeviceObject *oldServiceObject = super->GetObject(super, info.servName);
282     if (oldServiceObject == NULL) {
283         HDF_LOGE("update service %{public}s not exist", info.servName);
284         return HDF_DEV_ERR_NO_DEVICE_SERVICE;
285     }
286 
287     struct HdfDeviceObject *serviceObject = ObtainServiceObject(stub, info.servName, service);
288     if (serviceObject == NULL) {
289         return HDF_ERR_MALLOC_FAIL;
290     }
291 
292     ret = super->UpdateService(super, serviceObject, &info);
293     if (ret != HDF_SUCCESS) {
294         ReleaseServiceObject(stub, serviceObject);
295     } else {
296         ReleaseServiceObject(stub, oldServiceObject);
297     }
298     HDF_LOGI("update service %{public}s, %{public}d", info.servName, ret);
299     return ret;
300 }
301 
DevSvcManagerStubGetService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)302 static int32_t DevSvcManagerStubGetService(struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
303 {
304     int ret = HDF_FAILURE;
305     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
306     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
307         HDF_LOGE("%{public}s: invalid interface token", __func__);
308         return HDF_ERR_INVALID_PARAM;
309     }
310     const char *name = HdfSbufReadString(data);
311     if (name == NULL) {
312         HDF_LOGE("%{public}s failed, name is null", __func__);
313         return ret;
314     }
315     ret = GetServicePermCheck(name);
316     if (ret != HDF_SUCCESS) {
317         return ret;
318     }
319     struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
320     if (serviceObject == NULL) {
321         HDF_LOGE("StubGetService service %{public}s not found", name);
322         return HDF_FAILURE;
323     }
324 
325     const char *svcMgrName = "hdf_device_manager";
326     if (strcmp(name, svcMgrName) != 0) {
327         OsalMutexLock(&stub->devSvcStubMutex);
328         if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
329             OsalMutexUnlock(&stub->devSvcStubMutex);
330             HDF_LOGE("StubGetService service %{public}s is invalid", name);
331             return HDF_FAILURE;
332         }
333     }
334     struct HdfRemoteService *remoteService = (struct HdfRemoteService *)serviceObject->service;
335     if (remoteService != NULL) {
336         HdfSbufWriteRemoteService(reply, remoteService);
337         ret = HDF_SUCCESS;
338         HDF_LOGI("StubGetService service %{public}s found", name);
339     } else {
340         HDF_LOGE("StubGetService %{public}s remoteService is null", name);
341         ret = HDF_FAILURE;
342     }
343 
344     if (strcmp(name, svcMgrName) != 0) {
345         OsalMutexUnlock(&stub->devSvcStubMutex);
346     }
347 
348     return ret;
349 }
350 
DevSvcManagerStubListAllService(struct IDevSvcManager * super,struct HdfSBuf * data,struct HdfSBuf * reply)351 static int32_t DevSvcManagerStubListAllService(
352     struct IDevSvcManager *super, struct HdfSBuf *data, struct HdfSBuf *reply)
353 {
354     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
355     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
356         HDF_LOGE("%{public}s: invalid interface token", __func__);
357         return HDF_ERR_INVALID_PARAM;
358     }
359     int ret = ListServicePermCheck();
360     if (ret != HDF_SUCCESS) {
361         return ret;
362     }
363     super->ListAllService(super, reply);
364 
365     return HDF_SUCCESS;
366 }
367 
DevSvcManagerStubRemoveService(struct IDevSvcManager * super,struct HdfSBuf * data)368 static int32_t DevSvcManagerStubRemoveService(struct IDevSvcManager *super, struct HdfSBuf *data)
369 {
370     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
371     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
372         HDF_LOGE("%{public}s: invalid interface token", __func__);
373         return HDF_ERR_INVALID_PARAM;
374     }
375     const char *name = HdfSbufReadString(data);
376     if (name == NULL) {
377         HDF_LOGE("%{public}s failed, name is null", __func__);
378         return HDF_FAILURE;
379     }
380     int32_t ret = AddServicePermCheck(name);
381     if (ret != HDF_SUCCESS) {
382         return ret;
383     }
384     struct HdfDeviceObject *serviceObject = super->GetObject(super, name);
385     if (serviceObject == NULL) {
386         HDF_LOGE("remove service %{public}s not exist", name);
387         return HDF_DEV_ERR_NO_DEVICE_SERVICE;
388     }
389 
390     OsalMutexLock(&stub->devSvcStubMutex);
391     if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
392         OsalMutexUnlock(&stub->devSvcStubMutex);
393         HDF_LOGI("StubRemoveService service %{public}s is invalid", name);
394         return HDF_FAILURE;
395     }
396 
397     const char *servName = (const char *)serviceObject->priv;
398     if (servName == NULL) {
399         OsalMutexUnlock(&stub->devSvcStubMutex);
400         HDF_LOGE("remove service %{public}s is broken object", name);
401         return HDF_ERR_INVALID_OBJECT;
402     }
403 
404     if (strcmp(name, servName) != 0) {
405         OsalMutexUnlock(&stub->devSvcStubMutex);
406         HDF_LOGE("remove service %{public}s name mismatch with %{public}s", name, servName);
407         return HDF_ERR_INVALID_OBJECT;
408     }
409     OsalMutexUnlock(&stub->devSvcStubMutex);
410     super->RemoveService(super, name, serviceObject);
411     HDF_LOGI("service %{public}s removed", name);
412 
413     ReleaseServiceObject(stub, serviceObject);
414     return HDF_SUCCESS;
415 }
DevSvcManagerStubRegisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)416 static int32_t DevSvcManagerStubRegisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
417 {
418     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
419     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
420         HDF_LOGE("%{public}s: invalid interface token", __func__);
421         return HDF_ERR_INVALID_PARAM;
422     }
423     uint16_t listenClass = DEVICE_CLASS_DEFAULT;
424     if (!HdfSbufReadUint16(data, &listenClass)) {
425         return HDF_ERR_INVALID_PARAM;
426     }
427     struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
428     if (listenerRemote == NULL) {
429         return HDF_ERR_INVALID_PARAM;
430     }
431 
432     struct ServStatListenerHolder *listenerHolder =
433         ServStatListenerHolderCreate((uintptr_t)listenerRemote, listenClass);
434     if (listenerHolder == NULL) {
435         return HDF_ERR_MALLOC_FAIL;
436     }
437 
438     int ret = super->RegsterServListener(super, listenerHolder);
439     if (ret != HDF_SUCCESS) {
440         ServStatListenerHolderRelease(listenerHolder);
441     } else {
442         HDF_LOGI("register servstat listener success");
443     }
444 
445     return HDF_SUCCESS;
446 }
447 
DevSvcManagerStubUnregisterServListener(struct IDevSvcManager * super,struct HdfSBuf * data)448 static int32_t DevSvcManagerStubUnregisterServListener(struct IDevSvcManager *super, struct HdfSBuf *data)
449 {
450     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)super;
451     if (!HdfRemoteServiceCheckInterfaceToken(stub->remote, data)) {
452         HDF_LOGE("%{public}s: invalid interface token", __func__);
453         return HDF_ERR_INVALID_PARAM;
454     }
455     struct HdfRemoteService *listenerRemote = HdfSbufReadRemoteService(data);
456     if (listenerRemote == NULL) {
457         return HDF_ERR_INVALID_PARAM;
458     }
459     struct ServStatListenerHolder *listenerHolder = ServStatListenerHolderGet(listenerRemote->index);
460     if (listenerHolder == NULL) {
461         HDF_LOGE("failed to unregister svcstat listener, unknown listener");
462         HdfRemoteServiceRecycle(listenerRemote);
463         return HDF_ERR_INVALID_OBJECT;
464     }
465     super->UnregsterServListener(super, listenerHolder);
466     ServStatListenerHolderRelease(listenerHolder);
467     HdfRemoteServiceRecycle(listenerRemote);
468     HDF_LOGI("unregister servstat listener success");
469     return HDF_SUCCESS;
470 }
471 
DevSvcManagerStubDispatch(struct HdfRemoteService * service,int code,struct HdfSBuf * data,struct HdfSBuf * reply)472 int DevSvcManagerStubDispatch(struct HdfRemoteService *service, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
473 {
474     int ret = HDF_FAILURE;
475     struct DevSvcManagerStub *stub = (struct DevSvcManagerStub *)service;
476     if (stub == NULL) {
477         HDF_LOGE("DevSvcManagerStubDispatch failed, object is null, code is %{public}d", code);
478         return ret;
479     }
480     struct IDevSvcManager *super = (struct IDevSvcManager *)&stub->super;
481     HDF_LOGD("DevSvcManagerStubDispatch called: code=%{public}d", code);
482     switch (code) {
483         case DEVSVC_MANAGER_ADD_SERVICE:
484             ret = DevSvcManagerStubAddService(super, data);
485             break;
486         case DEVSVC_MANAGER_UPDATE_SERVICE:
487             ret = DevSvcManagerStubUpdateService(super, data);
488             break;
489         case DEVSVC_MANAGER_GET_SERVICE:
490             ret = DevSvcManagerStubGetService(super, data, reply);
491             break;
492         case DEVSVC_MANAGER_REMOVE_SERVICE:
493             ret = DevSvcManagerStubRemoveService(super, data);
494             break;
495         case DEVSVC_MANAGER_REGISTER_SVCLISTENER:
496             ret = DevSvcManagerStubRegisterServListener(super, data);
497             break;
498         case DEVSVC_MANAGER_UNREGISTER_SVCLISTENER:
499             ret = DevSvcManagerStubUnregisterServListener(super, data);
500             break;
501         case DEVSVC_MANAGER_LIST_ALL_SERVICE:
502             ret = DevSvcManagerStubListAllService(super, data, reply);
503             break;
504         default:
505             ret = HdfRemoteServiceDefaultDispatch(stub->remote, code, data, reply);
506             break;
507     }
508     return ret;
509 }
510 
DevSvcManagerOnServiceDied(struct HdfDeathRecipient * recipient,struct HdfRemoteService * remote)511 void DevSvcManagerOnServiceDied(struct HdfDeathRecipient *recipient, struct HdfRemoteService *remote)
512 {
513     struct DevSvcManagerStub *stub =
514         HDF_SLIST_CONTAINER_OF(struct HdfDeathRecipient, recipient, struct DevSvcManagerStub, recipient);
515     if (stub == NULL) {
516         return;
517     }
518 
519     struct IDevSvcManager *iSvcMgr = &stub->super.super;
520     if (iSvcMgr->GetService == NULL || iSvcMgr->RemoveService == NULL) {
521         HDF_LOGI("%{public}s:invalid svcmgr object", __func__);
522         return;
523     }
524 
525     OsalMutexLock(&stub->devSvcStubMutex);
526     if (!CheckRemoteObjectValidNoLock(stub, remote)) {
527         OsalMutexUnlock(&stub->devSvcStubMutex);
528         return;
529     }
530     struct HdfDeviceObject *serviceObject = (struct HdfDeviceObject *)remote->target;
531 
532     if (!CheckServiceObjectValidNoLock(stub, serviceObject)) {
533         OsalMutexUnlock(&stub->devSvcStubMutex);
534         return;
535     }
536 
537     char *serviceName = HdfStringCopy((char *)serviceObject->priv);
538     OsalMutexUnlock(&stub->devSvcStubMutex);
539     if (serviceName == NULL) {
540         HDF_LOGI("%{public}s HdfStringCopy fail", __func__);
541         return;
542     }
543 
544     HDF_LOGI("service %{public}s died", serviceName);
545     iSvcMgr->RemoveService(iSvcMgr, serviceName, serviceObject);
546 
547     ReleaseServiceObject(stub, serviceObject);
548     OsalMemFree(serviceName);
549 }
550 
DevSvcManagerStubStart(struct IDevSvcManager * svcmgr)551 int DevSvcManagerStubStart(struct IDevSvcManager *svcmgr)
552 {
553     struct DevSvcManagerStub *inst = (struct DevSvcManagerStub *)svcmgr;
554     if (inst == NULL) {
555         return HDF_ERR_INVALID_PARAM;
556     }
557     if (inst->started) {
558         return HDF_SUCCESS;
559     }
560 
561     ServStatListenerHolderinit();
562 
563     static struct HdfRemoteDispatcher dispatcher = {.Dispatch = DevSvcManagerStubDispatch};
564     inst->remote = HdfRemoteServiceObtain((struct HdfObject *)inst, &dispatcher);
565     if (inst->remote == NULL) {
566         HDF_LOGE("failed to obtain device service manager remote service");
567         return HDF_ERR_MALLOC_FAIL;
568     }
569     if (!HdfRemoteServiceSetInterfaceDesc(inst->remote, "HDI.IServiceManager.V1_0")) {
570         HDF_LOGE("%{public}s: failed to init interface desc", __func__);
571         return HDF_ERR_INVALID_OBJECT;
572     }
573 
574     inst->recipient.OnRemoteDied = DevSvcManagerOnServiceDied;
575     int ret = HdfRemoteServiceRegister(DEVICE_SERVICE_MANAGER_SA_ID, inst->remote);
576     if (ret != 0) {
577         HDF_LOGE("failed to publish device service manager, %{public}d", ret);
578         HdfRemoteServiceRecycle(inst->remote);
579         inst->remote = NULL;
580     } else {
581         HDF_LOGI("publish device service manager success");
582         inst->started = true;
583     }
584 
585     return ret;
586 }
587 
DevSvcManagerStubConstruct(struct DevSvcManagerStub * inst)588 static bool DevSvcManagerStubConstruct(struct DevSvcManagerStub *inst)
589 {
590     if (inst == NULL) {
591         return false;
592     }
593     if (!DevSvcManagerConstruct(&inst->super)) {
594         HDF_LOGE("failed to construct device service manager");
595         return false;
596     }
597     inst->super.super.StartService = DevSvcManagerStubStart;
598     OsalMutexInit(&inst->devSvcStubMutex);
599     HdfSListInit(&inst->devObjHolderList);
600 
601     return true;
602 }
603 
DevSvcManagerStubCreate(void)604 struct HdfObject *DevSvcManagerStubCreate(void)
605 {
606     static struct DevSvcManagerStub *instance;
607     if (instance != NULL) {
608         return (struct HdfObject *)instance;
609     }
610 
611     instance = OsalMemCalloc(sizeof(struct DevSvcManagerStub));
612     if (!DevSvcManagerStubConstruct(instance)) {
613         OsalMemFree(instance);
614         instance = NULL;
615     }
616 
617     return (struct HdfObject *)instance;
618 }
619 
DevObjHolderListReleaseNoLock(struct DevSvcManagerStub * stub)620 static void DevObjHolderListReleaseNoLock(struct DevSvcManagerStub *stub)
621 {
622     struct HdfSListIterator it;
623     HdfSListIteratorInit(&it, &stub->devObjHolderList);
624     while (HdfSListIteratorHasNext(&it)) {
625         struct HdfSListNode *node = HdfSListIteratorNext(&it);
626         HdfSListIteratorRemove(&it);
627         struct HdfDeviceObjectHolder *holder =
628             HDF_SLIST_CONTAINER_OF(struct HdfSListNode, node, struct HdfDeviceObjectHolder, entry);
629 
630         ReleaseServiceObjectHolder(stub, holder);
631     }
632 }
633 
DevSvcManagerStubRelease(struct HdfObject * object)634 void DevSvcManagerStubRelease(struct HdfObject *object)
635 {
636     struct DevSvcManagerStub *instance = (struct DevSvcManagerStub *)object;
637     if (instance != NULL) {
638         if (instance->remote != NULL) {
639             HdfRemoteServiceRecycle(instance->remote);
640             instance->remote = NULL;
641         }
642         OsalMutexLock(&instance->devSvcStubMutex);
643         DevObjHolderListReleaseNoLock(instance);
644         OsalMutexUnlock(&instance->devSvcStubMutex);
645         OsalMutexDestroy(&instance->devSvcStubMutex);
646     }
647 }
648