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 #include "hdf_service_subscriber.h"
15
16 #define HDF_LOG_TAG service_observer
17
HdfServiceObserverConstruct(struct HdfServiceObserver * observer)18 bool HdfServiceObserverConstruct(struct HdfServiceObserver *observer)
19 {
20 if (observer == NULL) {
21 HDF_LOGE("observer is null");
22 return false;
23 }
24 if (OsalMutexInit(&observer->observerMutex) != HDF_SUCCESS) {
25 return false;
26 }
27 HdfSListInit(&observer->services);
28 return true;
29 }
30
HdfServiceObserverDestruct(struct HdfServiceObserver * observer)31 void HdfServiceObserverDestruct(struct HdfServiceObserver *observer)
32 {
33 if (observer != NULL) {
34 HdfSListFlush(&observer->services, HdfServiceObserverRecordDelete);
35 OsalMutexDestroy(&observer->observerMutex);
36 }
37 }
38
HdfServiceObserverSubscribeService(struct HdfServiceObserver * observer,const char * svcName,devid_t deviceId,struct SubscriberCallback callback)39 int HdfServiceObserverSubscribeService(
40 struct HdfServiceObserver *observer, const char *svcName, devid_t deviceId, struct SubscriberCallback callback)
41 {
42 struct HdfServiceObserverRecord *serviceRecord = NULL;
43 struct HdfServiceSubscriber *subscriber = NULL;
44 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
45 if ((observer == NULL) || (svcName == NULL)) {
46 HDF_LOGE("observer or svcName or callback.OnServiceConnected is null");
47 return HDF_FAILURE;
48 }
49 serviceRecord = (struct HdfServiceObserverRecord *)HdfSListSearch(
50 &observer->services, serviceKey, HdfServiceObserverRecordCompare);
51 if (serviceRecord == NULL) {
52 serviceRecord = HdfServiceObserverRecordObtain(serviceKey);
53 if (serviceRecord == NULL) {
54 HDF_LOGE("failed to subscribe service, serviceRecord is null");
55 return HDF_FAILURE;
56 }
57 subscriber = HdfServiceSubscriberObtain(callback, deviceId);
58 if (subscriber == NULL) {
59 HDF_LOGE("failed to subscribe service, subscriber is null");
60 HdfServiceObserverRecordRecycle(serviceRecord);
61 return HDF_FAILURE;
62 }
63 OsalMutexLock(&observer->observerMutex);
64 HdfSListAdd(&observer->services, &serviceRecord->entry);
65 OsalMutexUnlock(&observer->observerMutex);
66 } else {
67 subscriber = HdfServiceSubscriberObtain(callback, deviceId);
68 if (subscriber == NULL) {
69 HDF_LOGE("failed to subscribe service, subscriber obtain null");
70 return HDF_FAILURE;
71 }
72 }
73 if ((serviceRecord->publisher != NULL) && (subscriber->callback.OnServiceConnected != NULL) &&
74 ((serviceRecord->policy != SERVICE_POLICY_PRIVATE) || (serviceRecord->devId == deviceId))) {
75 subscriber->state = HDF_SUBSCRIBER_STATE_READY;
76 subscriber->callback.OnServiceConnected(subscriber->callback.deviceObject, serviceRecord->publisher);
77 }
78 OsalMutexLock(&serviceRecord->obsRecMutex);
79 HdfSListAdd(&serviceRecord->subscribers, &subscriber->entry);
80 OsalMutexUnlock(&serviceRecord->obsRecMutex);
81 return HDF_SUCCESS;
82 }
83
HdfServiceObserverPublishService(struct HdfServiceObserver * observer,const char * svcName,devid_t deviceId,uint16_t policy,struct HdfObject * service)84 int HdfServiceObserverPublishService(struct HdfServiceObserver *observer, const char *svcName, devid_t deviceId,
85 uint16_t policy, struct HdfObject *service)
86 {
87 struct HdfServiceObserverRecord *serviceRecord = NULL;
88 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
89 if ((observer == NULL) || (svcName == NULL)) {
90 HDF_LOGE("observer or svcName is null");
91 return HDF_FAILURE;
92 }
93 serviceRecord = (struct HdfServiceObserverRecord *)HdfSListSearch(
94 &observer->services, serviceKey, HdfServiceObserverRecordCompare);
95 if (serviceRecord == NULL) {
96 serviceRecord = HdfServiceObserverRecordObtain(serviceKey);
97 if (serviceRecord == NULL) {
98 HDF_LOGE("PublishService failed, serviceRecord is null");
99 return HDF_FAILURE;
100 }
101 serviceRecord->publisher = service;
102 serviceRecord->devId = deviceId;
103 serviceRecord->policy = policy;
104 OsalMutexLock(&observer->observerMutex);
105 HdfSListAdd(&observer->services, &serviceRecord->entry);
106 OsalMutexUnlock(&observer->observerMutex);
107 } else {
108 serviceRecord->publisher = service;
109 HdfServiceObserverRecordNotifySubscribers(serviceRecord, deviceId, policy);
110 }
111 return HDF_SUCCESS;
112 }
113
HdfServiceObserverRemoveRecord(struct HdfServiceObserver * observer,const char * svcName)114 void HdfServiceObserverRemoveRecord(struct HdfServiceObserver *observer, const char *svcName)
115 {
116 struct HdfServiceObserverRecord *serviceRecord = NULL;
117 uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0);
118 if ((observer == NULL) || (svcName == NULL)) {
119 HDF_LOGW("observer or svcName is null");
120 return;
121 }
122 serviceRecord = (struct HdfServiceObserverRecord *)HdfSListSearch(
123 &observer->services, serviceKey, HdfServiceObserverRecordCompare);
124 if (serviceRecord != NULL) {
125 OsalMutexLock(&observer->observerMutex);
126 HdfSListRemove(&observer->services, &serviceRecord->entry);
127 OsalMutexUnlock(&observer->observerMutex);
128 HdfServiceObserverRecordRecycle(serviceRecord);
129 }
130 }
131