Files
hardware_interfaces/gnss/2.0/default/Gnss.cpp
Anil Admal f45338a356 Restore gnss@1.1 HAL capability bits removed in gnss@2.0 (hal)
In the IGnssCallback.hal@2.0 introduced in Android Q, the
capability bits in IGnssCallback.hal@1.1 that represent sub-HAL
interfaces have been removed as they are derivable from the
existing getExtensionXXX() family of methods in the IGnss.hal
interface.

These need to be restored back as the synchronous nature of the
getExtensionXXX() methods called by the framework has an impact on
partner implementations that need to communicate with the modem to
get the capabilities.

Additionally, the capability bit MEASUREMENT_CORRECTIONS needs to be
added for the new optional measurement_corrections@1.0 sub-HAL
introduced in gnss@2.0.

Fixes: 129870126
Test: Verified through cuttlefish default implementation and VTS tests.
Change-Id: Ib4164c9501b8db9f09eb5429a077d477d0a4a7f9
2019-04-04 17:16:10 +00:00

326 lines
9.6 KiB
C++

/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "Gnss"
#include "Gnss.h"
#include <log/log.h>
#include <utils/SystemClock.h>
#include "AGnss.h"
#include "AGnssRil.h"
#include "GnssBatching.h"
#include "GnssConfiguration.h"
#include "GnssMeasurement.h"
#include "GnssMeasurementCorrections.h"
#include "GnssVisibilityControl.h"
#include "Utils.h"
using ::android::hardware::Status;
using ::android::hardware::gnss::common::Utils;
using ::android::hardware::gnss::measurement_corrections::V1_0::implementation::
GnssMeasurementCorrections;
using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
namespace android {
namespace hardware {
namespace gnss {
namespace V2_0 {
namespace implementation {
using GnssSvFlags = IGnssCallback::GnssSvFlags;
sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
namespace {
V2_0::GnssLocation getMockLocationV2_0() {
const ElapsedRealtime timestamp = {
.flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
.timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
// This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
// In an actual implementation provide an estimate of the synchronization uncertainty
// or don't set the field.
.timeUncertaintyNs = 1000000};
V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocation(), .elapsedRealtime = timestamp};
return location;
}
} // namespace
Gnss::Gnss() : mMinIntervalMs(1000) {}
Gnss::~Gnss() {
stop();
}
// Methods from V1_0::IGnss follow.
Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>&) {
// TODO(b/124012850): Implement function.
return bool{};
}
Return<bool> Gnss::start() {
if (mIsActive) {
ALOGW("Gnss has started. Restarting...");
stop();
}
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
const auto location = getMockLocationV2_0();
this->reportLocation(location);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
}
});
return true;
}
Return<bool> Gnss::stop() {
mIsActive = false;
if (mThread.joinable()) {
mThread.join();
}
return true;
}
Return<void> Gnss::cleanup() {
// TODO(b/124012850): Implement function.
return Void();
}
Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
// TODO(b/124012850): Implement function.
return bool{};
}
Return<bool> Gnss::injectLocation(double, double, float) {
// TODO(b/124012850): Implement function.
return bool{};
}
Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
// TODO(b/124012850): Implement function.
return Void();
}
Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
uint32_t) {
return true;
}
Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IAGnssRil>{};
}
Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IGnssGeofencing>{};
}
Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IAGnss>{};
}
Return<sp<V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
// The IGnssNi.hal interface is deprecated in 2.0.
return nullptr;
}
Return<sp<V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
// Not supported
return nullptr;
}
Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IGnssNavigationMessage>{};
}
Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IGnssXtra>{};
}
Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IGnssConfiguration>{};
}
Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IGnssDebug>{};
}
Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
// TODO(b/124012850): Implement function.
return sp<V1_0::IGnssBatching>{};
}
// Methods from V1_1::IGnss follow.
Return<bool> Gnss::setCallback_1_1(const sp<V1_1::IGnssCallback>& callback) {
ALOGD("Gnss::setCallback_1_1");
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
return false;
}
sGnssCallback_1_1 = callback;
uint32_t capabilities = (uint32_t)V1_0::IGnssCallback::Capabilities::MEASUREMENTS;
auto ret = sGnssCallback_1_1->gnssSetCapabilitesCb(capabilities);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
ret = sGnssCallback_1_1->gnssSetSystemInfoCb(gnssInfo);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
auto gnssName = "Google Mock GNSS Implementation v2.0";
ret = sGnssCallback_1_1->gnssNameCb(gnssName);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
return true;
}
Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
uint32_t, bool) {
return true;
}
Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
// TODO(b/124012850): Implement function.
return sp<V1_1::IGnssConfiguration>{};
}
Return<sp<V1_1::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_1_1() {
ALOGD("Gnss::getExtensionGnssMeasurement_1_1");
return new GnssMeasurement();
}
Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
// TODO(b/124012850): Implement function.
return bool{};
}
// Methods from V2_0::IGnss follow.
Return<sp<V2_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_2_0() {
return new GnssConfiguration{};
}
Return<sp<V2_0::IGnssDebug>> Gnss::getExtensionGnssDebug_2_0() {
// TODO(b/124012850): Implement function.
return sp<V2_0::IGnssDebug>{};
}
Return<sp<V2_0::IAGnss>> Gnss::getExtensionAGnss_2_0() {
return new AGnss{};
}
Return<sp<V2_0::IAGnssRil>> Gnss::getExtensionAGnssRil_2_0() {
return new AGnssRil{};
}
Return<sp<V2_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement_2_0() {
ALOGD("Gnss::getExtensionGnssMeasurement_2_0");
return new GnssMeasurement();
}
Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
Gnss::getExtensionMeasurementCorrections() {
ALOGD("Gnss::getExtensionMeasurementCorrections");
return new GnssMeasurementCorrections();
}
Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> Gnss::getExtensionVisibilityControl() {
ALOGD("Gnss::getExtensionVisibilityControl");
return new GnssVisibilityControl();
}
Return<sp<V2_0::IGnssBatching>> Gnss::getExtensionGnssBatching_2_0() {
return new GnssBatching();
}
Return<bool> Gnss::setCallback_2_0(const sp<V2_0::IGnssCallback>& callback) {
ALOGD("Gnss::setCallback_2_0");
if (callback == nullptr) {
ALOGE("%s: Null callback ignored", __func__);
return false;
}
sGnssCallback_2_0 = callback;
using Capabilities = V2_0::IGnssCallback::Capabilities;
const auto capabilities = Capabilities::MEASUREMENTS | Capabilities::MEASUREMENT_CORRECTIONS |
Capabilities::LOW_POWER_MODE | Capabilities::SATELLITE_BLACKLIST;
auto ret = sGnssCallback_2_0->gnssSetCapabilitiesCb_2_0(capabilities);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
V1_1::IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2019};
ret = sGnssCallback_2_0->gnssSetSystemInfoCb(gnssInfo);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
auto gnssName = "Google Mock GNSS Implementation v2.0";
ret = sGnssCallback_2_0->gnssNameCb(gnssName);
if (!ret.isOk()) {
ALOGE("%s: Unable to invoke callback", __func__);
}
return true;
}
Return<void> Gnss::reportLocation(const V2_0::GnssLocation& location) const {
std::unique_lock<std::mutex> lock(mMutex);
if (sGnssCallback_2_0 == nullptr) {
ALOGE("%s: sGnssCallback 2.0 is null.", __func__);
return Void();
}
sGnssCallback_2_0->gnssLocationCb_2_0(location);
return Void();
}
Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
// TODO(b/124012850): Implement function.
return bool{};
}
} // namespace implementation
} // namespace V2_0
} // namespace gnss
} // namespace hardware
} // namespace android