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             auto r = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
    159                     geofenceBreachNotification.ids[i], gnssLocation, transition,
    160                     static_cast<GnssUtcTime>(geofenceBreachNotification.timestamp));
    161             if (!r.isOk()) {
    162                 LOC_LOGE("%s] Error from gnssGeofenceTransitionCb description=%s",
    163                     __func__, r.description().c_str());
    164             }
    165         }
    166     }
    167 }
    168 
    169 void GeofenceAPIClient::onGeofenceStatusCb(GeofenceStatusNotification geofenceStatusNotification)
    170 {
    171     LOC_LOGD("%s]: (%d)", __FUNCTION__, geofenceStatusNotification.available);
    172     if (mGnssGeofencingCbIface != nullptr) {
    173         IGnssGeofenceCallback::GeofenceAvailability status =
    174             IGnssGeofenceCallback::GeofenceAvailability::UNAVAILABLE;
    175         if (geofenceStatusNotification.available == GEOFENCE_STATUS_AVAILABILE_YES) {
    176             status = IGnssGeofenceCallback::GeofenceAvailability::AVAILABLE;
    177         }
    178         GnssLocation gnssLocation;
    179         memset(&gnssLocation, 0, sizeof(GnssLocation));
    180         auto r = mGnssGeofencingCbIface->gnssGeofenceStatusCb(status, gnssLocation);
    181         if (!r.isOk()) {
    182             LOC_LOGE("%s] Error from gnssGeofenceStatusCb description=%s",
    183                 __func__, r.description().c_str());
    184         }
    185     }
    186 }
    187 
    188 void GeofenceAPIClient::onAddGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
    189 {
    190     LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
    191     if (mGnssGeofencingCbIface != nullptr) {
    192         for (size_t i = 0; i < count; i++) {
    193             IGnssGeofenceCallback::GeofenceStatus status =
    194                 IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
    195             if (errors[i] == LOCATION_ERROR_SUCCESS)
    196                 status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
    197             else if (errors[i] == LOCATION_ERROR_ID_EXISTS)
    198                 status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_EXISTS;
    199             auto r = mGnssGeofencingCbIface->gnssGeofenceAddCb(ids[i], status);
    200             if (!r.isOk()) {
    201                 LOC_LOGE("%s] Error from gnssGeofenceAddCb description=%s",
    202                     __func__, r.description().c_str());
    203             }
    204         }
    205     }
    206 }
    207 
    208 void GeofenceAPIClient::onRemoveGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
    209 {
    210     LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
    211     if (mGnssGeofencingCbIface != nullptr) {
    212         for (size_t i = 0; i < count; i++) {
    213             IGnssGeofenceCallback::GeofenceStatus status =
    214                 IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
    215             if (errors[i] == LOCATION_ERROR_SUCCESS)
    216                 status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
    217             else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
    218                 status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
    219             auto r = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(ids[i], status);
    220             if (!r.isOk()) {
    221                 LOC_LOGE("%s] Error from gnssGeofenceRemoveCb description=%s",
    222                     __func__, r.description().c_str());
    223             }
    224         }
    225     }
    226 }
    227 
    228 void GeofenceAPIClient::onPauseGeofencesCb(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             auto r = mGnssGeofencingCbIface->gnssGeofencePauseCb(ids[i], status);
    240             if (!r.isOk()) {
    241                 LOC_LOGE("%s] Error from gnssGeofencePauseCb description=%s",
    242                     __func__, r.description().c_str());
    243             }
    244         }
    245     }
    246 }
    247 
    248 void GeofenceAPIClient::onResumeGeofencesCb(size_t count, LocationError* errors, uint32_t* ids)
    249 {
    250     LOC_LOGD("%s]: (%zu)", __FUNCTION__, count);
    251     if (mGnssGeofencingCbIface != nullptr) {
    252         for (size_t i = 0; i < count; i++) {
    253             IGnssGeofenceCallback::GeofenceStatus status =
    254                 IGnssGeofenceCallback::GeofenceStatus::ERROR_GENERIC;
    255             if (errors[i] == LOCATION_ERROR_SUCCESS)
    256                 status = IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS;
    257             else if (errors[i] == LOCATION_ERROR_ID_UNKNOWN)
    258                 status = IGnssGeofenceCallback::GeofenceStatus::ERROR_ID_UNKNOWN;
    259             auto r = mGnssGeofencingCbIface->gnssGeofenceResumeCb(ids[i], status);
    260             if (!r.isOk()) {
    261                 LOC_LOGE("%s] Error from gnssGeofenceResumeCb description=%s",
    262                     __func__, r.description().c_str());
    263             }
    264         }
    265     }
    266 }
    267 
    268 }  // namespace implementation
    269 }  // namespace V1_0
    270 }  // namespace gnss
    271 }  // namespace hardware
    272 }  // namespace android
    273