• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_CORE_EVENT_H_
18 #define CHRE_CORE_EVENT_H_
19 
20 #include "chre/platform/assert.h"
21 #include "chre/util/non_copyable.h"
22 #include "chre/util/system/system_callback_type.h"
23 #include "chre_api/chre/event.h"
24 
25 #include <cstdint>
26 
27 namespace chre {
28 
29 //! Instance ID used for events sent by the system
30 constexpr uint16_t kSystemInstanceId = 0;
31 
32 //! Target instance ID used to deliver a message to all nanoapps registered for
33 //! the event
34 constexpr uint16_t kBroadcastInstanceId = UINT16_MAX;
35 
36 //! This value can be used in a nanoapp's own instance ID to indicate that the
37 //! ID is invalid/not assigned yet
38 constexpr uint16_t kInvalidInstanceId = kBroadcastInstanceId;
39 
40 //! Default target group mask that results in the event being sent to any app
41 //! registered for it.
42 constexpr uint16_t kDefaultTargetGroupMask = 0;
43 
44 class Event : public NonCopyable {
45  public:
46   Event() = delete;
47 
48   // Events targeted at nanoapps
49   Event(uint16_t eventType_, void *eventData_,
50         chreEventCompleteFunction *freeCallback_, bool isLowPriority_,
51         uint16_t senderInstanceId_ = kSystemInstanceId,
52         uint16_t targetInstanceId_ = kBroadcastInstanceId,
53         uint16_t targetAppGroupMask_ = kDefaultTargetGroupMask)
eventType(eventType_)54       : eventType(eventType_),
55         receivedTimeMillis(getTimeMillis()),
56         eventData(eventData_),
57         freeCallback(freeCallback_),
58         senderInstanceId(senderInstanceId_),
59         targetInstanceId(targetInstanceId_),
60         targetAppGroupMask(targetAppGroupMask_),
61         isLowPriority(isLowPriority_) {
62     // Sending events to the system must only be done via the other constructor
63     CHRE_ASSERT(targetInstanceId_ != kSystemInstanceId);
64   }
65 
66   // Alternative constructor used for system-internal events (e.g. deferred
67   // callbacks)
Event(uint16_t eventType_,void * eventData_,SystemEventCallbackFunction * systemEventCallback_,void * extraData_)68   Event(uint16_t eventType_, void *eventData_,
69         SystemEventCallbackFunction *systemEventCallback_, void *extraData_)
70       : eventType(eventType_),
71         receivedTimeMillis(getTimeMillis()),
72         eventData(eventData_),
73         systemEventCallback(systemEventCallback_),
74         extraData(extraData_),
75         targetInstanceId(kSystemInstanceId),
76         targetAppGroupMask(kDefaultTargetGroupMask),
77         isLowPriority(false) {
78     // Posting events to the system must always have a corresponding callback
79     CHRE_ASSERT(systemEventCallback_ != nullptr);
80   }
81 
incrementRefCount()82   void incrementRefCount() {
83     mRefCount++;
84     CHRE_ASSERT(mRefCount != 0);
85   }
86 
decrementRefCount()87   void decrementRefCount() {
88     CHRE_ASSERT(mRefCount > 0);
89     mRefCount--;
90   }
91 
isUnreferenced()92   bool isUnreferenced() const {
93     return (mRefCount == 0);
94   }
95 
96   //! @return true if this event has an associated callback which needs to be
97   //! called prior to deallocating the event
hasFreeCallback()98   bool hasFreeCallback() {
99     return (targetInstanceId == kSystemInstanceId || freeCallback != nullptr);
100   }
101 
102   /**
103    * Invoke the callback associated with this event with the applicable function
104    * signature (passing extraData if this is a system event).
105    *
106    * The caller MUST confirm that hasFreeCallback() is true before calling this
107    * method.
108    */
invokeFreeCallback()109   void invokeFreeCallback() {
110     if (targetInstanceId == kSystemInstanceId) {
111       systemEventCallback(eventType, eventData, extraData);
112     } else {
113       freeCallback(eventType, eventData);
114     }
115   }
116 
117   //! @return Monotonic time reference for initializing receivedTimeMillis
118   static uint16_t getTimeMillis();
119 
120   const uint16_t eventType;
121 
122   //! This value can serve as a proxy for how fast CHRE is processing events
123   //! in its queue by substracting the newest event timestamp by the oldest one.
124   const uint16_t receivedTimeMillis;
125   void *const eventData;
126 
127   //! If targetInstanceId is kSystemInstanceId, senderInstanceId is always
128   //! kSystemInstanceId (nanoapps can't send events to the system), so we
129   //! utilize that to allow an extra 32 bits of data to be passed to the
130   //! callback, which can reduce dynamic allocation in several cases. Therefore,
131   //! if targetInstanceId == kSystemInstanceId, then we use the latter two
132   //! elements in the following two unions
133   union {
134     chreEventCompleteFunction *const freeCallback;
135     SystemEventCallbackFunction *const systemEventCallback;
136   };
137   union {
138     const uint16_t senderInstanceId;
139     void *const extraData;
140   };
141   const uint16_t targetInstanceId;
142 
143   // Bitmask that's used to limit the event delivery to some subset of listeners
144   // registered for this type of event (useful when waking up listeners that can
145   // have different power considerations). When left as the default value
146   // (kDefaultTargetGroupMask), this has the same behavior as broadcasting to
147   // all registered listeners.
148   const uint16_t targetAppGroupMask;
149 
150   const bool isLowPriority;
151 
152  private:
153   uint8_t mRefCount = 0;
154 };
155 
156 }  // namespace chre
157 
158 #endif  // CHRE_CORE_EVENT_H_
159