mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-02 02:42:35 +00:00
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
326 lines
9.6 KiB
C++
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
|