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/heap_block_header.h" 25 #include "chre/platform/platform_nanoapp.h" 26 #include "chre/util/dynamic_vector.h" 27 #include "chre/util/fixed_size_vector.h" 28 #include "chre/util/system/debug_dump.h" 29 #include "chre/util/system/napp_permissions.h" 30 #include "chre_api/chre/event.h" 31 32 namespace chre { 33 34 /** 35 * A class that tracks the state of a Nanoapp including incoming events and 36 * event registrations. 37 * 38 * Inheritance is used to separate the common interface with common 39 * implementation part (chre::Nanoapp) from the common interface with 40 * platform-specific implementation part (chre::PlatformNanoapp) from the purely 41 * platform-specific part (chre::PlatformNanoappBase). However, this inheritance 42 * relationship does *not* imply polymorphism, and this object must only be 43 * referred to via the most-derived type, i.e. chre::Nanoapp. 44 */ 45 class Nanoapp : public PlatformNanoapp { 46 public: 47 Nanoapp(); 48 49 /** 50 * @return The unique identifier for this Nanoapp instance 51 */ getInstanceId()52 uint16_t getInstanceId() const { 53 return mInstanceId; 54 } 55 56 /** 57 * Assigns an instance ID to this Nanoapp. This must be called prior to 58 * starting this Nanoapp. 59 */ setInstanceId(uint16_t instanceId)60 void setInstanceId(uint16_t instanceId) { 61 mInstanceId = instanceId; 62 } 63 64 /** 65 * @return The current total number of bytes the nanoapp has allocated. 66 */ getTotalAllocatedBytes()67 size_t getTotalAllocatedBytes() const { 68 return mTotalAllocatedBytes; 69 } 70 71 /** 72 * @return The peak total number of bytes the nanoapp has allocated. 73 */ getPeakAllocatedBytes()74 size_t getPeakAllocatedBytes() const { 75 return mPeakAllocatedBytes; 76 } 77 78 /** 79 * Sets the total number of bytes the nanoapp has allocated. Also, modifies 80 * the peak allocated bytes if the current total is higher than the peak. 81 * 82 * @param The total number of bytes the nanoapp has allocated. 83 */ setTotalAllocatedBytes(size_t totalAllocatedBytes)84 void setTotalAllocatedBytes(size_t totalAllocatedBytes) { 85 mTotalAllocatedBytes = totalAllocatedBytes; 86 if (mTotalAllocatedBytes > mPeakAllocatedBytes) { 87 mPeakAllocatedBytes = mTotalAllocatedBytes; 88 } 89 } 90 91 /** 92 * @return true if the nanoapp should receive broadcast event 93 */ 94 bool isRegisteredForBroadcastEvent(const Event *event) const; 95 96 /** 97 * Updates the Nanoapp's registration so that it will receive broadcast events 98 * with the given event type. 99 * 100 * @param eventType The event type that the nanoapp will now be registered to 101 * receive 102 * @param groupIdMask A mask of group IDs to register the nanoapp for. If an 103 * event is sent that targets any of the group IDs in the mask, it will 104 * be delivered to the nanoapp. 105 */ 106 void registerForBroadcastEvent( 107 uint16_t eventType, uint16_t groupIdMask = kDefaultTargetGroupMask); 108 109 /** 110 * Updates the Nanoapp's registration so that it will not receive broadcast 111 * events with the given event type. 112 * 113 * @param eventType The event type that the nanoapp will be unregistered from 114 * assuming the group ID also matches a valid entry. 115 * @param groupIdMask The mask of group IDs that will be unregistered from. 116 */ 117 void unregisterForBroadcastEvent( 118 uint16_t eventType, uint16_t groupIdMask = kDefaultTargetGroupMask); 119 120 /** 121 * Configures whether nanoapp info events will be sent to the nanoapp. 122 * Nanoapps are not sent nanoapp start/stop events by default. 123 * 124 * @param enable true if events are to be sent, false otherwise. 125 */ 126 void configureNanoappInfoEvents(bool enable); 127 128 /** 129 * Configures whether host sleep events will be sent to the nanoapp. Nanoapps 130 * are not sent sleep/awake events by default. 131 * 132 * @param enable true if events are to be sent, false otherwise. 133 */ 134 void configureHostSleepEvents(bool enable); 135 136 /** 137 * Configures whether debug dump events will be sent to the nanoapp. Nanoapps 138 * are not sent debug dump events by default. 139 * 140 * @param enable true if events are to be sent, false otherwise. 141 */ 142 void configureDebugDumpEvent(bool enable); 143 144 /** 145 * Configures whether a user settings event will be sent to the nanoapp 146 * for a specified setting (@see CHRE_USER_SETTINGS) 147 * Nanoapps are not sent user settings events by default. 148 * 149 * @param setting The user setting that the nanoapp wishes to configure 150 * events for. 151 * 152 * @param enable true if events are to be sent, false otherwise. 153 */ 154 void configureUserSettingEvent(uint8_t setting, bool enable); 155 156 /** 157 * Sends an event to the nanoapp to be processed. 158 * 159 * @param event A pointer to the event to be processed 160 */ 161 void processEvent(Event *event); 162 163 /** 164 * Log info about a single host wakeup that this nanoapp triggered by storing 165 * the count of wakeups in mWakeupBuckets. 166 */ 167 void blameHostWakeup(); 168 169 /* 170 * If buckets not full, then just pushes a 0 to back of buckets. If full, then 171 * shifts down all buckets from back to front and sets back to 0, losing the 172 * latest bucket value that was in front. 173 * 174 * @param numBuckets the number of buckets to cycle into to mWakeupBuckets 175 */ 176 void cycleWakeupBuckets(size_t numBuckets); 177 178 /** 179 * Prints state in a string buffer. Must only be called from the context of 180 * the main CHRE thread. 181 * 182 * @param debugDump The object that is printed into for debug dump logs. 183 */ 184 void logStateToBuffer(DebugDumpWrapper &debugDump) const; 185 186 /** 187 * @return true if the nanoapp is permitted to use the provided permission. 188 */ 189 bool permitPermissionUse(uint32_t permission) const; 190 191 /** 192 * Configures notification updates for a given host endpoint. 193 * 194 * @param hostEndpointId The ID of the host endpoint. 195 * @param enable true to enable notifications. 196 * 197 * @return true if the configuration is successful. 198 */ 199 bool configureHostEndpointNotifications(uint16_t hostEndpointId, bool enable); 200 201 /** 202 * Publishes RPC services for this nanoapp. 203 * 204 * @param services A pointer to the list of RPC services to publish. 205 * Can be null if numServices is 0. 206 * @param numServices The number of services to publish, i.e. the length of 207 * the services array. 208 * 209 * @return true if the publishing is successful. 210 */ 211 bool publishRpcServices(struct chreNanoappRpcService *services, 212 size_t numServices); 213 214 /** 215 * @return The list of RPC services pushblished by this nanoapp. 216 */ getRpcServices()217 const DynamicVector<struct chreNanoappRpcService> &getRpcServices() const { 218 return mRpcServices; 219 } 220 221 /** 222 * Adds a block of memory to the linked list of headers. 223 * 224 * @see getFirstHeapBlock 225 * @see chreHeapAlloc 226 */ 227 void linkHeapBlock(HeapBlockHeader *header); 228 229 /** 230 * Removes a block of memory from the linked list of headers. 231 * 232 * @see getFirstHeapBlock 233 * @see chreHeapFree 234 */ 235 void unlinkHeapBlock(HeapBlockHeader *header); 236 237 /** 238 * @return A pointer to the first allocated heap block. 239 */ getFirstHeapBlock()240 HeapBlockHeader *getFirstHeapBlock() { 241 return mFirstHeader; 242 } 243 244 private: 245 uint16_t mInstanceId = kInvalidInstanceId; 246 247 //! The total number of wakeup counts for a nanoapp. 248 uint32_t mNumWakeupsSinceBoot = 0; 249 250 /** 251 * Head of the singly linked list of heap block headers. 252 * 253 * The list is used to free all the memory allocated by the nanoapp. 254 * 255 * @see MemoryManager 256 */ 257 HeapBlockHeader *mFirstHeader = nullptr; 258 259 //! The total memory allocated by the nanoapp in bytes. 260 size_t mTotalAllocatedBytes = 0; 261 262 //! The peak total number of bytes allocated by the nanoapp. 263 size_t mPeakAllocatedBytes = 0; 264 265 //! The number of buckets for wakeup logging, adjust along with 266 //! EventLoop::kIntervalWakupBucketInMins. 267 static constexpr size_t kMaxSizeWakeupBuckets = 4; 268 269 //! A fixed size buffer of buckets that keeps track of the number of host 270 //! wakeups over time intervals. 271 FixedSizeVector<uint16_t, kMaxSizeWakeupBuckets> mWakeupBuckets; 272 273 //! Metadata needed for keeping track of the registered events for this 274 //! nanoapp. 275 struct EventRegistration { EventRegistrationEventRegistration276 EventRegistration(uint16_t eventType_, uint16_t groupIdMask_) 277 : eventType(eventType_), groupIdMask(groupIdMask_) {} 278 279 uint16_t eventType; 280 uint16_t groupIdMask; 281 }; 282 283 //! The set of broadcast events that this app is registered for. 284 // TODO: Implement a set container and replace DynamicVector here. There may 285 // also be a better way of handling this (perhaps we map event type to apps 286 // who care about them). 287 DynamicVector<EventRegistration> mRegisteredEvents; 288 289 //! The registered host endpoints to receive notifications for. 290 DynamicVector<uint16_t> mRegisteredHostEndpoints; 291 292 //! The list of RPC services for this nanoapp. 293 DynamicVector<struct chreNanoappRpcService> mRpcServices; 294 295 //! @return index of event registration if found. mRegisteredEvents.size() if 296 //! not. 297 size_t registrationIndex(uint16_t eventType) const; 298 299 /** 300 * A special function to deliver GNSS measurement events to nanoapps and 301 * handles version compatibility. 302 * 303 * @param event The pointer to the event 304 */ 305 void handleGnssMeasurementDataEvent(const Event *event); 306 isRegisteredForHostEndpointNotifications(uint16_t hostEndpointId)307 bool isRegisteredForHostEndpointNotifications(uint16_t hostEndpointId) const { 308 return mRegisteredHostEndpoints.find(hostEndpointId) != 309 mRegisteredHostEndpoints.size(); 310 } 311 }; 312 313 } // namespace chre 314 315 #endif // CHRE_CORE_NANOAPP_H_ 316