gnss_request_manager.h revision 4d4114f774c181bf46cf57f36f68cc0674dd347c
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 private: 95 /** 96 * Tracks a nanoapp that has subscribed to a location session and the 97 * reporting interval. 98 */ 99 struct LocationSessionRequest { 100 //! The nanoapp instance ID that made this request. 101 uint32_t nanoappInstanceId; 102 103 //! The interval of location results requested. 104 Milliseconds minInterval; 105 }; 106 107 /** 108 * Tracks the state of the locationing engine. 109 */ 110 struct LocationSessionStateTransition { 111 //! The nanoapp instance ID that prompted the change. 112 uint32_t nanoappInstanceId; 113 114 //! The cookie provided to the CHRE API when the nanoapp requested a change 115 //! to the state of the location engine. 116 const void *cookie; 117 118 //! The target state of the location engine. 119 bool enable; 120 121 //! The target minimum reporting interval for the location engine. This is 122 //! only valid if enable is set to true. 123 Milliseconds minInterval; 124 }; 125 126 //! The maximum number of state transitions allowed for location and GNSS 127 //! measurement resources. 128 static constexpr size_t kMaxGnssStateTransitions = 8; 129 130 //! The instance of the platform GNSS interface. 131 PlatformGnss mPlatformGnss; 132 133 //! The queue of state transitions for the location engine. Only one 134 //! asynchronous location engine state transition can be in flight at one 135 //! time. Any further requests are queued here. 136 ArrayQueue<LocationSessionStateTransition, 137 kMaxGnssStateTransitions> mLocationSessionStateTransitions; 138 139 //! The request multiplexer for GNSS location requests. 140 DynamicVector<LocationSessionRequest> mLocationSessionRequests; 141 142 //! The current interval being sent to the location session. This is only 143 //! valid if the mLocationSessionRequests is non-empty. 144 Milliseconds mCurrentLocationSessionInterval; 145 146 /** 147 * Configures the location engine to be enabled/disabled. If enable is set to 148 * true then the minInterval and minTimeToFirstFix values are valid. 149 * 150 * @param nanoapp The nanoapp requesting the state change for the location 151 * engine. 152 * @param enable Whether to enable or disable the location engine. 153 * @param minInterval The minimum location reporting interval requested by the 154 * nanoapp. 155 * @param minTimeToFirstFix The minimum time to the first fix. 156 * @param cookie The cookie provided by the nanoapp to round-trip for context. 157 * @return true if the request was accepted. 158 */ 159 bool configureLocationSession(Nanoapp *nanoapp, bool enable, 160 Milliseconds minInterval, 161 Milliseconds minTimeToFirstFix, 162 const void *cookie); 163 164 /** 165 * Checks if a nanoapp has an open location session request. 166 * 167 * @param instanceId The nanoapp instance ID to search for. 168 * @param requestIndex A pointer to an index to populate if the nanoapp has an 169 * open location session. 170 * @return true if the provided instanceId was found. 171 */ 172 bool nanoappHasLocationSessionRequest(uint32_t instanceId, 173 size_t *requestIndex = nullptr); 174 175 /** 176 * Adds a request for a location session to the queue of state transitions. 177 * 178 * @param instanceId The nanoapp instance ID requesting a location session. 179 * @param enable Whether the location session is being enabled or disabled for 180 * this nanoapp. 181 * @param minInterval The minimum interval reqested by the nanoapp. 182 * @param cookie A cookie that is round-tripped to the nanoapp for context. 183 * @return true if the state transition was added to the queue. 184 */ 185 bool addLocationSessionRequestToQueue(uint32_t instanceId, bool enable, 186 Milliseconds minInterval, 187 const void *cookie); 188 189 /** 190 * @return true if the location session is currently enabled. 191 */ 192 bool locationSessionIsEnabled(); 193 194 /** 195 * Determines if the location session is already in the requested state. 196 * 197 * @param requestedState The target state of the location session. 198 * @param minInterval The reporting interval if the requestedState is true. 199 * @param nanoappHasRequest true if the requesting nanoapp already has an 200 * outstanding request. 201 * @return true if the location session is already in the requested state. 202 */ 203 bool locationSessionIsInRequestedState(bool requestedState, 204 Milliseconds minInterval, 205 bool nanoappHasRequest); 206 207 /** 208 * Determines if a change to the location session state is required given a 209 * set of parameters. 210 * 211 * @param requestedState The target state requested by a nanoapp. 212 * @param minInterval The minimum location reporting interval. 213 * @param nanoappHasRequest If the nanoapp already has a request. 214 * @param requestIndex The index of the request in the list of open requests 215 * if nanoappHasRequest is set to true. 216 * @return true if a state transition is required. 217 */ 218 bool locationSessionStateTransitionIsRequired(bool requestedState, 219 Milliseconds minInterval, 220 bool nanoappHasRequest, 221 size_t requestIndex); 222 223 /** 224 * Updates the location session requests given a nanoapp and the interval 225 * requested. 226 * 227 * @param enable true if enabling the location session. 228 * @param minInterval the minimum reporting interval if enable is set to true. 229 * @param instanceId the nanoapp instance ID that owns the request. 230 * @return true if the location session request list was updated. 231 */ 232 bool updateLocationSessionRequests(bool enable, Milliseconds minInterval, 233 uint32_t instanceId); 234 235 /** 236 * Posts the result of a GNSS location session start/stop request. 237 * 238 * @param instanceId The nanoapp instance ID that made the request. 239 * @param success true if the operation was successful. 240 * @param enable true if enabling the location session. 241 * @param minInterval the minimum location reporting interval. 242 * @param errorCode the error code as a result of this operation. 243 * @param cookie the cookie that the nanoapp is provided for context. 244 * @return true if the event was successfully posted. 245 */ 246 bool postLocationSessionAsyncResultEvent( 247 uint32_t instanceId, bool success, bool enable, Milliseconds minInterval, 248 uint8_t errorCode, const void *cookie); 249 250 /** 251 * Calls through to postLocationSessionAsyncResultEvent but invokes 252 * FATAL_ERROR if the event is not posted successfully. This is used in 253 * asynchronous contexts where a nanoapp could be stuck waiting for a response 254 * but CHRE failed to enqueue one. For parameter details, 255 * @see postLocationSessionAsyncResultEvent 256 */ 257 void postLocationSessionAsyncResultEventFatal( 258 uint32_t instanceId, bool success, bool enable, Milliseconds minInterval, 259 uint8_t errorCode, const void *cookie); 260 261 /** 262 * Handles the result of a request to PlatformGnss to change the state of the 263 * scan monitor. See the handleLocationSessionStatusChange method which may be 264 * called from any thread. This method is intended to be invoked on the CHRE 265 * event loop thread. 266 * 267 * @param enabled true if the location session was enabled 268 * @param errorCode an error code that is provided to indicate success. 269 */ 270 void handleLocationSessionStatusChangeSync(bool enabled, uint8_t errorCode); 271 272 /** 273 * Handles the releasing of a GNSS location event. 274 * 275 * @param event The event to free. 276 */ 277 void handleFreeLocationEvent(chreGnssLocationEvent *event); 278 279 /** 280 * Releases a GNSS location event after nanoapps have consumed it. 281 * 282 * @param eventType the type of event being freed. 283 * @param eventData a pointer to the scan event to release. 284 */ 285 static void freeLocationEventCallback(uint16_t eventType, void *eventData); 286}; 287 288} // namespace chre 289 290#endif // CHRE_CORE_GNSS_REQUEST_MANAGER_H_ 291