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