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