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/core/event_loop_common.h" 21 #include "chre/platform/assert.h" 22 #include "chre/util/non_copyable.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 uint32_t kSystemInstanceId = 0; 31 32 //! Target instance ID used to deliver a message to all nanoapps registered for 33 //! the event 34 constexpr uint32_t kBroadcastInstanceId = UINT32_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 uint32_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 = UINT16_MAX; 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_, 51 uint32_t senderInstanceId_ = kSystemInstanceId, 52 uint32_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 // Sending events to the system must only be done via the other constructor 62 CHRE_ASSERT(targetInstanceId_ != kSystemInstanceId); 63 CHRE_ASSERT(targetAppGroupMask_ > 0); 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 // Posting events to the system must always have a corresponding callback 78 CHRE_ASSERT(systemEventCallback_ != nullptr); 79 } 80 incrementRefCount()81 void incrementRefCount() { 82 mRefCount++; 83 CHRE_ASSERT(mRefCount != 0); 84 } 85 decrementRefCount()86 void decrementRefCount() { 87 CHRE_ASSERT(mRefCount > 0); 88 mRefCount--; 89 } 90 isUnreferenced()91 bool isUnreferenced() const { 92 return (mRefCount == 0); 93 } 94 95 //! @return true if this event has an associated callback which needs to be 96 //! called prior to deallocating the event hasFreeCallback()97 bool hasFreeCallback() { 98 return (targetInstanceId == kSystemInstanceId || freeCallback != nullptr); 99 } 100 101 /** 102 * Invoke the callback associated with this event with the applicable function 103 * signature (passing extraData if this is a system event). 104 * 105 * The caller MUST confirm that hasFreeCallback() is true before calling this 106 * method. 107 */ invokeFreeCallback()108 void invokeFreeCallback() { 109 if (targetInstanceId == kSystemInstanceId) { 110 systemEventCallback(eventType, eventData, extraData); 111 } else { 112 freeCallback(eventType, eventData); 113 } 114 } 115 116 const uint16_t eventType; 117 118 //! This value can serve as a proxy for how fast CHRE is processing events 119 //! in its queue by substracting the newest event timestamp by the oldest one. 120 const uint16_t receivedTimeMillis; 121 void *const eventData; 122 123 //! If targetInstanceId is kSystemInstanceId, senderInstanceId is always 124 //! kSystemInstanceId (nanoapps can't send events to the system), so we 125 //! utilize that to allow an extra 32 bits of data to be passed to the 126 //! callback, which can reduce dynamic allocation in several cases. Therefore, 127 //! if targetInstanceId == kSystemInstanceId, then we use the latter two 128 //! elements in the following two unions 129 union { 130 chreEventCompleteFunction *const freeCallback; 131 SystemEventCallbackFunction *const systemEventCallback; 132 }; 133 union { 134 const uint32_t senderInstanceId; 135 void *const extraData; 136 }; 137 const uint32_t targetInstanceId; 138 139 // Bitmask that's used to limit the event delivery to some subset of listeners 140 // registered for this type of event (useful when waking up listeners that can 141 // have different power considerations). When left as the default value 142 // (kDefaultTargetGroupMask), this has the same behavior as broadcasting to 143 // all registered listeners. 144 const uint16_t targetAppGroupMask; 145 146 private: 147 uint16_t mRefCount = 0; 148 149 //! @return Monotonic time reference for initializing receivedTimeMillis 150 static uint16_t getTimeMillis(); 151 }; 152 153 } // namespace chre 154 155 #endif // CHRE_CORE_EVENT_H_ 156