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