blob: 7db86897f9201b2042b0e41be52a94b32319bfd8 [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 Kuznetsov216311f2020-01-02 17:23:42 -080020#include "GnssDebug.h"
Yu-Han Yangc06b5362019-10-25 14:14:35 -070021#include "GnssMeasurement.h"
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -080022#include "GnssMeasurementCorrections.h"
Yu-Han Yangc06b5362019-10-25 14:14:35 -070023#include "Utils.h"
24
25#include <log/log.h>
26
27using ::android::hardware::gnss::common::Utils;
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -080028using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::
29 GnssMeasurementCorrections;
Yu-Han Yangc06b5362019-10-25 14:14:35 -070030
31namespace android {
32namespace hardware {
33namespace gnss {
34namespace V2_1 {
35namespace implementation {
36
37sp<V2_1::IGnssCallback> Gnss::sGnssCallback_2_1 = nullptr;
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -080038sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
Sasha Kuznetsov216311f2020-01-02 17:23:42 -080039sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
40sp<V1_0::IGnssCallback> Gnss::sGnssCallback_1_0 = nullptr;
Yu-Han Yangc06b5362019-10-25 14:14:35 -070041
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -080042Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
Yu-Han Yangc06b5362019-10-25 14:14:35 -070043
44Gnss::~Gnss() {
45 stop();
46}
47
48Return<bool> Gnss::start() {
49 ALOGD("start");
50 if (mIsActive) {
51 ALOGW("Gnss has started. Restarting...");
52 stop();
53 }
54
55 mIsActive = true;
56 mThread = std::thread([this]() {
57 while (mIsActive == true) {
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -080058 auto svStatus = filterBlacklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
Yu-Han Yangc06b5362019-10-25 14:14:35 -070059 this->reportSvStatus(svStatus);
60
Sasha Kuznetsov216311f2020-01-02 17:23:42 -080061 if (sGnssCallback_2_1 != nullptr || sGnssCallback_2_0 != nullptr) {
62 const auto location = Utils::getMockLocationV2_0();
63 this->reportLocation(location);
64 } else {
65 const auto location = Utils::getMockLocationV1_0();
66 this->reportLocation(location);
67 }
Yu-Han Yangc06b5362019-10-25 14:14:35 -070068
69 std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
70 }
71 });
72 return true;
73}
74
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -080075hidl_vec<GnssSvInfo> Gnss::filterBlacklistedSatellitesV2_1(hidl_vec<GnssSvInfo> gnssSvInfoList) {
76 for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
77 if (mGnssConfiguration->isBlacklistedV2_1(gnssSvInfoList[i])) {
78 gnssSvInfoList[i].v2_0.v1_0.svFlag &=
79 ~static_cast<uint8_t>(V1_0::IGnssCallback::GnssSvFlags::USED_IN_FIX);
80 }
81 }
82 return gnssSvInfoList;
83}
84
Yu-Han Yangc06b5362019-10-25 14:14:35 -070085Return<bool> Gnss::stop() {
86 ALOGD("stop");
87 mIsActive = false;
88 if (mThread.joinable()) {
89 mThread.join();
90 }
91 return true;
92}
93
94// Methods from V1_0::IGnss follow.
Sasha Kuznetsov216311f2020-01-02 17:23:42 -080095Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>& callback) {
96 if (callback == nullptr) {
97 ALOGE("%s: Null callback ignored", __func__);
98 return false;
99 }
100
101 sGnssCallback_1_0 = callback;
102
103 uint32_t capabilities = 0x0 | V1_0::IGnssCallback::Capabilities::MEASUREMENTS |
104 V1_0::IGnssCallback::Capabilities::SCHEDULING;
105 auto ret = sGnssCallback_1_0->gnssSetCapabilitesCb(capabilities);
106 if (!ret.isOk()) {
107 ALOGE("%s: Unable to invoke callback", __func__);
108 }
109
110 IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
111
112 ret = sGnssCallback_1_0->gnssSetSystemInfoCb(gnssInfo);
113 if (!ret.isOk()) {
114 ALOGE("%s: Unable to invoke callback", __func__);
115 }
116
117 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700118}
119
120Return<void> Gnss::cleanup() {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800121 sGnssCallback_2_1 = nullptr;
122 sGnssCallback_2_0 = nullptr;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700123 return Void();
124}
125
126Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800127 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700128}
129
130Return<bool> Gnss::injectLocation(double, double, float) {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800131 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700132}
133
134Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
135 // TODO implement
136 return Void();
137}
138
139Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800140 V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
141 uint32_t, uint32_t) {
142 mMinIntervalMs = minIntervalMs;
143 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700144}
145
146Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
147 // TODO implement
148 return ::android::sp<V1_0::IAGnssRil>{};
149}
150
151Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
152 // TODO implement
153 return ::android::sp<V1_0::IGnssGeofencing>{};
154}
155
156Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
157 // TODO implement
158 return ::android::sp<V1_0::IAGnss>{};
159}
160
161Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
162 // TODO implement
163 return ::android::sp<V1_0::IGnssNi>{};
164}
165
166Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800167 ALOGD("Gnss::getExtensionGnssMeasurement");
168 return new GnssMeasurement();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700169}
170
171Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
172 // TODO implement
173 return ::android::sp<V1_0::IGnssNavigationMessage>{};
174}
175
176Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
177 // TODO implement
178 return ::android::sp<V1_0::IGnssXtra>{};
179}
180
181Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
182 // TODO implement
183 return ::android::sp<V1_0::IGnssConfiguration>{};
184}
185
186Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800187 return new V1_1::implementation::GnssDebug();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700188}
189
190Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
191 // TODO implement
192 return ::android::sp<V1_0::IGnssBatching>{};
193}
194
195// Methods from V1_1::IGnss follow.
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800196Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
197 if (callback == nullptr) {
198 ALOGE("%s: Null callback ignored", __func__);
199 return false;
200 }
201
202 sGnssCallback_1_1 = callback;
203
204 uint32_t capabilities = 0x0;
205 auto ret = sGnssCallback_1_1->gnssSetCapabilitesCb(capabilities);
206 if (!ret.isOk()) {
207 ALOGE("%s: Unable to invoke callback", __func__);
208 }
209
210 IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
211
212 ret = sGnssCallback_1_1->gnssSetSystemInfoCb(gnssInfo);
213 if (!ret.isOk()) {
214 ALOGE("%s: Unable to invoke callback", __func__);
215 }
216
217 auto gnssName = "Google Mock GNSS Implementation v2.1";
218 ret = sGnssCallback_1_1->gnssNameCb(gnssName);
219 if (!ret.isOk()) {
220 ALOGE("%s: Unable to invoke callback", __func__);
221 }
222
223 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700224}
225
226Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800227 V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
228 uint32_t, uint32_t, bool) {
229 mMinIntervalMs = minIntervalMs;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700230 return true;
231}
232
233Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
234 // TODO implement
235 return ::android::sp<V1_1::IGnssConfiguration>{};
236}
237
238Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
239 // TODO implement
240 return ::android::sp<V1_1::IGnssMeasurement>{};
241}
242
243Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800244 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700245}
246
247// Methods from V2_0::IGnss follow.
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800248Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
249 ALOGD("Gnss::setCallback_2_0");
250 if (callback == nullptr) {
251 ALOGE("%s: Null callback ignored", __func__);
252 return false;
253 }
254
255 sGnssCallback_2_0 = callback;
256
257 using Capabilities = V2_0::IGnssCallback::Capabilities;
258 const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
259 Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
260 auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
261 if (!ret.isOk()) {
262 ALOGE("%s: Unable to invoke callback", __func__);
263 }
264
265 V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
266
267 ret = sGnssCallback_2_0->gnssSetSystemInfoCb(gnssInfo);
268 if (!ret.isOk()) {
269 ALOGE("%s: Unable to invoke callback", __func__);
270 }
271
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800272 auto gnssName = "Google Mock GNSS Implementation v2.1";
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800273 ret = sGnssCallback_2_0->gnssNameCb(gnssName);
274 if (!ret.isOk()) {
275 ALOGE("%s: Unable to invoke callback", __func__);
276 }
277
278 return true;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700279}
280
281Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800282 ALOGD("Gnss::getExtensionGnssConfiguration_2_0");
283 return mGnssConfiguration;
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700284}
285
286Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
287 // TODO implement
288 return ::android::sp<V2_0::IGnssDebug>{};
289}
290
291Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
292 // TODO implement
293 return ::android::sp<V2_0::IAGnss>{};
294}
295
296Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
297 // TODO implement
298 return ::android::sp<V2_0::IAGnssRil>{};
299}
300
301Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800302 ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
303 return new GnssMeasurement();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700304}
305
306Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
307Gnss::getExtensionMeasurementCorrections() {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800308 ALOGD("Gnss::getExtensionMeasurementCorrections()");
309 return new GnssMeasurementCorrections();
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700310}
311
312Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
313 // TODO implement
314 return ::android::sp<visibility_control::V1_0::IGnssVisibilityControl>{};
315}
316
317Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
318 // TODO implement
319 return ::android::sp<V2_0::IGnssBatching>{};
320}
321
322Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800323 // TODO(b/124012850): Implement function.
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700324 return bool{};
325}
326
327// Methods from V2_1::IGnss follow.
328Return<bool> Gnss::setCallback_2_1(const sp<V2_1::IGnssCallback>& callback) {
329 ALOGD("Gnss::setCallback_2_1");
330 if (callback == nullptr) {
331 ALOGE("%s: Null callback ignored", __func__);
332 return false;
333 }
334
335 sGnssCallback_2_1 = callback;
336
337 using Capabilities = V2_0::IGnssCallback::Capabilities;
338 const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
339 Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
340 auto ret = sGnssCallback_2_1->gnssSetCapabilitiesCb_2_0(capabilities);
341 if (!ret.isOk()) {
342 ALOGE("%s: Unable to invoke callback", __func__);
343 }
344
345 V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2020};
346
347 ret = sGnssCallback_2_1->gnssSetSystemInfoCb(gnssInfo);
348 if (!ret.isOk()) {
349 ALOGE("%s: Unable to invoke callback", __func__);
350 }
351
352 auto gnssName = "Android Mock GNSS Implementation v2.1";
353 ret = sGnssCallback_2_1->gnssNameCb(gnssName);
354 if (!ret.isOk()) {
355 ALOGE("%s: Unable to invoke callback", __func__);
356 }
357
358 return true;
359}
360
361Return<sp<V2_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_1() {
362 ALOGD("Gnss::getExtensionGnssMeasurement_2_1");
363 return new GnssMeasurement();
364}
365
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -0800366Return<sp<V2_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_1() {
Sasha Kuznetsovc1c257b2019-12-13 13:08:16 -0800367 ALOGD("Gnss::getExtensionGnssConfiguration_2_1");
Sasha Kuznetsov845f6d52019-12-04 12:17:50 -0800368 return mGnssConfiguration;
369}
370
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700371void Gnss::reportSvStatus(const hidl_vec<GnssSvInfo>& svInfoList) const {
372 std::unique_lock<std::mutex> lock(mMutex);
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800373 // TODO(skz): update this to call 2_0 callback if non-null
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700374 if (sGnssCallback_2_1 == nullptr) {
375 ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
376 return;
377 }
378 auto ret = sGnssCallback_2_1->gnssSvStatusCb_2_1(svInfoList);
379 if (!ret.isOk()) {
380 ALOGE("%s: Unable to invoke callback", __func__);
381 }
382}
383
Sasha Kuznetsov216311f2020-01-02 17:23:42 -0800384void Gnss::reportLocation(const V1_0::GnssLocation& location) const {
385 std::unique_lock<std::mutex> lock(mMutex);
386 if (sGnssCallback_1_1 != nullptr) {
387 auto ret = sGnssCallback_1_1->gnssLocationCb(location);
388 if (!ret.isOk()) {
389 ALOGE("%s: Unable to invoke callback v1.1", __func__);
390 }
391 return;
392 }
393 if (sGnssCallback_1_0 == nullptr) {
394 ALOGE("%s: No non-null callback", __func__);
395 return;
396 }
397 auto ret = sGnssCallback_1_0->gnssLocationCb(location);
398 if (!ret.isOk()) {
399 ALOGE("%s: Unable to invoke callback v1.0", __func__);
400 }
401}
402
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700403void Gnss::reportLocation(const V2_0::GnssLocation& location) const {
404 std::unique_lock<std::mutex> lock(mMutex);
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800405 if (sGnssCallback_2_1 != nullptr) {
406 auto ret = sGnssCallback_2_1->gnssLocationCb_2_0(location);
407 if (!ret.isOk()) {
408 ALOGE("%s: Unable to invoke callback v2.1", __func__);
409 }
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700410 return;
411 }
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800412 if (sGnssCallback_2_0 == nullptr) {
413 ALOGE("%s: No non-null callback", __func__);
414 return;
415 }
416 auto ret = sGnssCallback_2_0->gnssLocationCb_2_0(location);
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700417 if (!ret.isOk()) {
Sasha Kuznetsov7fd5cc32019-12-09 17:11:08 -0800418 ALOGE("%s: Unable to invoke callback v2.0", __func__);
Yu-Han Yangc06b5362019-10-25 14:14:35 -0700419 }
420}
421
422} // namespace implementation
423} // namespace V2_1
424} // namespace gnss
425} // namespace hardware
426} // namespace android