blob: 2b327a99169c515294183fbcdd628c49c8837817 [file] [log] [blame]
Yu-Han Yangc06b5362019-10-25 14:14:35 -07001/*
2 * Copyright (C) 2019 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 "Gnss"
18
19#include "Gnss.h"
Sasha Kuznetsov768de572020-02-11 06:00:10 +000020#include "GnssAntennaInfo.h"
Sasha Kuznetsov216311f2020-01-02 17:23:42 -080021#include "GnssDebug.h"
Yu-Han Yangc06b5362019-10-25 14:14:35 -070022#include "GnssMeasurement.h"
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -080023#include "GnssMeasurementCorrections.h"
Yu-Han Yangc06b5362019-10-25 14:14:35 -070024#include "Utils.h"
25
26#include <log/log.h>
27
28using ::android::hardware::gnss::common::Utils;
Sasha Kuznetsov31eea852020-01-03 13:06:38 -080029using ::android::hardware::gnss::measurement_corrections::V1_1::implementation::
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -080030 GnssMeasurementCorrections;
Yu-Han Yangc06b5362019-10-25 14:14:35 -070031
32namespace android {
33namespace hardware {
34namespace gnss {
35namespace V2_1 {
36namespace implementation {
37
38sp<V2_1::IGnssCallback> Gnss::sGnssCallback_2_1 = nullptr;
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -080039sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
Sasha Kuznetsov216311f2020-01-02 17:23:42 -080040sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
41sp<V1_0::IGnssCallback> Gnss::sGnssCallback_1_0 = nullptr;
Yu-Han Yangc06b5362019-10-25 14:14:35 -070042
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -080043Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
Yu-Han Yangc06b5362019-10-25 14:14:35 -070044
45Gnss::~Gnss() {
46 stop();
47}
48
49Return<bool> Gnss::start() {
50 ALOGD("start");
51 if (mIsActive) {
52 ALOGW("Gnss has started. Restarting...");
53 stop();
54 }
55
56 mIsActive = true;
57 mThread = std::thread([this]() {
58 while (mIsActive == true) {
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -080059 auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
Yu-Han Yangc06b5362019-10-25 14:14:35 -070060 this->reportSvStatus(svStatus);
61
Sasha Kuznetsov216311f2020-01-02 17:23:42 -080062 if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) {
63 const auto location = Utils::getMockLocationV2_0();
64 this->reportLocation(location);
65 } else {
66 const auto location = Utils::getMockLocationV1_0();
67 this->reportLocation(location);
68 }
Yu-Han Yangc06b5362019-10-25 14:14:35 -070069
70 std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
71 }
72 });
73 return true;
74}
75
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -080076hidl_vec<GnssSvInfo> Gnss::filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList) {
77 for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
78 if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
79 gnssSvInfoList[i].v2_0.v1_0.svFlag &=
80 ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
81 }
82 }
83 return gnssSvInfoList;
84}
85
Yu-Han Yangc06b5362019-10-25 14:14:35 -070086Return<bool> Gnss::stop() {
87 ALOGD("stop");
88 mIsActive = false;
89 if (mThread.joinable()) {
90 mThread.join();
91 }
92 return true;
93}
94
95// Methods from V1_0::IGnss follow.
Sasha Kuznetsov216311f2020-01-02 17:23:42 -080096Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
97 if (callback == nullptr) {
98 ALOGE("%s: Null callback ignored", __func__);
99 return false;
100 }
101
102 sGnssCallback_1_0 = callback;
103
104 uint32_t capabilities = 0x0 | V1_0::IGnssCallback::Capabilities::MEASUREMENTS |
105 V1_0::IGnssCallback::Capabilities::SCHEDULING;
106 auto ret = sGnssCallback_1_0->gnssSetCapabilitesCb(capabilities);
107 if (!ret.isOk()) {
108 ALOGE("%s: Unable to invoke callback", __func__);
109 }
110
111 IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
112
113 ret = sGnssCallback_1_0->gnssSetSystemInfoCb(gnssInfo);
114 if (!ret.isOk()) {
115 ALOGE("%s: Unable to invoke callback", __func__);
116 }
117
118 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700119}
120
121Return<void> Gnss::cleanup() {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800122 sGnssCallback_2_1 = nullptr;
123 sGnssCallback_2_0 = nullptr;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700124 return Void();
125}
126
127Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800128 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700129}
130
131Return<bool> Gnss::injectLocation(double, double, float) {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800132 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700133}
134
135Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
136 // TODO implement
137 return Void();
138}
139
140Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800141 V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
142 uint32_t, uint32_t) {
143 mMinIntervalMs = minIntervalMs;
144 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700145}
146
147Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
148 // TODO implement
149 return ::android::sp<V1_0::IAGnssRil>{};
150}
151
152Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
153 // TODO implement
154 return ::android::sp<V1_0::IGnssGeofencing>{};
155}
156
157Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
158 // TODO implement
159 return ::android::sp<V1_0::IAGnss>{};
160}
161
162Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
163 // TODO implement
164 return ::android::sp<V1_0::IGnssNi>{};
165}
166
167Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800168 ALOGD("Gnss::getExtensionGnssMeasurement");
169 return new GnssMeasurement();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700170}
171
172Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
173 // TODO implement
174 return ::android::sp<V1_0::IGnssNavigationMessage>{};
175}
176
177Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
178 // TODO implement
179 return ::android::sp<V1_0::IGnssXtra>{};
180}
181
182Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
183 // TODO implement
184 return ::android::sp<V1_0::IGnssConfiguration>{};
185}
186
187Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800188 return new V1_1::implementation::GnssDebug();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700189}
190
191Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
192 // TODO implement
193 return ::android::sp<V1_0::IGnssBatching>{};
194}
195
196// Methods from V1_1::IGnss follow.
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800197Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
198 if (callback == nullptr) {
199 ALOGE("%s: Null callback ignored", __func__);
200 return false;
201 }
202
203 sGnssCallback_1_1 = callback;
204
205 uint32_t capabilities = 0x0;
206 auto ret = sGnssCallback_1_1->gnssSetCapabilitesCb(capabilities);
207 if (!ret.isOk()) {
208 ALOGE("%s: Unable to invoke callback", __func__);
209 }
210
211 IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
212
213 ret = sGnssCallback_1_1->gnssSetSystemInfoCb(gnssInfo);
214 if (!ret.isOk()) {
215 ALOGE("%s: Unable to invoke callback", __func__);
216 }
217
218 auto gnssName = "Google Mock GNSS Implementation v2.1";
219 ret = sGnssCallback_1_1->gnssNameCb(gnssName);
220 if (!ret.isOk()) {
221 ALOGE("%s: Unable to invoke callback", __func__);
222 }
223
224 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700225}
226
227Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800228 V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
229 uint32_t, uint32_t, bool) {
230 mMinIntervalMs = minIntervalMs;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700231 return true;
232}
233
234Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
235 // TODO implement
236 return ::android::sp<V1_1::IGnssConfiguration>{};
237}
238
239Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
240 // TODO implement
241 return ::android::sp<V1_1::IGnssMeasurement>{};
242}
243
244Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800245 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700246}
247
248// Methods from V2_0::IGnss follow.
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800249Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
250 ALOGD("Gnss::setCallback_2_0");
251 if (callback == nullptr) {
252 ALOGE("%s: Null callback ignored", __func__);
253 return false;
254 }
255
256 sGnssCallback_2_0 = callback;
257
258 using Capabilities = V2_0::IGnssCallback::Capabilities;
259 const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
260 Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
261 auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
262 if (!ret.isOk()) {
263 ALOGE("%s: Unable to invoke callback", __func__);
264 }
265
266 V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
267
268 ret = sGnssCallback_2_0->gnssSetSystemInfoCb(gnssInfo);
269 if (!ret.isOk()) {
270 ALOGE("%s: Unable to invoke callback", __func__);
271 }
272
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800273 auto gnssName = "Google Mock GNSS Implementation v2.1";
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800274 ret = sGnssCallback_2_0->gnssNameCb(gnssName);
275 if (!ret.isOk()) {
276 ALOGE("%s: Unable to invoke callback", __func__);
277 }
278
279 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700280}
281
282Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800283 ALOGD("Gnss::getExtensionGnssConfiguration_2_0");
284 return mGnssConfiguration;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700285}
286
287Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
288 // TODO implement
289 return ::android::sp<V2_0::IGnssDebug>{};
290}
291
292Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
293 // TODO implement
294 return ::android::sp<V2_0::IAGnss>{};
295}
296
297Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
298 // TODO implement
299 return ::android::sp<V2_0::IAGnssRil>{};
300}
301
302Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800303 ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
304 return new GnssMeasurement();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700305}
306
307Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
308Gnss::getExtensionMeasurementCorrections() {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800309 ALOGD("Gnss::getExtensionMeasurementCorrections()");
310 return new GnssMeasurementCorrections();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700311}
312
313Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
314 // TODO implement
315 return ::android::sp<visibility_control::V1_0::IGnssVisibilityControl>{};
316}
317
318Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
319 // TODO implement
320 return ::android::sp<V2_0::IGnssBatching>{};
321}
322
323Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800324 // TODO(b/124012850): Implement function.
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700325 return bool{};
326}
327
328// Methods from V2_1::IGnss follow.
329Return<bool> Gnss::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) {
330 ALOGD("Gnss::setCallback_2_1");
331 if (callback == nullptr) {
332 ALOGE("%s: Null callback ignored", __func__);
333 return false;
334 }
335
336 sGnssCallback_2_1 = callback;
337
Sasha Kuznetsov768de572020-02-11 06:00:10 +0000338 using Capabilities = V2_1::IGnssCallback::Capabilities;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700339 const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
Sasha Kuznetsov768de572020-02-11 06:00:10 +0000340 Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST |
341 Capabilities::ANTENNA_INFO;
Yu-Han Yang99b6d962020-02-13 14:19:09 -0800342 auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_1(capabilities);
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700343 if (!ret.isOk()) {
344 ALOGE("%s: Unable to invoke callback", __func__);
345 }
346
347 V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2020};
348
349 ret = sGnssCallback_2_1->gnssSetSystemInfoCb(gnssInfo);
350 if (!ret.isOk()) {
351 ALOGE("%s: Unable to invoke callback", __func__);
352 }
353
354 auto gnssName = "Android Mock GNSS Implementation v2.1";
355 ret = sGnssCallback_2_1->gnssNameCb(gnssName);
356 if (!ret.isOk()) {
357 ALOGE("%s: Unable to invoke callback", __func__);
358 }
359
360 return true;
361}
362
363Return<sp<V2_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_1() {
364 ALOGD("Gnss::getExtensionGnssMeasurement_2_1");
365 return new GnssMeasurement();
366}
367
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -0800368Return<sp<V2_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_1() {
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800369 ALOGD("Gnss::getExtensionGnssConfiguration_2_1");
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -0800370 return mGnssConfiguration;
371}
372
Sasha Kuznetsov31eea852020-01-03 13:06:38 -0800373Return<sp<measurement_corrections::V1_1::IMeasurementCorrections>>
374Gnss::getExtensionMeasurementCorrections_1_1() {
375 ALOGD("Gnss::getExtensionMeasurementCorrections_1_1()");
376 return new GnssMeasurementCorrections();
377}
378
Sasha Kuznetsov768de572020-02-11 06:00:10 +0000379Return<sp<V2_1::IGnssAntennaInfo>> Gnss::getExtensionGnssAntennaInfo() {
380 ALOGD("Gnss::getExtensionGnssAntennaInfo");
381 return new GnssAntennaInfo();
382}
383
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700384void Gnss::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const {
385 std::unique_lock<std::mutex> lock(mMutex);
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800386 // TODO(skz): update this to call 2_0 callback if non-null
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700387 if (sGnssCallback_2_1 == nullptr) {
388 ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
389 return;
390 }
391 auto ret = sGnssCallback_2_1->gnssSvStatusCb_2_1(svInfoList);
392 if (!ret.isOk()) {
393 ALOGE("%s: Unable to invoke callback", __func__);
394 }
395}
396
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800397void Gnss::reportLocation(const V1_0::GnssLocation& location) const {
398 std::unique_lock<std::mutex> lock(mMutex);
399 if (sGnssCallback_1_1 != nullptr) {
400 auto ret = sGnssCallback_1_1->gnssLocationCb(location);
401 if (!ret.isOk()) {
402 ALOGE("%s: Unable to invoke callback v1.1", __func__);
403 }
404 return;
405 }
406 if (sGnssCallback_1_0 == nullptr) {
407 ALOGE("%s: No non-null callback", __func__);
408 return;
409 }
410 auto ret = sGnssCallback_1_0->gnssLocationCb(location);
411 if (!ret.isOk()) {
412 ALOGE("%s: Unable to invoke callback v1.0", __func__);
413 }
414}
415
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700416void Gnss::reportLocation(const V2_0::GnssLocation& location) const {
417 std::unique_lock<std::mutex> lock(mMutex);
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800418 if (sGnssCallback_2_1 != nullptr) {
419 auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location);
420 if (!ret.isOk()) {
421 ALOGE("%s: Unable to invoke callback v2.1", __func__);
422 }
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700423 return;
424 }
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800425 if (sGnssCallback_2_0 == nullptr) {
426 ALOGE("%s: No non-null callback", __func__);
427 return;
428 }
429 auto ret = sGnssCallback_2_0->gnssLocationCb_2_0(location);
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700430 if (!ret.isOk()) {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800431 ALOGE("%s: Unable to invoke callback v2.0", __func__);
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700432 }
433}
434
435} // namespace implementation
436} // namespace V2_1
437} // namespace gnss
438} // namespace hardware
439} // namespace android