• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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