Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2016 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 #define LOG_TAG "GnssHal_GnssGeofencing"
     18 
     19 #include "GnssGeofencing.h"
     20 #include <GnssUtils.h>
     21 
     22 namespace android {
     23 namespace hardware {
     24 namespace gnss {
     25 namespace V1_0 {
     26 namespace implementation {
     27 
     28 std::vector<std::unique_ptr<ThreadFuncArgs>> GnssGeofencing::sThreadFuncArgsList;
     29 sp<IGnssGeofenceCallback> GnssGeofencing::mGnssGeofencingCbIface = nullptr;
     30 bool GnssGeofencing::sInterfaceExists = false;
     31 
     32 GpsGeofenceCallbacks GnssGeofencing::sGnssGfCb = {
     33     .geofence_transition_callback = gnssGfTransitionCb,
     34     .geofence_status_callback = gnssGfStatusCb,
     35     .geofence_add_callback = gnssGfAddCb,
     36     .geofence_remove_callback = gnssGfRemoveCb,
     37     .geofence_pause_callback = gnssGfPauseCb,
     38     .geofence_resume_callback = gnssGfResumeCb,
     39     .create_thread_cb = createThreadCb
     40 };
     41 
     42 GnssGeofencing::GnssGeofencing(const GpsGeofencingInterface* gpsGeofencingIface)
     43     : mGnssGeofencingIface(gpsGeofencingIface) {
     44     /* Error out if an instance of the interface already exists. */
     45     LOG_ALWAYS_FATAL_IF(sInterfaceExists);
     46     sInterfaceExists = true;
     47 }
     48 
     49 GnssGeofencing::~GnssGeofencing() {
     50     sThreadFuncArgsList.clear();
     51     sInterfaceExists = false;
     52 }
     53 void GnssGeofencing::gnssGfTransitionCb(int32_t geofenceId,
     54                                         GpsLocation* location,
     55                                         int32_t transition,
     56                                         GpsUtcTime timestamp) {
     57     if (mGnssGeofencingCbIface == nullptr) {
     58         ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
     59         return;
     60     }
     61 
     62     if (location == nullptr) {
     63         ALOGE("%s : Invalid location from GNSS HAL", __func__);
     64         return;
     65     }
     66 
     67     GnssLocation gnssLocation = convertToGnssLocation(location);
     68     auto ret = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
     69             geofenceId,
     70             gnssLocation,
     71             static_cast<IGnssGeofenceCallback::GeofenceTransition>(transition),
     72             timestamp);
     73     if (!ret.isOk()) {
     74         ALOGE("%s: Unable to invoke callback", __func__);
     75     }
     76 }
     77 
     78 void GnssGeofencing::gnssGfStatusCb(int32_t status, GpsLocation* location) {
     79     if (mGnssGeofencingCbIface == nullptr) {
     80         ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
     81         return;
     82     }
     83 
     84     GnssLocation gnssLocation;
     85 
     86     if (location != nullptr) {
     87         gnssLocation = convertToGnssLocation(location);
     88     } else {
     89         gnssLocation = {};
     90     }
     91 
     92     auto ret = mGnssGeofencingCbIface->gnssGeofenceStatusCb(
     93             static_cast<IGnssGeofenceCallback::GeofenceAvailability>(status), gnssLocation);
     94     if (!ret.isOk()) {
     95         ALOGE("%s: Unable to invoke callback", __func__);
     96     }
     97 }
     98 
     99 void GnssGeofencing::gnssGfAddCb(int32_t geofenceId, int32_t status) {
    100     if (mGnssGeofencingCbIface == nullptr) {
    101         ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
    102         return;
    103     }
    104 
    105     auto ret = mGnssGeofencingCbIface->gnssGeofenceAddCb(
    106             geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
    107     if (!ret.isOk()) {
    108         ALOGE("%s: Unable to invoke callback", __func__);
    109     }
    110 }
    111 
    112 void GnssGeofencing::gnssGfRemoveCb(int32_t geofenceId, int32_t status) {
    113     if (mGnssGeofencingCbIface == nullptr) {
    114         ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
    115         return;
    116     }
    117 
    118     auto ret = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(
    119             geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
    120     if (!ret.isOk()) {
    121         ALOGE("%s: Unable to invoke callback", __func__);
    122     }
    123 }
    124 
    125 void GnssGeofencing::gnssGfPauseCb(int32_t geofenceId, int32_t status) {
    126     if (mGnssGeofencingCbIface == nullptr) {
    127         ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
    128         return;
    129     }
    130 
    131     auto ret = mGnssGeofencingCbIface->gnssGeofencePauseCb(
    132             geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
    133     if (!ret.isOk()) {
    134         ALOGE("%s: Unable to invoke callback", __func__);
    135     }
    136 }
    137 
    138 void GnssGeofencing::gnssGfResumeCb(int32_t geofenceId, int32_t status) {
    139     if (mGnssGeofencingCbIface == nullptr) {
    140         ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
    141         return;
    142     }
    143 
    144     auto ret = mGnssGeofencingCbIface->gnssGeofenceResumeCb(
    145             geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
    146     if (!ret.isOk()) {
    147         ALOGE("%s: Unable to invoke callback", __func__);
    148     }
    149 }
    150 
    151 pthread_t GnssGeofencing::createThreadCb(const char* name, void (*start)(void*), void* arg) {
    152     return createPthread(name, start, arg, &sThreadFuncArgsList);
    153 }
    154 
    155 // Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
    156 Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback)  {
    157     mGnssGeofencingCbIface = callback;
    158 
    159     if (mGnssGeofencingIface == nullptr) {
    160         ALOGE("%s: GnssGeofencing interface is not available", __func__);
    161     } else {
    162         mGnssGeofencingIface->init(&sGnssGfCb);
    163     }
    164 
    165     return Void();
    166 }
    167 
    168 Return<void> GnssGeofencing::addGeofence(
    169         int32_t geofenceId,
    170         double latitudeDegrees,
    171         double longitudeDegrees,
    172         double radiusMeters,
    173         IGnssGeofenceCallback::GeofenceTransition lastTransition,
    174         int32_t monitorTransitions,
    175         uint32_t notificationResponsivenessMs,
    176         uint32_t unknownTimerMs)  {
    177     if (mGnssGeofencingIface == nullptr) {
    178         ALOGE("%s: GnssGeofencing interface is not available", __func__);
    179         return Void();
    180     } else {
    181         mGnssGeofencingIface->add_geofence_area(
    182                 geofenceId,
    183                 latitudeDegrees,
    184                 longitudeDegrees,
    185                 radiusMeters,
    186                 static_cast<int32_t>(lastTransition),
    187                 monitorTransitions,
    188                 notificationResponsivenessMs,
    189                 unknownTimerMs);
    190     }
    191     return Void();
    192 }
    193 
    194 Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId)  {
    195     if (mGnssGeofencingIface == nullptr) {
    196         ALOGE("%s: GnssGeofencing interface is not available", __func__);
    197     } else {
    198         mGnssGeofencingIface->pause_geofence(geofenceId);
    199     }
    200     return Void();
    201 }
    202 
    203 Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions)  {
    204     if (mGnssGeofencingIface == nullptr) {
    205         ALOGE("%s: GnssGeofencing interface is not available", __func__);
    206     } else {
    207         mGnssGeofencingIface->resume_geofence(geofenceId, monitorTransitions);
    208     }
    209     return Void();
    210 }
    211 
    212 Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId)  {
    213     if (mGnssGeofencingIface == nullptr) {
    214         ALOGE("%s: GnssGeofencing interface is not available", __func__);
    215     } else {
    216         mGnssGeofencingIface->remove_geofence_area(geofenceId);
    217     }
    218     return Void();
    219 }
    220 
    221 }  // namespace implementation
    222 }  // namespace V1_0
    223 }  // namespace gnss
    224 }  // namespace hardware
    225 }  // namespace android
    226