1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdf_service_observer.h"
10 #include "hdf_base.h"
11 #include "hdf_cstring.h"
12 #include "hdf_log.h"
13 #include "hdf_observer_record.h"
14
15 #define HDF_LOG_TAG service_observer
16
HdfServiceObserverConstruct(struct HdfServiceObserver * observer)17 bool HdfServiceObserverConstruct(struct HdfServiceObserver *observer)
18 {
19 if (observer == NULL) {
20 HDF_LOGE("observer is null");
21 return false;
22 }
23 if (OsalMutexInit(&observer->observerMutex) != HDF_SUCCESS) {
24 return false;
25 }
26 HdfSListInit(&observer->services);
27 return true;
28 }
29
HdfServiceObserverDestruct(struct HdfServiceObserver * observer)30 void HdfServiceObserverDestruct(struct HdfServiceObserver *observer)
31 {
32 if (observer != NULL) {
33 HdfSListFlush(&observer->services, HdfServiceObserverRecordDelete);
34 OsalMutexDestroy(&observer->observerMutex);
35 }
36 }
37
HdfServiceObserverSubscribeService(struct HdfServiceObserver * observer,const char * svcName,devid_t devid,struct SubscriberCallback callback)38 int HdfServiceObserverSubscribeService(struct HdfServiceObserver *observer,
39 const char *svcName, devid_t devid, struct SubscriberCallback callback)
40 {
41 struct HdfServiceObserverRecord *serviceRecord = NULL;
42 struct HdfServiceSubscriber *subscriber = NULL;
43 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
44 if ((observer == NULL) || (svcName == NULL)) {
45 HDF_LOGE("observer or svcName or callback.OnServiceConnected is null");
46 return HDF_FAILURE;
47 }
48 serviceRecord = (struct HdfServiceObserverRecord *)HdfSListSearch(
49 &observer->services, serviceKey, HdfServiceObserverRecordCompare);
50 if (serviceRecord == NULL) {
51 serviceRecord = HdfServiceObserverRecordObtain(serviceKey);
52 if (serviceRecord == NULL) {
53 HDF_LOGE("failed to subscribe service, serviceRecord is null");
54 return HDF_FAILURE;
55 }
56 subscriber = HdfServiceSubscriberObtain(callback, devid);
57 if (subscriber == NULL) {
58 HDF_LOGE("failed to subscribe service, subscriber is null");
59 HdfServiceObserverRecordRecycle(serviceRecord);
60 return HDF_FAILURE;
61 }
62 OsalMutexLock(&observer->observerMutex);
63 HdfSListAdd(&observer->services, &serviceRecord->entry);
64 OsalMutexUnlock(&observer->observerMutex);
65 } else {
66 subscriber = HdfServiceSubscriberObtain(callback, devid);
67 if (subscriber == NULL) {
68 HDF_LOGE("failed to subscribe service, subscriber obtain null");
69 return HDF_FAILURE;
70 }
71 }
72 if ((serviceRecord->publisher != NULL) &&
73 (subscriber->callback.OnServiceConnected != NULL) &&
74 ((serviceRecord->policy != SERVICE_POLICY_PRIVATE) ||
75 (serviceRecord->devId == devid))) {
76 subscriber->state = HDF_SUBSCRIBER_STATE_READY;
77 subscriber->callback.OnServiceConnected(subscriber->callback.deviceObject, serviceRecord->publisher);
78 }
79 OsalMutexLock(&serviceRecord->obsRecMutex);
80 HdfSListAdd(&serviceRecord->subscribers, &subscriber->entry);
81 OsalMutexUnlock(&serviceRecord->obsRecMutex);
82 return HDF_SUCCESS;
83 }
84
HdfServiceObserverPublishService(struct HdfServiceObserver * observer,const char * svcName,uint32_t devId,uint16_t policy,struct HdfObject * service)85 int HdfServiceObserverPublishService(struct HdfServiceObserver *observer,
86 const char *svcName, uint32_t devId, uint16_t policy, struct HdfObject *service)
87 {
88 struct HdfServiceObserverRecord *serviceRecord = NULL;
89 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
90 if ((observer == NULL) || (svcName == NULL)) {
91 HDF_LOGE("observer or svcName is null");
92 return HDF_FAILURE;
93 }
94 serviceRecord = (struct HdfServiceObserverRecord *)HdfSListSearch(
95 &observer->services, serviceKey, HdfServiceObserverRecordCompare);
96 if (serviceRecord == NULL) {
97 serviceRecord = HdfServiceObserverRecordObtain(serviceKey);
98 if (serviceRecord == NULL) {
99 HDF_LOGE("PublishService failed, serviceRecord is null");
100 return HDF_FAILURE;
101 }
102 serviceRecord->publisher = service;
103 serviceRecord->devId = devId;
104 serviceRecord->policy = policy;
105 OsalMutexLock(&observer->observerMutex);
106 HdfSListAdd(&observer->services, &serviceRecord->entry);
107 OsalMutexUnlock(&observer->observerMutex);
108 } else {
109 serviceRecord->publisher = service;
110 HdfServiceObserverRecordNotifySubscribers(serviceRecord, devId, policy);
111 }
112 return HDF_SUCCESS;
113 }
114
HdfServiceObserverRemoveRecord(struct HdfServiceObserver * observer,const char * svcName)115 void HdfServiceObserverRemoveRecord(struct HdfServiceObserver *observer, const char *svcName)
116 {
117 struct HdfServiceObserverRecord *serviceRecord = NULL;
118 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
119 if ((observer == NULL) || (svcName == NULL)) {
120 HDF_LOGW("observer or svcName is null");
121 return;
122 }
123 serviceRecord = (struct HdfServiceObserverRecord *)HdfSListSearch(
124 &observer->services, serviceKey, HdfServiceObserverRecordCompare);
125 if (serviceRecord != NULL) {
126 OsalMutexLock(&observer->observerMutex);
127 HdfSListRemove(&observer->services, &serviceRecord->entry);
128 OsalMutexUnlock(&observer->observerMutex);
129 HdfServiceObserverRecordRecycle(serviceRecord);
130 }
131 }
132
133