• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GnssGeofencing(const GpsGeofencingInterface * gpsGeofencingIface)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 
~GnssGeofencing()49 GnssGeofencing::~GnssGeofencing() {
50     sThreadFuncArgsList.clear();
51     sInterfaceExists = false;
52 }
gnssGfTransitionCb(int32_t geofenceId,GpsLocation * location,int32_t transition,GpsUtcTime timestamp)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 
gnssGfStatusCb(int32_t status,GpsLocation * location)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 
gnssGfAddCb(int32_t geofenceId,int32_t status)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 
gnssGfRemoveCb(int32_t geofenceId,int32_t status)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 
gnssGfPauseCb(int32_t geofenceId,int32_t status)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 
gnssGfResumeCb(int32_t geofenceId,int32_t status)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 
createThreadCb(const char * name,void (* start)(void *),void * arg)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.
setCallback(const sp<IGnssGeofenceCallback> & callback)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 
addGeofence(int32_t geofenceId,double latitudeDegrees,double longitudeDegrees,double radiusMeters,IGnssGeofenceCallback::GeofenceTransition lastTransition,int32_t monitorTransitions,uint32_t notificationResponsivenessMs,uint32_t unknownTimerMs)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 
pauseGeofence(int32_t geofenceId)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 
resumeGeofence(int32_t geofenceId,int32_t monitorTransitions)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 
removeGeofence(int32_t geofenceId)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