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_NANOAPP_H_ 18 #define CHRE_CORE_NANOAPP_H_ 19 20 #include <cinttypes> 21 22 #include "chre/core/event.h" 23 #include "chre/core/event_ref_queue.h" 24 #include "chre/platform/platform_nanoapp.h" 25 #include "chre/util/dynamic_vector.h" 26 #include "chre/util/fixed_size_vector.h" 27 #include "chre/util/system/debug_dump.h" 28 #include "chre/util/system/napp_permissions.h" 29 30 namespace chre { 31 32 /** 33 * A class that tracks the state of a Nanoapp including incoming events and 34 * event registrations. 35 * 36 * Inheritance is used to separate the common interface with common 37 * implementation part (chre::Nanoapp) from the common interface with 38 * platform-specific implementation part (chre::PlatformNanoapp) from the purely 39 * platform-specific part (chre::PlatformNanoappBase). However, this inheritance 40 * relationship does *not* imply polymorphism, and this object must only be 41 * referred to via the most-derived type, i.e. chre::Nanoapp. 42 */ 43 class Nanoapp : public PlatformNanoapp { 44 public: 45 Nanoapp(); 46 ~Nanoapp(); 47 48 /** 49 * @return The unique identifier for this Nanoapp instance 50 */ getInstanceId()51 uint32_t getInstanceId() const { 52 return mInstanceId; 53 } 54 55 /** 56 * Assigns an instance ID to this Nanoapp. This must be called prior to 57 * starting this Nanoapp. 58 */ setInstanceId(uint32_t instanceId)59 void setInstanceId(uint32_t instanceId) { 60 mInstanceId = instanceId; 61 } 62 63 /** 64 * @return The current total number of bytes the nanoapp has allocated. 65 */ getTotalAllocatedBytes()66 size_t getTotalAllocatedBytes() const { 67 return mTotalAllocatedBytes; 68 } 69 70 /** 71 * @return The peak total number of bytes the nanoapp has allocated. 72 */ getPeakAllocatedBytes()73 size_t getPeakAllocatedBytes() const { 74 return mPeakAllocatedBytes; 75 } 76 77 /** 78 * Sets the total number of bytes the nanoapp has allocated. Also, modifies 79 * the peak allocated bytes if the current total is higher than the peak. 80 * 81 * @param The total number of bytes the nanoapp has allocated. 82 */ setTotalAllocatedBytes(size_t totalAllocatedBytes)83 void setTotalAllocatedBytes(size_t totalAllocatedBytes) { 84 mTotalAllocatedBytes = totalAllocatedBytes; 85 if (mTotalAllocatedBytes > mPeakAllocatedBytes) { 86 mPeakAllocatedBytes = mTotalAllocatedBytes; 87 } 88 } 89 90 /** 91 * @return true if the nanoapp should receive broadcast events with the given 92 * type 93 */ 94 bool isRegisteredForBroadcastEvent(uint16_t eventType, 95 uint16_t targetGroupIdMask) const; 96 97 /** 98 * Updates the Nanoapp's registration so that it will receive broadcast events 99 * with the given event type. 100 * 101 * @param eventType The event type that the nanoapp will now be registered to 102 * receive 103 * @param groupIdMask A mask of group IDs to register the nanoapp for. If an 104 * event is sent that targets any of the group IDs in the mask, it will 105 * be delivered to the nanoapp. 106 */ 107 void registerForBroadcastEvent( 108 uint16_t eventType, uint16_t groupIdMask = kDefaultTargetGroupMask); 109 110 /** 111 * Updates the Nanoapp's registration so that it will not receive broadcast 112 * events with the given event type. 113 * 114 * @param eventType The event type that the nanoapp will be unregistered from 115 * assuming the group ID also matches a valid entry. 116 * @param groupIdMask The mask of group IDs that will be unregistered from. 117 */ 118 void unregisterForBroadcastEvent( 119 uint16_t eventType, uint16_t groupIdMask = kDefaultTargetGroupMask); 120 121 /** 122 * Adds an event to this nanoapp's queue of pending events. 123 */ postEvent(Event * event)124 void postEvent(Event *event) { 125 mEventQueue.push(event); 126 } 127 128 /** 129 * Indicates whether there are any pending events in this apps queue. 130 * 131 * @return true if there are events waiting to be processed 132 */ hasPendingEvent()133 bool hasPendingEvent() { 134 return !mEventQueue.empty(); 135 } 136 137 /** 138 * Configures whether nanoapp info events will be sent to the nanoapp. 139 * Nanoapps are not sent nanoapp start/stop events by default. 140 * 141 * @param enable true if events are to be sent, false otherwise. 142 */ 143 void configureNanoappInfoEvents(bool enable); 144 145 /** 146 * Configures whether host sleep events will be sent to the nanoapp. Nanoapps 147 * are not sent sleep/awake events by default. 148 * 149 * @param enable true if events are to be sent, false otherwise. 150 */ 151 void configureHostSleepEvents(bool enable); 152 153 /** 154 * Configures whether debug dump events will be sent to the nanoapp. Nanoapps 155 * are not sent debug dump events by default. 156 * 157 * @param enable true if events are to be sent, false otherwise. 158 */ 159 void configureDebugDumpEvent(bool enable); 160 161 /** 162 * Configures whether a user settings event will be sent to the nanoapp 163 * for a specified setting (@see CHRE_USER_SETTINGS) 164 * Nanoapps are not sent user settings events by default. 165 * 166 * @param setting The user setting that the nanoapp wishes to configure 167 * events for. 168 * 169 * @param enable true if events are to be sent, false otherwise. 170 */ 171 void configureUserSettingEvent(uint8_t setting, bool enable); 172 173 /** 174 * Sends the next event in the queue to the nanoapp and returns the processed 175 * event. The hasPendingEvent() method should be tested before invoking this. 176 * 177 * @return A pointer to the processed event 178 */ 179 Event *processNextEvent(); 180 181 /** 182 * Log info about a single host wakeup that this nanoapp triggered by storing 183 * the count of wakeups in mWakeupBuckets. 184 */ 185 void blameHostWakeup(); 186 187 /* 188 * If buckets not full, then just pushes a 0 to back of buckets. If full, then 189 * shifts down all buckets from back to front and sets back to 0, losing the 190 * latest bucket value that was in front. 191 * 192 * @param numBuckets the number of buckets to cycle into to mWakeupBuckets 193 */ 194 void cycleWakeupBuckets(size_t numBuckets); 195 196 /** 197 * Prints state in a string buffer. Must only be called from the context of 198 * the main CHRE thread. 199 * 200 * @param debugDump The object that is printed into for debug dump logs. 201 */ 202 void logStateToBuffer(DebugDumpWrapper &debugDump) const; 203 204 /** 205 * @return true if the nanoapp is permitted to use the provided permission. 206 */ 207 bool permitPermissionUse(uint32_t permission) const; 208 209 private: 210 uint32_t mInstanceId = kInvalidInstanceId; 211 212 //! The total memory allocated by the nanoapp in bytes. 213 size_t mTotalAllocatedBytes = 0; 214 215 //! The peak total number of bytes allocated by the nanoapp. 216 size_t mPeakAllocatedBytes = 0; 217 218 //! The number of buckets for wakeup logging, adjust along with 219 //! EventLoop::kIntervalWakupBucketInMins. 220 static constexpr size_t kMaxSizeWakeupBuckets = 4; 221 222 //! A fixed size buffer of buckets that keeps track of the number of host 223 //! wakeups over time intervals. 224 FixedSizeVector<uint16_t, kMaxSizeWakeupBuckets> mWakeupBuckets; 225 226 //! Metadata needed for keeping track of the registered events for this 227 //! nanoapp. 228 struct EventRegistration { EventRegistrationEventRegistration229 EventRegistration(uint16_t eventType_, uint16_t groupIdMask_) 230 : eventType(eventType_), groupIdMask(groupIdMask_) {} 231 232 uint16_t eventType; 233 uint16_t groupIdMask; 234 }; 235 236 //! The set of broadcast events that this app is registered for. 237 // TODO: Implement a set container and replace DynamicVector here. There may 238 // also be a better way of handling this (perhaps we map event type to apps 239 // who care about them). 240 DynamicVector<EventRegistration> mRegisteredEvents; 241 242 EventRefQueue mEventQueue; 243 244 //! @return index of event registration if found. mRegisteredEvents.size() if 245 //! not. 246 size_t registrationIndex(uint16_t eventType) const; 247 248 /** 249 * A special function to deliver GNSS measurement events to nanoapps and 250 * handles version compatibility. 251 * 252 * @param event The pointer to the event 253 */ 254 void handleGnssMeasurementDataEvent(const Event *event); 255 }; 256 257 } // namespace chre 258 259 #endif // CHRE_CORE_NANOAPP_H_ 260