blob: 95c5e600c0c909239a15bae3a1bdb6d79a609b3a [file] [log] [blame]
Wyatt Riley8791e7b2017-01-17 12:12:25 -08001/*
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_GnssBatchingInterface"
18
Wyatt Rileyad03ab22016-12-14 14:54:29 -080019#include "GnssBatching.h"
Wyatt Riley8791e7b2017-01-17 12:12:25 -080020#include <Gnss.h> // for wakelock consolidation
21#include <GnssUtils.h>
22
23#include <cutils/log.h> // for ALOGE
24#include <vector>
Wyatt Rileyad03ab22016-12-14 14:54:29 -080025
26namespace android {
27namespace hardware {
28namespace gnss {
29namespace V1_0 {
30namespace implementation {
31
Wyatt Riley8791e7b2017-01-17 12:12:25 -080032sp<IGnssBatchingCallback> GnssBatching::sGnssBatchingCbIface = nullptr;
33bool GnssBatching::sFlpSupportsBatching = false;
Wyatt Rileyad03ab22016-12-14 14:54:29 -080034
Wyatt Riley8791e7b2017-01-17 12:12:25 -080035FlpCallbacks GnssBatching::sFlpCb = {
36 .size = sizeof(FlpCallbacks),
37 .location_cb = locationCb,
38 .acquire_wakelock_cb = acquireWakelockCb,
39 .release_wakelock_cb = releaseWakelockCb,
40 .set_thread_event_cb = setThreadEventCb,
41 .flp_capabilities_cb = flpCapabilitiesCb,
42 .flp_status_cb = flpStatusCb,
43};
44
45GnssBatching::GnssBatching(const FlpLocationInterface* flpLocationIface) :
46 mFlpLocationIface(flpLocationIface) {
47}
48
49/*
50 * This enum is used locally by various methods below. It is only used by the default
51 * implementation and is not part of the GNSS interface.
52 */
53enum BatchingValues : uint16_t {
54 // Numbers 0-3 were used in earlier implementations - using 4 to be distinct to the HAL
55 FLP_GNSS_BATCHING_CLIENT_ID = 4,
56 // Tech. mask of GNSS, and sensor aiding, for legacy HAL to fit with GnssBatching API
57 FLP_TECH_MASK_GNSS_AND_SENSORS = FLP_TECH_MASK_GNSS | FLP_TECH_MASK_SENSORS,
58 // Putting a cap to avoid possible memory issues. Unlikely values this high are supported.
59 MAX_LOCATIONS_PER_BATCH = 1000
60};
61
62void GnssBatching::locationCb(int32_t locationsCount, FlpLocation** locations) {
63 if (sGnssBatchingCbIface == nullptr) {
64 ALOGE("%s: GNSS Batching Callback Interface configured incorrectly", __func__);
65 return;
66 }
67
68 if (locations == nullptr) {
69 ALOGE("%s: Invalid locations from GNSS HAL", __func__);
70 return;
71 }
72
73 if (locationsCount < 0) {
74 ALOGE("%s: Negative location count: %d set to 0", __func__, locationsCount);
75 locationsCount = 0;
76 } else if (locationsCount > MAX_LOCATIONS_PER_BATCH) {
77 ALOGW("%s: Unexpected high location count: %d set to %d", __func__, locationsCount,
78 MAX_LOCATIONS_PER_BATCH);
79 locationsCount = MAX_LOCATIONS_PER_BATCH;
80 }
81
82 /**
83 * Note:
84 * Some existing implementations may drop duplicate locations. These could be expanded here
85 * but as there's ambiguity between no-GPS-fix vs. dropped duplicates in that implementation,
86 * and that's not specified by the fused_location.h, that isn't safe to do here.
87 * Fortunately, this shouldn't be a major issue in cases where GNSS batching is typically
88 * used (e.g. when user is likely in vehicle/bicycle.)
89 */
90 std::vector<android::hardware::gnss::V1_0::GnssLocation> gnssLocations;
91 for (int iLocation = 0; iLocation < locationsCount; iLocation++) {
92 if (locations[iLocation] == nullptr) {
93 ALOGE("%s: Null location at slot: %d of %d, skipping", __func__, iLocation,
94 locationsCount);
95 continue;
96 }
97 if ((locations[iLocation]->sources_used & ~FLP_TECH_MASK_GNSS_AND_SENSORS) != 0)
98 {
99 ALOGE("%s: Unrequested location type %d at slot: %d of %d, skipping", __func__,
100 locations[iLocation]->sources_used, iLocation, locationsCount);
101 continue;
102 }
103 gnssLocations.push_back(convertToGnssLocation(locations[iLocation]));
104 }
105
106 sGnssBatchingCbIface->gnssLocationBatchCb(gnssLocations);
107}
108
109void GnssBatching::acquireWakelockCb() {
110 Gnss::acquireWakelockFused();
111}
112
113void GnssBatching::releaseWakelockCb() {
114 Gnss::releaseWakelockFused();
115}
116
117// this can just return success, because threads are now set up on demand in the jni layer
118int32_t GnssBatching::setThreadEventCb(ThreadEvent event) {
119 return FLP_RESULT_SUCCESS;
120}
121
122void GnssBatching::flpCapabilitiesCb(int32_t capabilities) {
123 ALOGD("%s capabilities %d", __func__, capabilities);
124
125 if (capabilities & CAPABILITY_GNSS) {
126 // once callback is received and capabilities high enough, we know version is
127 // high enough for flush()
128 sFlpSupportsBatching = true;
129 }
130}
131
132void GnssBatching::flpStatusCb(int32_t status) {
133 ALOGD("%s (default implementation) not forwarding status: %d", __func__, status);
134}
Wyatt Rileyad03ab22016-12-14 14:54:29 -0800135
136// Methods from ::android::hardware::gnss::V1_0::IGnssBatching follow.
137Return<bool> GnssBatching::init(const sp<IGnssBatchingCallback>& callback) {
Wyatt Riley8791e7b2017-01-17 12:12:25 -0800138 if (mFlpLocationIface == nullptr) {
139 ALOGE("%s: Flp batching is unavailable", __func__);
140 return false;
141 }
142
143 sGnssBatchingCbIface = callback;
144
145 return (mFlpLocationIface->init(&sFlpCb) == 0);
Wyatt Rileyad03ab22016-12-14 14:54:29 -0800146}
147
148Return<uint16_t> GnssBatching::getBatchSize() {
Wyatt Riley8791e7b2017-01-17 12:12:25 -0800149 if (mFlpLocationIface == nullptr) {
150 ALOGE("%s: Flp batching interface is unavailable", __func__);
151 return 0;
152 }
153
154 return mFlpLocationIface->get_batch_size();
Wyatt Rileyad03ab22016-12-14 14:54:29 -0800155}
156
157Return<bool> GnssBatching::start(const IGnssBatching::Options& options) {
Wyatt Riley8791e7b2017-01-17 12:12:25 -0800158 if (mFlpLocationIface == nullptr) {
159 ALOGE("%s: Flp batching interface is unavailable", __func__);
160 return false;
161 }
162
163 if (!sFlpSupportsBatching) {
164 ALOGE("%s: Flp batching interface not supported, no capabilities callback received",
165 __func__);
166 return false;
167 }
168
169 FlpBatchOptions optionsHw;
170 // Legacy code used 9999 mW for High accuracy, and 21 mW for balanced.
171 // New GNSS API just expects reasonable GNSS chipset behavior - do something efficient
172 // given the interval. This 100 mW limit should be quite sufficient (esp. given legacy code
173 // implementations may not even use this value.)
174 optionsHw.max_power_allocation_mW = 100;
175 optionsHw.sources_to_use = FLP_TECH_MASK_GNSS_AND_SENSORS;
176 optionsHw.flags = 0;
177 if (options.flags & Flag::WAKEUP_ON_FIFO_FULL) {
178 optionsHw.flags |= FLP_BATCH_WAKEUP_ON_FIFO_FULL;
179 }
180 optionsHw.period_ns = options.periodNanos;
181 optionsHw.smallest_displacement_meters = 0; // Zero offset - just use time interval
182
183 return (mFlpLocationIface->start_batching(FLP_GNSS_BATCHING_CLIENT_ID, &optionsHw)
184 == FLP_RESULT_SUCCESS);
Wyatt Rileyad03ab22016-12-14 14:54:29 -0800185}
186
187Return<void> GnssBatching::flush() {
Wyatt Riley8791e7b2017-01-17 12:12:25 -0800188 if (mFlpLocationIface == nullptr) {
189 ALOGE("%s: Flp batching interface is unavailable", __func__);
190 return Void();
191 }
192
193 mFlpLocationIface->flush_batched_locations();
194
Wyatt Rileyad03ab22016-12-14 14:54:29 -0800195 return Void();
196}
197
198Return<bool> GnssBatching::stop() {
Wyatt Riley8791e7b2017-01-17 12:12:25 -0800199 if (mFlpLocationIface == nullptr) {
200 ALOGE("%s: Flp batching interface is unavailable", __func__);
201 return false;
202 }
203
204 return (mFlpLocationIface->stop_batching(FLP_GNSS_BATCHING_CLIENT_ID) == FLP_RESULT_SUCCESS);
Wyatt Rileyad03ab22016-12-14 14:54:29 -0800205}
206
207Return<void> GnssBatching::cleanup() {
Wyatt Riley8791e7b2017-01-17 12:12:25 -0800208 if (mFlpLocationIface == nullptr) {
209 ALOGE("%s: Flp batching interface is unavailable", __func__);
210 return Void();
211 }
212
213 mFlpLocationIface->cleanup();
214
Wyatt Rileyad03ab22016-12-14 14:54:29 -0800215 return Void();
216}
217
218} // namespace implementation
219} // namespace V1_0
220} // namespace gnss
221} // namespace hardware
222} // namespace android