blob: f42de42c8edc529047db456400dd06a2206b050b [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();
51}
52void GnssGeofencing::gnssGfTransitionCb(int32_t geofenceId,
53 GpsLocation* location,
54 int32_t transition,
55 GpsUtcTime timestamp) {
56 if (mGnssGeofencingCbIface == nullptr) {
57 ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
58 return;
59 }
60
61 if (location == nullptr) {
62 ALOGE("%s : Invalid location from GNSS HAL", __func__);
63 return;
64 }
65
66 GnssLocation gnssLocation = convertToGnssLocation(location);
67 mGnssGeofencingCbIface->gnssGeofenceTransitionCb(
68 geofenceId,
69 gnssLocation,
70 static_cast<IGnssGeofenceCallback::GeofenceTransition>(transition),
71 timestamp);
72}
73
74void GnssGeofencing::gnssGfStatusCb(int32_t status, GpsLocation* location) {
75 if (mGnssGeofencingCbIface == nullptr) {
76 ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
77 return;
78 }
79
80 GnssLocation gnssLocation;
81
82 if (location != nullptr) {
83 gnssLocation = convertToGnssLocation(location);
84 } else {
85 gnssLocation = {};
86 }
87
88 mGnssGeofencingCbIface->gnssGeofenceStatusCb(
89 static_cast<IGnssGeofenceCallback::GeofenceAvailability>(status), gnssLocation);
90}
91
92void GnssGeofencing::gnssGfAddCb(int32_t geofenceId, int32_t status) {
93 if (mGnssGeofencingCbIface == nullptr) {
94 ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
95 return;
96 }
97
98 mGnssGeofencingCbIface->gnssGeofenceAddCb(
99 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
100}
101
102void GnssGeofencing::gnssGfRemoveCb(int32_t geofenceId, int32_t status) {
103 if (mGnssGeofencingCbIface == nullptr) {
104 ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
105 return;
106 }
107
108 mGnssGeofencingCbIface->gnssGeofenceRemoveCb(
109 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
110}
111
112void GnssGeofencing::gnssGfPauseCb(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 mGnssGeofencingCbIface->gnssGeofencePauseCb(
119 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
120}
121
122void GnssGeofencing::gnssGfResumeCb(int32_t geofenceId, int32_t status) {
123 if (mGnssGeofencingCbIface == nullptr) {
124 ALOGE("%s: GNSS Geofence Callback Interface configured incorrectly", __func__);
125 return;
126 }
127
128 mGnssGeofencingCbIface->gnssGeofenceResumeCb(
129 geofenceId, static_cast<IGnssGeofenceCallback::GeofenceStatus>(status));
130}
131
132pthread_t GnssGeofencing::createThreadCb(const char* name, void (*start)(void*), void* arg) {
133 return createPthread(name, start, arg, &sThreadFuncArgsList);
134}
135
136// Methods from ::android::hardware::gnss::V1_0::IGnssGeofencing follow.
137Return<void> GnssGeofencing::setCallback(const sp<IGnssGeofenceCallback>& callback) {
138 mGnssGeofencingCbIface = callback;
139
140 if (mGnssGeofencingIface == nullptr) {
141 ALOGE("%s: GnssGeofencing interface is not available", __func__);
142 } else {
143 mGnssGeofencingIface->init(&sGnssGfCb);
144 }
145
146 return Void();
147}
148
149Return<void> GnssGeofencing::addGeofence(
150 int32_t geofenceId,
151 double latitudeDegrees,
152 double longitudeDegrees,
153 double radiusMeters,
154 IGnssGeofenceCallback::GeofenceTransition lastTransition,
155 int32_t monitorTransitions,
156 uint32_t notificationResponsivenessMs,
157 uint32_t unknownTimerMs) {
158 if (mGnssGeofencingIface == nullptr) {
159 ALOGE("%s: GnssGeofencing interface is not available", __func__);
160 return Void();
161 } else {
162 mGnssGeofencingIface->add_geofence_area(
163 geofenceId,
164 latitudeDegrees,
165 longitudeDegrees,
166 radiusMeters,
167 static_cast<int32_t>(lastTransition),
168 monitorTransitions,
169 notificationResponsivenessMs,
170 unknownTimerMs);
171 }
172 return Void();
173}
174
175Return<void> GnssGeofencing::pauseGeofence(int32_t geofenceId) {
176 if (mGnssGeofencingIface == nullptr) {
177 ALOGE("%s: GnssGeofencing interface is not available", __func__);
178 } else {
179 mGnssGeofencingIface->pause_geofence(geofenceId);
180 }
181 return Void();
182}
183
184Return<void> GnssGeofencing::resumeGeofence(int32_t geofenceId, int32_t monitorTransitions) {
185 if (mGnssGeofencingIface == nullptr) {
186 ALOGE("%s: GnssGeofencing interface is not available", __func__);
187 } else {
188 mGnssGeofencingIface->resume_geofence(geofenceId, monitorTransitions);
189 }
190 return Void();
191}
192
193Return<void> GnssGeofencing::removeGeofence(int32_t geofenceId) {
194 if (mGnssGeofencingIface == nullptr) {
195 ALOGE("%s: GnssGeofencing interface is not available", __func__);
196 } else {
197 mGnssGeofencingIface->remove_geofence_area(geofenceId);
198 }
199 return Void();
200}
201
202} // namespace implementation
203} // namespace V1_0
204} // namespace gnss
205} // namespace hardware
206} // namespace android