gnss_request_manager.h revision 9418557f186eb102966f9049658722c3ff31c840
1/* 2 * Copyright (C) 2017 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_GNSS_REQUEST_MANAGER_H_ 18#define CHRE_CORE_GNSS_REQUEST_MANAGER_H_ 19 20#include <cstdint> 21 22#include "chre/core/nanoapp.h" 23#include "chre/platform/platform_gnss.h" 24#include "chre/util/non_copyable.h" 25#include "chre/util/time.h" 26 27namespace chre { 28 29/** 30 * The GnssRequestManager handles requests from nanoapps for GNSS data. This 31 * includes multiplexing multiple requests into one for the platform to handle. 32 * 33 * This class is effectively a singleton as there can only be one instance of 34 * the PlatformGnss instance. 35 */ 36class GnssRequestManager : public NonCopyable { 37 public: 38 /** 39 * Initializes a GnssRequestManager. 40 */ 41 GnssRequestManager(); 42 43 /** 44 * @return the GNSS capabilities exposed by this platform. 45 */ 46 uint32_t getCapabilities(); 47 48 /** 49 * Starts a location session asynchronously. The result is delivered through 50 * a CHRE_EVENT_GNSS_ASYNC_RESULT event. 51 * 52 * @param nanoapp The nanoapp requesting the location session. 53 * @param minInterval The minimum reporting interval for location results. 54 * @param timeToNextFix The amount of time that the locationing system is 55 * allowed to delay generating a fix. 56 * @param cookie A cookie that is round-tripped to provide context to the 57 * nanoapp making the request. 58 * @return true if the request was accepted for processing. 59 */ 60 bool startLocationSession(Nanoapp *nanoapp, Milliseconds minInterval, 61 Milliseconds minTimeToNextFix, const void *cookie); 62 63 /** 64 * Stops a location session asynchronously. The result is delivered through a 65 * CHRE_EVENT_GNSS_ASYNC_RESULT event. 66 * 67 * @param nanoapp The nanoapp requesting the location session to stop. 68 * @param cookie A cookie that is round-tripped to provide context to the 69 * nanoapp making the request. 70 * @return true if the request was accepted for processing. 71 */ 72 bool stopLocationSession(Nanoapp *nanoapp, const void *cookie); 73 74 /** 75 * Handles the result of a request to the PlatformGnss to request a change to 76 * the location session. 77 * 78 * @param enabled true if the location session is currently active 79 * @param errorCode an error code that is used to indicate success or what 80 * type of error has occured. See chreError enum in the CHRE API for 81 * additional details. 82 */ 83 void handleLocationSessionStatusChange(bool enabled, uint8_t errorCode); 84 85 /** 86 * Handles a CHRE GNSS location event. 87 * 88 * @param event The GNSS location event provided to the GNSS request manager. 89 * This memory is guaranteed not to be modified until it has been 90 * explicitly released through the PlatformGnss instance. 91 */ 92 void handleLocationEvent(chreGnssLocationEvent *event); 93 94 /** 95 * Prints state in a string buffer. Must only be called from the context of 96 * the main CHRE thread. 97 * 98 * @param buffer Pointer to the start of the buffer. 99 * @param bufferPos Pointer to buffer position to start the print (in-out). 100 * @param size Size of the buffer in bytes. 101 * 102 * @return true if entire log printed, false if overflow or error. 103 */ 104 bool logStateToBuffer(char *buffer, size_t *bufferPos, 105 size_t bufferSize) const; 106 107 private: 108 /** 109 * Tracks a nanoapp that has subscribed to a location session and the 110 * reporting interval. 111 */ 112 struct LocationSessionRequest { 113 //! The nanoapp instance ID that made this request. 114 uint32_t nanoappInstanceId; 115 116 //! The interval of location results requested. 117 Milliseconds minInterval; 118 }; 119 120 /** 121 * Tracks the state of the locationing engine. 122 */ 123 struct LocationSessionStateTransition { 124 //! The nanoapp instance ID that prompted the change. 125 uint32_t nanoappInstanceId; 126 127 //! The cookie provided to the CHRE API when the nanoapp requested a change 128 //! to the state of the location engine. 129 const void *cookie; 130 131 //! The target state of the location engine. 132 bool enable; 133 134 //! The target minimum reporting interval for the location engine. This is 135 //! only valid if enable is set to true. 136 Milliseconds minInterval; 137 }; 138 139 //! The maximum number of state transitions allowed for location and GNSS 140 //! measurement resources. 141 static constexpr size_t kMaxGnssStateTransitions = 8; 142 143 //! The instance of the platform GNSS interface. 144 PlatformGnss mPlatformGnss; 145 146 //! The queue of state transitions for the location engine. Only one 147 //! asynchronous location engine state transition can be in flight at one 148 //! time. Any further requests are queued here. 149 ArrayQueue<LocationSessionStateTransition, 150 kMaxGnssStateTransitions> mLocationSessionStateTransitions; 151 152 //! The request multiplexer for GNSS location requests. 153 DynamicVector<LocationSessionRequest> mLocationSessionRequests; 154 155 //! The current interval being sent to the location session. This is only 156 //! valid if the mLocationSessionRequests is non-empty. 157 Milliseconds mCurrentLocationSessionInterval; 158 159 /** 160 * Configures the location engine to be enabled/disabled. If enable is set to 161 * true then the minInterval and minTimeToFirstFix values are valid. 162 * 163 * @param nanoapp The nanoapp requesting the state change for the location 164 * engine. 165 * @param enable Whether to enable or disable the location engine. 166 * @param minInterval The minimum location reporting interval requested by the 167 * nanoapp. 168 * @param minTimeToFirstFix The minimum time to the first fix. 169 * @param cookie The cookie provided by the nanoapp to round-trip for context. 170 * @return true if the request was accepted. 171 */ 172 bool configureLocationSession(Nanoapp *nanoapp, bool enable, 173 Milliseconds minInterval, 174 Milliseconds minTimeToFirstFix, 175 const void *cookie); 176 177 /** 178 * Checks if a nanoapp has an open location session request. 179 * 180 * @param instanceId The nanoapp instance ID to search for. 181 * @param requestIndex A pointer to an index to populate if the nanoapp has an 182 * open location session. 183 * @return true if the provided instanceId was found. 184 */ 185 bool nanoappHasLocationSessionRequest(uint32_t instanceId, 186 size_t *requestIndex = nullptr); 187 188 /** 189 * Adds a request for a location session to the queue of state transitions. 190 * 191 * @param instanceId The nanoapp instance ID requesting a location session. 192 * @param enable Whether the location session is being enabled or disabled for 193 * this nanoapp. 194 * @param minInterval The minimum interval reqested by the nanoapp. 195 * @param cookie A cookie that is round-tripped to the nanoapp for context. 196 * @return true if the state transition was added to the queue. 197 */ 198 bool addLocationSessionRequestToQueue(uint32_t instanceId, bool enable, 199 Milliseconds minInterval, 200 const void *cookie); 201 202 /** 203 * @return true if the location session is currently enabled. 204 */ 205 bool locationSessionIsEnabled(); 206 207 /** 208 * Determines if the location session is already in the requested state. 209 * 210 * @param requestedState The target state of the location session. 211 * @param minInterval The reporting interval if the requestedState is true. 212 * @param nanoappHasRequest true if the requesting nanoapp already has an 213 * outstanding request. 214 * @return true if the location session is already in the requested state. 215 */ 216 bool locationSessionIsInRequestedState(bool requestedState, 217 Milliseconds minInterval, 218 bool nanoappHasRequest); 219 220 /** 221 * Determines if a change to the location session state is required given a 222 * set of parameters. 223 * 224 * @param requestedState The target state requested by a nanoapp. 225 * @param minInterval The minimum location reporting interval. 226 * @param nanoappHasRequest If the nanoapp already has a request. 227 * @param requestIndex The index of the request in the list of open requests 228 * if nanoappHasRequest is set to true. 229 * @return true if a state transition is required. 230 */ 231 bool locationSessionStateTransitionIsRequired(bool requestedState, 232 Milliseconds minInterval, 233 bool nanoappHasRequest, 234 size_t requestIndex); 235 236 /** 237 * Updates the location session requests given a nanoapp and the interval 238 * requested. 239 * 240 * @param enable true if enabling the location session. 241 * @param minInterval the minimum reporting interval if enable is set to true. 242 * @param instanceId the nanoapp instance ID that owns the request. 243 * @return true if the location session request list was updated. 244 */ 245 bool updateLocationSessionRequests(bool enable, Milliseconds minInterval, 246 uint32_t instanceId); 247 248 /** 249 * Posts the result of a GNSS location session start/stop request. 250 * 251 * @param instanceId The nanoapp instance ID that made the request. 252 * @param success true if the operation was successful. 253 * @param enable true if enabling the location session. 254 * @param minInterval the minimum location reporting interval. 255 * @param errorCode the error code as a result of this operation. 256 * @param cookie the cookie that the nanoapp is provided for context. 257 * @return true if the event was successfully posted. 258 */ 259 bool postLocationSessionAsyncResultEvent( 260 uint32_t instanceId, bool success, bool enable, Milliseconds minInterval, 261 uint8_t errorCode, const void *cookie); 262 263 /** 264 * Calls through to postLocationSessionAsyncResultEvent but invokes 265 * FATAL_ERROR if the event is not posted successfully. This is used in 266 * asynchronous contexts where a nanoapp could be stuck waiting for a response 267 * but CHRE failed to enqueue one. For parameter details, 268 * @see postLocationSessionAsyncResultEvent 269 */ 270 void postLocationSessionAsyncResultEventFatal( 271 uint32_t instanceId, bool success, bool enable, Milliseconds minInterval, 272 uint8_t errorCode, const void *cookie); 273 274 /** 275 * Handles the result of a request to PlatformGnss to change the state of the 276 * scan monitor. See the handleLocationSessionStatusChange method which may be 277 * called from any thread. This method is intended to be invoked on the CHRE 278 * event loop thread. 279 * 280 * @param enabled true if the location session was enabled 281 * @param errorCode an error code that is provided to indicate success. 282 */ 283 void handleLocationSessionStatusChangeSync(bool enabled, uint8_t errorCode); 284 285 /** 286 * Handles the releasing of a GNSS location event. 287 * 288 * @param event The event to free. 289 */ 290 void handleFreeLocationEvent(chreGnssLocationEvent *event); 291 292 /** 293 * Releases a GNSS location event after nanoapps have consumed it. 294 * 295 * @param eventType the type of event being freed. 296 * @param eventData a pointer to the scan event to release. 297 */ 298 static void freeLocationEventCallback(uint16_t eventType, void *eventData); 299}; 300 301} // namespace chre 302 303#endif // CHRE_CORE_GNSS_REQUEST_MANAGER_H_ 304