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