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