• 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_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