Home | History | Annotate | Download | only in location_api
      1 /* Copyright (c) 2017, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation, nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #define LOG_NDDEBUG 0
     31 #define LOG_TAG "LocSvc_GeofenceApiClient"
     32 
     33 #include <log_util.h>
     34 #include <loc_cfg.h>
     35 
     36 #include "LocationUtil.h"
     37 #include "GeofenceAPIClient.h"
     38 
     39 namespace android {
     40 namespace hardware {
     41 namespace gnss {
     42 namespace V1_0 {
     43 namespace implementation {
     44 
     45 
     46 GeofenceAPIClient::GeofenceAPIClient(const sp<IGnssGeofenceCallback>& callback) :
     47     LocationAPIClientBase(),
     48     mGnssGeofencingCbIface(callback)
     49 {
     50     LOC_LOGD("%s]: (%p)", __FUNCTION__, &callback);
     51 
     52     LocationCallbacks locationCallbacks;
     53     locationCallbacks.size = sizeof(LocationCallbacks);
     54 
     55     locationCallbacks.trackingCb = nullptr;
     56     locationCallbacks.batchingCb = nullptr;
     57 
     58     locationCallbacks.geofenceBreachCb = nullptr;
     59     if (mGnssGeofencingCbIface != nullptr) {
     60         locationCallbacks.geofenceBreachCb =
     61             [this](GeofenceBreachNotification geofenceBreachNotification) {
     62                 onGeofenceBreachCb(geofenceBreachNotification);
     63             };
     64 
     65         locationCallbacks.geofenceStatusCb =
     66             [this](GeofenceStatusNotification geofenceStatusNotification) {
     67                 onGeofenceStatusCb(geofenceStatusNotification);
     68             };
     69     }
     70 
     71     locationCallbacks.gnssLocationInfoCb = nullptr;
     72     locationCallbacks.gnssNiCb = nullptr;
     73     locationCallbacks.gnssSvCb = nullptr;
     74     locationCallbacks.gnssNmeaCb = nullptr;
     75     locationCallbacks.gnssMeasurementsCb = nullptr;
     76 
     77     locAPISetCallbacks(locationCallbacks);
     78 }
     79 
     80 void GeofenceAPIClient::geofenceAdd(uint32_t geofence_id, double latitude, double longitude,
     81         double radius_meters, int32_t last_transition, int32_t monitor_transitions,
     82         uint32_t notification_responsiveness_ms, uint32_t unknown_timer_ms)
     83 {
     84     LOC_LOGD("%s]: (%d %f %f %f %d %d %d %d)", __FUNCTION__,
     85             geofence_id, latitude, longitude, radius_meters,
     86             last_transition, monitor_transitions, notification_responsiveness_ms, unknown_timer_ms);
     87 
     88     GeofenceOption options;
     89     memset(&options, 0, sizeof(GeofenceOption));
     90     options.size = sizeof(GeofenceOption);
     91     if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
     92         options.breachTypeMask |= GEOFENCE_BREACH_ENTER_BIT;
     93     if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
     94         options.breachTypeMask |=  GEOFENCE_BREACH_EXIT_BIT;
     95     options.responsiveness = notification_responsiveness_ms;
     96 
     97     GeofenceInfo data;
     98     data.size = sizeof(GeofenceInfo);
     99     data.latitude = latitude;
    100     data.longitude = longitude;
    101     data.radius = radius_meters;
    102 
    103     LocationError err = (LocationError)locAPIAddGeofences(1, &geofence_id, &options, &data);
    104     if (LOCATION_ERROR_SUCCESS != err) {
    105         onAddGeofencesCb(1, &err, &geofence_id);
    106     }
    107 }
    108 
    109 void GeofenceAPIClient::geofencePause(uint32_t geofence_id)
    110 {
    111     LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
    112     locAPIPauseGeofences(1, &geofence_id);
    113 }
    114 
    115 void GeofenceAPIClient::geofenceResume(uint32_t geofence_id, int32_t monitor_transitions)
    116 {
    117     LOC_LOGD("%s]: (%d %d)", __FUNCTION__, geofence_id, monitor_transitions);
    118     GeofenceBreachTypeMask mask = 0;
    119     if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::ENTERED)
    120         mask |= GEOFENCE_BREACH_ENTER_BIT;
    121     if (monitor_transitions & IGnssGeofenceCallback::GeofenceTransition::EXITED)
    122         mask |=  GEOFENCE_BREACH_EXIT_BIT;
    123     locAPIResumeGeofences(1, &geofence_id, &mask);
    124 }
    125 
    126 void GeofenceAPIClient::geofenceRemove(uint32_t geofence_id)
    127 {
    128     LOC_LOGD("%s]: (%d)", __FUNCTION__, geofence_id);
    129     locAPIRemoveGeofences(1, &geofence_id);
    130 }
    131 
    132 void GeofenceAPIClient::geofenceRemoveAll()
    133 {
    134     LOC_LOGD("%s]", __FUNCTION__);
    135     // TODO locAPIRemoveAllGeofences();
    136 }
    137 
    138 // callbacks
    139 void GeofenceAPIClient::onGeofenceBreachCb(GeofenceBreachNotification geofenceBreachNotification)
    140 {
    141     LOC_LOGD("%s]: (%zu)", __FUNCTION__, geofenceBreachNotification.count);
    142     if (mGnssGeofencingCbIface != nullptr) {
    143         for (size_t i = 0; i < geofenceBreachNotification.count; i++) {
    144             GnssLocation gnssLocation;
    145             convertGnssLocation(geofenceBreachNotification.location, gnssLocation);
    146 
    147             IGnssGeofenceCallback::GeofenceTransition transition;
    148             if (geofenceBreachNotification.type == GEOFENCE_BREACH_ENTER)
    149                 transition = IGnssGeofenceCallback::GeofenceTransition::ENTERED;
    150             else if (geofenceBreachNotification.type == GEOFENCE_BREACH_EXIT)
    151                 transition = IGnssGeofenceCallback::GeofenceTransition::EXITED;
    152             else {
    153                 // continue with other breach if transition is
    154                 // nether GPS_GEOFENCE_ENTERED nor GPS_GEOFENCE_EXITED
    155                 continue;
    156             }
    157 
    158             mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
    159                     geofenceBreachNotification.ids[i], gnssLocation, transition,
    160                     static_cast<GnssUtcTime>(geofenceBreachNotification.timestamp));
    161         }
    162     }
    163 }
    164 
    165 void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification)
    166 {
    167     LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available);
    168     if (mGnssGeofencingCbIface != nullptr) {
    169         IGnssGeofenceCallback::GeofenceAvailability status =
    170             IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE;
    171         if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) {
    172             status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE;
    173         }
    174         GnssLocation gnssLocation;
    175         memset(&gnssLocation, 0, sizeof(GnssLocation));
    176         mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation);
    177     }
    178 }
    179 
    180 void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
    181 {
    182     LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
    183     if (mGnssGeofencingCbIface != nullptr) {
    184         for (size_t i = 0; i < count; i++) {
    185             IGnssGeofenceCallback::GeofenceStatus status =
    186                 IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
    187             if (errors[i] == LOCATION_ERROR_SUCCESS)
    188                 status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
    189             else if (errors[i] == LOCATION_ERROR_ID_EXISTS)
    190                 status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS;
    191             mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status);
    192         }
    193     }
    194 }
    195 
    196 void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
    197 {
    198     LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
    199     if (mGnssGeofencingCbIface != nullptr) {
    200         for (size_t i = 0; i < count; i++) {
    201             IGnssGeofenceCallback::GeofenceStatus status =
    202                 IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
    203             if (errors[i] == LOCATION_ERROR_SUCCESS)
    204                 status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
    205             else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
    206                 status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
    207             mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status);
    208         }
    209     }
    210 }
    211 
    212 void GeofenceAPIClient::onPauseGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
    213 {
    214     LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
    215     if (mGnssGeofencingCbIface != nullptr) {
    216         for (size_t i = 0; i < count; i++) {
    217             IGnssGeofenceCallback::GeofenceStatus status =
    218                 IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
    219             if (errors[i] == LOCATION_ERROR_SUCCESS)
    220                 status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
    221             else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
    222                 status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
    223             mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status);
    224         }
    225     }
    226 }
    227 
    228 void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
    229 {
    230     LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
    231     if (mGnssGeofencingCbIface != nullptr) {
    232         for (size_t i = 0; i < count; i++) {
    233             IGnssGeofenceCallback::GeofenceStatus status =
    234                 IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
    235             if (errors[i] == LOCATION_ERROR_SUCCESS)
    236                 status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
    237             else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
    238                 status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
    239             mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status);
    240         }
    241     }
    242 }
    243 
    244 }  // namespace implementation
    245 }  // namespace V1_0
    246 }  // namespace gnss
    247 }  // namespace hardware
    248 }  // namespace android
    249