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 
27 namespace chre {
28 
29 /**
30  * A class that tracks the state of a Nanoapp including incoming events and
31  * event registrations.
32  *
33  * Inheritance is used to separate the common interface with common
34  * implementation part (chre::Nanoapp) from the common interface with
35  * platform-specific implementation part (chre::PlatformNanoapp) from the purely
36  * platform-specific part (chre::PlatformNanoappBase). However, this inheritance
37  * relationship does *not* imply polymorphism, and this object must only be
38  * referred to via the most-derived type, i.e. chre::Nanoapp.
39  */
40 class Nanoapp : public PlatformNanoapp {
41  public:
42   ~Nanoapp();
43 
44   /**
45    * @return The unique identifier for this Nanoapp instance
46    */
getInstanceId()47   uint32_t getInstanceId() const {
48     return mInstanceId;
49   }
50 
51   /**
52    * Assigns an instance ID to this Nanoapp. This must be called prior to
53    * starting this Nanoapp.
54    */
setInstanceId(uint32_t instanceId)55   void setInstanceId(uint32_t instanceId) {
56     mInstanceId = instanceId;
57   }
58 
59   /**
60    * @return The current total number of bytes the nanoapp has allocated.
61    */
getTotalAllocatedBytes()62   size_t getTotalAllocatedBytes() const {
63     return mTotalAllocatedBytes;
64   }
65 
66   /**
67    * @return The peak total number of bytes the nanoapp has allocated.
68    */
getPeakAllocatedBytes()69   size_t getPeakAllocatedBytes() const {
70     return mPeakAllocatedBytes;
71   }
72 
73 
74   /**
75    * Sets the total number of bytes the nanoapp has allocated. Also, modifies
76    * the peak allocated bytes if the current total is higher than the peak.
77    *
78    * @param The total number of bytes the nanoapp has allocated.
79    */
setTotalAllocatedBytes(size_t totalAllocatedBytes)80   void setTotalAllocatedBytes(size_t totalAllocatedBytes) {
81     mTotalAllocatedBytes = totalAllocatedBytes;
82     if (mTotalAllocatedBytes > mPeakAllocatedBytes) {
83       mPeakAllocatedBytes = mTotalAllocatedBytes;
84     }
85   }
86 
87   /**
88    * @return true if the nanoapp should receive broadcast events with the given
89    *         type
90    */
91   bool isRegisteredForBroadcastEvent(uint16_t eventType) const;
92 
93   /**
94    * Updates the Nanoapp's registration so that it will receive broadcast events
95    * with the given event ID.
96    *
97    * @return true if the event is newly registered
98    */
99   bool registerForBroadcastEvent(uint16_t eventId);
100 
101   /**
102    * Updates the Nanoapp's registration so that it will not receive broadcast
103    * events with the given event ID.
104    *
105    * @return true if the event was previously registered
106    */
107   bool unregisterForBroadcastEvent(uint16_t eventId);
108 
109   /**
110    * Adds an event to this nanoapp's queue of pending events.
111    */
postEvent(Event * event)112   void postEvent(Event *event) {
113     mEventQueue.push(event);
114   }
115 
116   /**
117    * Indicates whether there are any pending events in this apps queue.
118    *
119    * @return true if there are events waiting to be processed
120    */
hasPendingEvent()121   bool hasPendingEvent() {
122     return !mEventQueue.empty();
123   }
124 
125   /**
126    * Configures whether nanoapp info events will be sent to the nanoapp.
127    * Nanoapps are not sent nanoapp start/stop events by default.
128    *
129    * @param enable true if events are to be sent, false otherwise.
130    */
131   void configureNanoappInfoEvents(bool enable);
132 
133   /**
134    * Configures whether host sleep events will be sent to the nanoapp. Nanoapps
135    * are not sent sleep/awake events by default.
136    *
137    * @param enable true if events are to be sent, false otherwise.
138    */
139   void configureHostSleepEvents(bool enable);
140 
141   /**
142    * Sends the next event in the queue to the nanoapp and returns the processed
143    * event. The hasPendingEvent() method should be tested before invoking this.
144    *
145    * @return A pointer to the processed event
146    */
147   Event *processNextEvent();
148 
149   /**
150    * Prints state in a string buffer. Must only be called from the context of
151    * the main CHRE thread.
152    *
153    * @param buffer Pointer to the start of the buffer.
154    * @param bufferPos Pointer to buffer position to start the print (in-out).
155    * @param size Size of the buffer in bytes.
156    */
157   void logStateToBuffer(char *buffer, size_t *bufferPos,
158                         size_t bufferSize) const;
159 
160  private:
161   uint32_t mInstanceId = kInvalidInstanceId;
162 
163   //! The total memory allocated by the nanoapp in bytes.
164   size_t mTotalAllocatedBytes = 0;
165 
166   //! The peak total number of bytes allocated by the nanoapp.
167   size_t mPeakAllocatedBytes = 0;
168 
169   //! The set of broadcast events that this app is registered for.
170   // TODO: Implement a set container and replace DynamicVector here. There may
171   // also be a better way of handling this (perhaps we map event type to apps
172   // who care about them).
173   DynamicVector<uint16_t> mRegisteredEvents;
174 
175   EventRefQueue mEventQueue;
176 };
177 
178 }
179 
180 #endif  // CHRE_CORE_NANOAPP_H_
181