blob: 54c4aaa1881f1f34d48d16b724316ecc22f13a2e [file] [log] [blame]
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -07001/*
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
22namespace android {
23namespace hardware {
24namespace gnss {
25namespace V1_0 {
26namespace implementation {
27
28std::vector<std::unique_ptr<ThreadFuncArgs>> GnssGeofencing::sThreadFuncArgsList;
29sp<IGnssGeofenceCallback> GnssGeofencing::mGnssGeofencingCbIface = nullptr;
30bool GnssGeofencing::sInterfaceExists = false;
31
32GpsGeofenceCallbacks 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
42GnssGeofencing::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
49GnssGeofencing::~GnssGeofencing() {
50 sThreadFuncArgsList.clear();
Hridya Valsarajue020ce22017-02-15 20:31:18 -080051 sInterfaceExists = false;
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -070052}
53void 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);
Hridya Valsarajue020ce22017-02-15 20:31:18 -080068 auto ret = mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -070069 geofenceId,
70 gnssLocation,
71 static_cast<IGnssGeofenceCallback::GeofenceTransition>(transition),
72 timestamp);
Hridya Valsarajue020ce22017-02-15 20:31:18 -080073 if (!ret.isOk()) {
74 ALOGE("%s: Unable to invoke callback", __func__);
75 }
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -070076}
77
78void 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
Hridya Valsarajue020ce22017-02-15 20:31:18 -080092 auto ret = mGnssGeofencingCbIface->gnssGeofenceStatusCb(
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -070093 static_cast<IGnssGeofenceCallback::GeofenceAvailability>(status), gnssLocation);
Hridya Valsarajue020ce22017-02-15 20:31:18 -080094 if (!ret.isOk()) {
95 ALOGE("%s: Unable to invoke callback", __func__);
96 }
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -070097}
98
99void 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
Hridya Valsarajue020ce22017-02-15 20:31:18 -0800105 auto ret = mGnssGeofencingCbIface->gnssGeofenceAddCb(
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -0700106 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
Hridya Valsarajue020ce22017-02-15 20:31:18 -0800107 if (!ret.isOk()) {
108 ALOGE("%s: Unable to invoke callback", __func__);
109 }
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -0700110}
111
112void 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
Hridya Valsarajue020ce22017-02-15 20:31:18 -0800118 auto ret = mGnssGeofencingCbIface->gnssGeofenceRemoveCb(
119 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
120 if (!ret.isOk()) {
121 ALOGE("%s: Unable to invoke callback", __func__);
122 }
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -0700123}
124
125void 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
Hridya Valsarajue020ce22017-02-15 20:31:18 -0800131 auto ret = mGnssGeofencingCbIface->gnssGeofencePauseCb(
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -0700132 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
Hridya Valsarajue020ce22017-02-15 20:31:18 -0800133 if (!ret.isOk()) {
134 ALOGE("%s: Unable to invoke callback", __func__);
135 }
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -0700136}
137
138void 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
Hridya Valsarajue020ce22017-02-15 20:31:18 -0800144 auto ret = mGnssGeofencingCbIface->gnssGeofenceResumeCb(
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -0700145 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
Hridya Valsarajue020ce22017-02-15 20:31:18 -0800146 if (!ret.isOk()) {
147 ALOGE("%s: Unable to invoke callback", __func__);
148 }
Hridya Valsaraju29dc1e02016-10-21 14:41:12 -0700149}
150
151pthread_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.
156Return<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
168Return<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
194Return<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
203Return<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
212Return<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