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