Merge "Add GnssBatching AIDL HAL (hardware/interfaces)"

This commit is contained in:
Yu-Han Yang
2021-11-04 23:22:42 +00:00
committed by Android (Google) Code Review
28 changed files with 762 additions and 69 deletions

View File

@@ -248,6 +248,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.gnss</name>
<version>2</version>
<interface>
<name>IGnss</name>
<instance>default</instance>

View File

@@ -27,7 +27,7 @@ cc_binary {
"android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
"android.hardware.gnss-V1-ndk",
"android.hardware.gnss-V2-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",

View File

@@ -50,7 +50,7 @@ cc_binary {
"android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
"android.hardware.gnss-V1-ndk",
"android.hardware.gnss-V2-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",

View File

@@ -44,7 +44,7 @@ cc_binary {
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
"android.hardware.gnss-V1-ndk",
"android.hardware.gnss-V2-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.gnss;
@VintfStability
parcelable GnssLocation {
int gnssLocationFlags;
double latitudeDegrees;
double longitudeDegrees;
double altitudeMeters;
double speedMetersPerSec;
double bearingDegrees;
double horizontalAccuracyMeters;
double verticalAccuracyMeters;
double speedAccuracyMetersPerSecond;
double bearingAccuracyDegrees;
long timestampMillis;
android.hardware.gnss.ElapsedRealtime elapsedRealtime;
const int HAS_LAT_LONG = 1;
const int HAS_ALTITUDE = 2;
const int HAS_SPEED = 4;
const int HAS_BEARING = 8;
const int HAS_HORIZONTAL_ACCURACY = 16;
const int HAS_VERTICAL_ACCURACY = 32;
const int HAS_SPEED_ACCURACY = 64;
const int HAS_BEARING_ACCURACY = 128;
}

View File

@@ -36,10 +36,11 @@ package android.hardware.gnss;
interface IGnss {
void setCallback(in android.hardware.gnss.IGnssCallback callback);
void close();
android.hardware.gnss.IGnssPsds getExtensionPsds();
@nullable android.hardware.gnss.IGnssPsds getExtensionPsds();
android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration();
android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
@nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
const int ERROR_INVALID_ARGUMENT = 1;
const int ERROR_ALREADY_INIT = 2;
const int ERROR_GENERIC = 3;

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.gnss;
@VintfStability
interface IGnssBatching {
void init(in android.hardware.gnss.IGnssBatchingCallback callback);
int getBatchSize();
void start(in long periodNanos, in int flags);
void flush();
void stop();
void cleanup();
const int WAKEUP_ON_FIFO_FULL = 1;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.gnss;
@VintfStability
interface IGnssBatchingCallback {
void gnssLocationBatchCb(in android.hardware.gnss.GnssLocation[] locations);
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2021 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.
*/
package android.hardware.gnss;
import android.hardware.gnss.ElapsedRealtime;
/** Represents a location. */
@VintfStability
parcelable GnssLocation {
/** Bit mask to indicate GnssLocation has valid latitude and longitude. */
const int HAS_LAT_LONG = 0x0001;
/** Bit mask to indicate GnssLocation has valid altitude. */
const int HAS_ALTITUDE = 0x0002;
/** Bit mask to indicate GnssLocation has valid speed. */
const int HAS_SPEED = 0x0004;
/** Bit mask to indicate GnssLocation has valid bearing. */
const int HAS_BEARING = 0x0008;
/** Bit mask to indicate GnssLocation has valid horizontal accuracy. */
const int HAS_HORIZONTAL_ACCURACY = 0x0010;
/** Bit mask to indicate GnssLocation has valid vertical accuracy. */
const int HAS_VERTICAL_ACCURACY = 0x0020;
/** Bit mask to indicate GnssLocation has valid speed accuracy. */
const int HAS_SPEED_ACCURACY = 0x0040;
/** Bit mask to indicate GnssLocation has valid bearing accuracy. */
const int HAS_BEARING_ACCURACY = 0x0080;
/** A bit field of flags indicating the validity of the fields in this GnssLocation. */
int gnssLocationFlags;
/** Represents latitude in degrees. */
double latitudeDegrees;
/** Represents longitude in degrees. */
double longitudeDegrees;
/** Represents altitude in meters above the WGS 84 reference ellipsoid. */
double altitudeMeters;
/** Represents speed in meters per second. */
double speedMetersPerSec;
/** Represents heading in degrees. */
double bearingDegrees;
/**
* Represents expected horizontal position accuracy, radial, in meters (68% confidence).
*/
double horizontalAccuracyMeters;
/**
* Represents expected vertical position accuracy in meters (68% confidence).
*/
double verticalAccuracyMeters;
/**
* Represents expected speed accuracy in meter per seconds (68% confidence).
*/
double speedAccuracyMetersPerSecond;
/**
* Represents expected bearing accuracy in degrees (68% confidence).
*/
double bearingAccuracyDegrees;
/** Timestamp for the location fix in milliseconds since January 1, 1970. */
long timestampMillis;
/**
* Timing information of the GNSS location synchronized with SystemClock.elapsedRealtimeNanos()
* clock.
*
* This clock information can be obtained from SystemClock.elapsedRealtimeNanos(), when the GNSS
* is attached straight to the AP/SOC. When it is attached to a separate module the timestamp
* needs to be estimated by syncing the notion of time via PTP or some other mechanism.
*/
ElapsedRealtime elapsedRealtime;
}

View File

@@ -16,6 +16,7 @@
package android.hardware.gnss;
import android.hardware.gnss.IGnssBatching;
import android.hardware.gnss.IGnssCallback;
import android.hardware.gnss.IGnssConfiguration;
import android.hardware.gnss.IGnssMeasurementInterface;
@@ -27,9 +28,8 @@ import android.hardware.gnss.IGnssPsds;
*/
@VintfStability
interface IGnss {
/**
* All GNSS Binder calls may return a ServiceSpecificException with the following error
* All GNSS binder calls may return a ServiceSpecificException with the following error
* codes.
*/
const int ERROR_INVALID_ARGUMENT = 1;
@@ -73,11 +73,9 @@ interface IGnss {
/**
* This method returns the IGnssPsds interface.
*
* This method must return non-null.
*
* @return Handle to the IGnssPsds interface.
*/
IGnssPsds getExtensionPsds();
@nullable IGnssPsds getExtensionPsds();
/**
* This method returns the IGnssConfiguration interface.
@@ -89,7 +87,7 @@ interface IGnss {
IGnssConfiguration getExtensionGnssConfiguration();
/**
* This methods returns the IGnssMeasurementInterface interface.
* This method returns the IGnssMeasurementInterface interface.
*
* This method must return non-null.
*
@@ -105,4 +103,11 @@ interface IGnss {
* @return Handle to the IGnssPowerIndication interface.
*/
IGnssPowerIndication getExtensionGnssPowerIndication();
/**
* This method returns the IGnssBatching interface.
*
* @return Handle to the IGnssBatching interface.
*/
@nullable IGnssBatching getExtensionGnssBatching();
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (C) 2021 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.
*/
package android.hardware.gnss;
import android.hardware.gnss.IGnssBatchingCallback;
/**
* Extended interface for GNSS Batching support.
*
* If this interface is supported, this batching request must be able to run in parallel with, or
* without, non-batched location requested by the IGnss start() & stop() - i.e. both requests must
* be handled independently, and not interfere with each other.
*
* For example, if a 1Hz continuous output is underway on the IGnssCallback, due to an IGnss start()
* operation, and then a IGnssBatching start() is called for a location every 10 seconds, the newly
* added batching request must not disrupt the 1Hz continuous location output on the IGnssCallback.
*
* As with GNSS Location outputs, source of location must be GNSS satellite measurements, optionally
* using interial and baro sensors to improve relative motion filtering. No additional absolute
* positioning information, such as WiFi derived location, may be mixed with the GNSS information.
*/
@VintfStability
interface IGnssBatching {
/**
* Bit mask indicating batching supports wake up and flush when FIFO is full.
*
* If this flag is set, the hardware implementation must wake up the application processor when
* the FIFO is full, and call IGnssBatchingCallback to return the locations.
*
* If the flag is not set, the hardware implementation must drop the oldest data when the FIFO
* is full.
*/
const int WAKEUP_ON_FIFO_FULL = 0x01;
/**
* Open the interface and provides the callback routines to the implementation of this
* interface.
*
* @param callback Callback interface for IGnssBatching.
*/
void init(in IGnssBatchingCallback callback);
/**
* Return the batch size (in number of GnssLocation objects) available in this hardware
* implementation.
*
* If the available size is variable, for example, based on other operations consuming memory,
* this is the minimum size guaranteed to be available for batching operations.
*
* This may, for example, be used by the client, to decide on the batching interval and whether
* the AP should be woken up or not.
*
* @return the number of location objects supported per batch
*/
int getBatchSize();
/**
* Start batching locations. This API is primarily used when the AP is asleep and the device can
* batch locations in the hardware.
*
* The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
* location.
*
* When the buffer is full and WAKEUP_ON_FIFO_FULL is used, IGnssBatchingCallback must be called
* to return the locations.
*
* When the buffer is full and WAKEUP_ON_FIFO_FULL is not set, the oldest location object is
* dropped. In this case the AP must not be woken up. The AP would then generally be responsible
* for using flushBatchedLocation to explicitly ask for the location as needed, to avoid it
* being dropped.
*
* @param periodNanos Time interval between samples in the location batch, in nanoseconds
* @param flags A bitfield of flags (WAKEUP_ON_FIFO_FULL) indicating the batching behavior
*/
void start(in long periodNanos, in int flags);
/**
* Retrieve all batched locations currently stored.
*
* The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
* location.
*
* IGnssBatchingCallback must be called in response, even if there are no locations to flush
* (in which case the Location vector must be empty).
*
* Subsequent calls to flush must not return any of the locations returned in this call.
*/
void flush();
/**
* Stop batching.
*/
void stop();
/**
* Closes the interface. If any batch operations are in progress, they must be stopped. If any
* locations are in the hardware batch, they must be deleted (and not sent via callback.)
*
* init() may be called again, after this, if the interface is to be restored
*/
void cleanup();
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2021 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.
*/
package android.hardware.gnss;
import android.hardware.gnss.GnssLocation;
/** The callback interface to report batched GNSS locations from the HAL. */
@VintfStability
interface IGnssBatchingCallback {
/**
* Called when a batch of locations is output, by various means, including
* a flush request, as well as the buffer becoming full (if appropriate option
* is set.)
*
* All locations returned by this callback must be cleared from the hardware
* buffer, such the sequential calls of this callback do not return any
* redundant locations. (Same lat/lon, at a new time, is acceptable.)
*
* @param locations A list of GNSS Locations
*/
void gnssLocationBatchCb(in GnssLocation[] locations);
}

View File

@@ -52,10 +52,11 @@ cc_binary {
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
"android.hardware.gnss-V1-ndk",
"android.hardware.gnss-V2-ndk",
],
srcs: [
"Gnss.cpp",
"GnssBatching.cpp",
"GnssHidlHal.cpp",
"GnssPowerIndication.cpp",
"GnssPsds.cpp",

View File

@@ -18,6 +18,7 @@
#include "Gnss.h"
#include <log/log.h>
#include "GnssBatching.h"
#include "GnssConfiguration.h"
#include "GnssMeasurementInterface.h"
#include "GnssPsds.h"
@@ -88,4 +89,11 @@ ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement(
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
ALOGD("Gnss::getExtensionGnssBatching");
*iGnssBatching = SharedRefBase::make<GnssBatching>();
return ndk::ScopedAStatus::ok();
}
} // namespace aidl::android::hardware::gnss

View File

@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <aidl/android/hardware/gnss/BnGnssBatching.h>
#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
@@ -37,6 +38,8 @@ class Gnss : public BnGnss {
std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) override;
ndk::ScopedAStatus getExtensionGnssMeasurement(
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
ndk::ScopedAStatus getExtensionGnssBatching(
std::shared_ptr<IGnssBatching>* iGnssBatching) override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) 2021 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 "GnssBatchingAidl"
#include "GnssBatching.h"
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <inttypes.h>
#include <log/log.h>
#include <utils/SystemClock.h>
#include "Utils.h"
namespace aidl::android::hardware::gnss {
using namespace ::android::hardware::gnss;
constexpr int BATCH_SIZE = 10;
std::shared_ptr<IGnssBatchingCallback> GnssBatching::sCallback = nullptr;
GnssBatching::GnssBatching()
: mMinIntervalMs(1000),
mWakeUpOnFifoFull(false),
mBatchedLocations(std::vector<GnssLocation>()) {}
GnssBatching::~GnssBatching() {
cleanup();
}
ndk::ScopedAStatus GnssBatching::init(const std::shared_ptr<IGnssBatchingCallback>& callback) {
ALOGD("init");
std::unique_lock<std::mutex> lock(mMutex);
sCallback = callback;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GnssBatching::getBatchSize(int* size) {
ALOGD("getBatchingSize");
*size = BATCH_SIZE;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GnssBatching::start(int64_t periodNanos, int flags) {
ALOGD("start: periodNanos=%" PRId64 ", flags=%d", periodNanos, flags);
if (mIsActive) {
ALOGW("Gnss has started. Restarting...");
stop();
}
mWakeUpOnFifoFull = (flags & IGnssBatching::WAKEUP_ON_FIFO_FULL) ? true : false;
// mMinIntervalMs is not smaller than 1 sec
periodNanos = (periodNanos < 1e9) ? 1e9 : periodNanos;
mMinIntervalMs = periodNanos / 1e6;
mIsActive = true;
mThread = std::thread([this]() {
while (mIsActive == true) {
const auto location = common::Utils::getMockLocation();
this->batchLocation(location);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
}
});
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GnssBatching::flush() {
ALOGD("flush");
if (mBatchedLocations.empty()) {
return ndk::ScopedAStatus::ok();
}
std::vector<GnssLocation> copy = std::vector<GnssLocation>(mBatchedLocations);
ndk::ScopedAStatus status;
if (sCallback != nullptr) {
sCallback->gnssLocationBatchCb(copy);
status = ndk::ScopedAStatus::ok();
} else {
ALOGE("GnssBatchingCallback is null. flush() failed.");
status = ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_GENERIC);
}
mBatchedLocations.clear();
return status;
}
ndk::ScopedAStatus GnssBatching::stop() {
ALOGD("stop");
// Do not call flush() at stop()
mIsActive = false;
if (mThread.joinable()) {
mThread.join();
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus GnssBatching::cleanup() {
ALOGD("cleanup");
std::unique_lock<std::mutex> lock(mMutex);
if (mIsActive) {
stop();
}
flush();
sCallback = nullptr;
return ndk::ScopedAStatus::ok();
}
void GnssBatching::batchLocation(const GnssLocation& location) {
if (mBatchedLocations.size() > BATCH_SIZE) {
mBatchedLocations.erase(mBatchedLocations.begin());
}
mBatchedLocations.push_back(location);
if (mWakeUpOnFifoFull && mBatchedLocations.size() == BATCH_SIZE) {
flush();
}
}
} // namespace aidl::android::hardware::gnss

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2021 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.
*/
#pragma once
#include <aidl/android/hardware/gnss/BnGnssBatching.h>
#include <atomic>
#include <thread>
namespace aidl::android::hardware::gnss {
struct GnssBatching : public BnGnssBatching {
public:
GnssBatching();
~GnssBatching();
ndk::ScopedAStatus init(const std::shared_ptr<IGnssBatchingCallback>& callback) override;
ndk::ScopedAStatus getBatchSize(int* size) override;
ndk::ScopedAStatus start(int64_t periodNanos, int flags) override;
ndk::ScopedAStatus flush() override;
ndk::ScopedAStatus stop() override;
ndk::ScopedAStatus cleanup() override;
private:
void batchLocation(const GnssLocation&);
// Guarded by mMutex
static std::shared_ptr<IGnssBatchingCallback> sCallback;
std::thread mThread;
std::atomic<bool> mIsActive;
std::atomic<long> mMinIntervalMs;
std::atomic<bool> mWakeUpOnFifoFull;
// Synchronization lock for sCallback
mutable std::mutex mMutex;
std::vector<GnssLocation> mBatchedLocations;
};
} // namespace aidl::android::hardware::gnss

View File

@@ -1,6 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.gnss</name>
<version>2</version>
<interface>
<name>IGnss</name>
<instance>default</instance>

View File

@@ -30,6 +30,7 @@ cc_test {
srcs: [
"gnss_hal_test.cpp",
"gnss_hal_test_cases.cpp",
"GnssBatchingCallback.cpp",
"GnssCallbackAidl.cpp",
"GnssMeasurementCallbackAidl.cpp",
"GnssPowerIndicationCallback.cpp",
@@ -43,7 +44,7 @@ cc_test {
"libbinder",
],
static_libs: [
"android.hardware.gnss-V1-cpp",
"android.hardware.gnss-V2-cpp",
"android.hardware.gnss@common-vts-lib",
],
test_suites: [

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2021 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.
*/
#include "GnssBatchingCallback.h"
#include <inttypes.h>
#include <log/log.h>
android::binder::Status GnssBatchingCallback::gnssLocationBatchCb(
const std::vector<android::hardware::gnss::GnssLocation>& locations) {
ALOGI("Batched locations received with size=%d", (int)locations.size());
for (const auto& location : locations) {
ALOGI("elapsedRealtime: flags = %d, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
location.elapsedRealtime.flags, location.elapsedRealtime.timestampNs,
location.elapsedRealtime.timeUncertaintyNs);
}
batched_locations_cbq_.store(locations);
return android::binder::Status::ok();
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2021 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.
*/
#pragma once
#include <android/hardware/gnss/BnGnssBatchingCallback.h>
#include <vector>
#include "GnssCallbackEventQueue.h"
/** Implementation for IGnssBatchingCallback. */
class GnssBatchingCallback : public android::hardware::gnss::BnGnssBatchingCallback {
public:
GnssBatchingCallback() : batched_locations_cbq_("batched_locations") {}
~GnssBatchingCallback() {}
android::binder::Status gnssLocationBatchCb(
const std::vector<android::hardware::gnss::GnssLocation>& locations) override;
android::hardware::gnss::common::GnssCallbackEventQueue<
std::vector<android::hardware::gnss::GnssLocation>>
batched_locations_cbq_;
std::vector<android::hardware::gnss::GnssLocation> last_batched_locations_;
};

View File

@@ -23,6 +23,7 @@
#include <binder/IServiceManager.h>
#include <android/hardware/gnss/2.1/IGnss.h>
#include "GnssBatchingCallback.h"
#include "GnssCallbackAidl.h"
#include "v2_1/gnss_hal_test_template.h"

View File

@@ -17,10 +17,12 @@
#define LOG_TAG "GnssHalTestCases"
#include <android/hardware/gnss/IGnss.h>
#include <android/hardware/gnss/IGnssBatching.h>
#include <android/hardware/gnss/IGnssMeasurementCallback.h>
#include <android/hardware/gnss/IGnssMeasurementInterface.h>
#include <android/hardware/gnss/IGnssPowerIndication.h>
#include <android/hardware/gnss/IGnssPsds.h>
#include "GnssBatchingCallback.h"
#include "GnssMeasurementCallbackAidl.h"
#include "GnssPowerIndicationCallback.h"
#include "gnss_hal_test.h"
@@ -33,6 +35,8 @@ using android::hardware::gnss::GnssData;
using android::hardware::gnss::GnssMeasurement;
using android::hardware::gnss::GnssPowerStats;
using android::hardware::gnss::IGnss;
using android::hardware::gnss::IGnssBatching;
using android::hardware::gnss::IGnssBatchingCallback;
using android::hardware::gnss::IGnssConfiguration;
using android::hardware::gnss::IGnssMeasurementCallback;
using android::hardware::gnss::IGnssMeasurementInterface;
@@ -749,3 +753,25 @@ TEST_P(GnssHalTest, BlocklistConstellationLocationOn) {
status = gnss_configuration_hal->setBlocklist(sources);
ASSERT_TRUE(status.isOk());
}
/*
* TestGnssBatchingExtension:
* 1. Gets the IGnssBatching extension.
* 2. Initializes the interface with an IGnssBatchingCallback.
* 3. Clean up.
*/
TEST_P(GnssHalTest, TestGnssBatchingExtension) {
sp<IGnssBatching> iGnssBatching;
auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
if (!status.isOk() || iGnssBatching == nullptr) {
// Device doesn't support batching. Skip the test.
return;
}
sp<IGnssBatchingCallback> iGnssBatchingCallback;
status = iGnssBatching->init(iGnssBatchingCallback);
ASSERT_TRUE(status.isOk());
status = iGnssBatching->cleanup();
ASSERT_TRUE(status.isOk());
}

View File

@@ -56,6 +56,6 @@ cc_library_static {
"android.hardware.gnss@2.1",
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss-V1-ndk",
"android.hardware.gnss-V2-ndk",
],
}

View File

@@ -28,6 +28,7 @@ namespace common {
using aidl::android::hardware::gnss::ElapsedRealtime;
using aidl::android::hardware::gnss::GnssClock;
using aidl::android::hardware::gnss::GnssData;
using aidl::android::hardware::gnss::GnssLocation;
using aidl::android::hardware::gnss::GnssMeasurement;
using aidl::android::hardware::gnss::IGnss;
using aidl::android::hardware::gnss::IGnssMeasurementCallback;
@@ -232,6 +233,30 @@ GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
return gnssData;
}
GnssLocation Utils::getMockLocation() {
ElapsedRealtime elapsedRealtime = {
.flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
.timestampNs = ::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 = 1020400};
GnssLocation location = {.gnssLocationFlags = 0xFF,
.latitudeDegrees = gMockLatitudeDegrees,
.longitudeDegrees = gMockLongitudeDegrees,
.altitudeMeters = gMockAltitudeMeters,
.speedMetersPerSec = gMockSpeedMetersPerSec,
.bearingDegrees = gMockBearingDegrees,
.horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
.verticalAccuracyMeters = kMockVerticalAccuracyMeters,
.speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
.bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
.timestampMillis = static_cast<int64_t>(
kMockTimestamp + ::android::elapsedRealtimeNano() / 1e6),
.elapsedRealtime = elapsedRealtime};
return location;
}
V2_0::GnssLocation Utils::getMockLocationV2_0() {
const V2_0::ElapsedRealtime timestamp = {
.flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |

View File

@@ -17,6 +17,7 @@
#ifndef android_hardware_gnss_common_default_Utils_H_
#define android_hardware_gnss_common_default_Utils_H_
#include <aidl/android/hardware/gnss/BnGnss.h>
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/2.0/IGnss.h>
@@ -34,6 +35,7 @@ struct Utils {
const bool enableCorrVecOutputs);
static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
static aidl::android::hardware::gnss::GnssLocation getMockLocation();
static V2_0::GnssLocation getMockLocationV2_0();
static V1_0::GnssLocation getMockLocationV1_0();
static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();

View File

@@ -24,12 +24,10 @@ namespace hardware {
namespace gnss {
namespace common {
using GnssConstellationType_V1_0 = V1_0::GnssConstellationType;
using GnssConstellationType_V2_0 = V2_0::GnssConstellationType;
using namespace measurement_corrections::V1_0;
using V1_0::GnssLocationFlags;
void Utils::checkLocation(const GnssLocation& location, bool check_speed,
void Utils::checkLocation(const V1_0::GnssLocation& location, bool check_speed,
bool check_more_accuracies) {
EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
@@ -96,7 +94,7 @@ void Utils::checkLocation(const GnssLocation& location, bool check_speed,
EXPECT_GT(location.timestamp, 1.48e12);
}
const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
const MeasurementCorrections Utils::getMockMeasurementCorrections() {
ReflectingPlane reflectingPlane = {
.latitudeDegrees = 37.4220039,
.longitudeDegrees = -122.0840991,
@@ -104,12 +102,12 @@ const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
.azimuthDegrees = 203.0,
};
SingleSatCorrection_V1_0 singleSatCorrection1 = {
SingleSatCorrection singleSatCorrection1 = {
.singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC |
GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE,
.constellation = GnssConstellationType_V1_0::GPS,
.constellation = V1_0::GnssConstellationType::GPS,
.svid = 12,
.carrierFrequencyHz = 1.59975e+09,
.probSatIsLos = 0.50001,
@@ -117,11 +115,11 @@ const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
.excessPathLengthUncertaintyMeters = 25.5,
.reflectingPlane = reflectingPlane,
};
SingleSatCorrection_V1_0 singleSatCorrection2 = {
SingleSatCorrection singleSatCorrection2 = {
.singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC,
.constellation = GnssConstellationType_V1_0::GPS,
.constellation = V1_0::GnssConstellationType::GPS,
.svid = 9,
.carrierFrequencyHz = 1.59975e+09,
.probSatIsLos = 0.873,
@@ -129,9 +127,9 @@ const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
.excessPathLengthUncertaintyMeters = 10.0,
};
hidl_vec<SingleSatCorrection_V1_0> singleSatCorrections = {singleSatCorrection1,
singleSatCorrection2};
MeasurementCorrections_1_0 mockCorrections = {
hidl_vec<SingleSatCorrection> singleSatCorrections = {singleSatCorrection1,
singleSatCorrection2};
MeasurementCorrections mockCorrections = {
.latitudeDegrees = 37.4219999,
.longitudeDegrees = -122.0840575,
.altitudeMeters = 30.60062531,
@@ -143,25 +141,26 @@ const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
return mockCorrections;
}
const MeasurementCorrections_1_1 Utils::getMockMeasurementCorrections_1_1() {
MeasurementCorrections_1_0 mockCorrections_1_0 = getMockMeasurementCorrections();
const measurement_corrections::V1_1::MeasurementCorrections
Utils::getMockMeasurementCorrections_1_1() {
MeasurementCorrections mockCorrections_1_0 = getMockMeasurementCorrections();
SingleSatCorrection_V1_1 singleSatCorrection1 = {
measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection1 = {
.v1_0 = mockCorrections_1_0.satCorrections[0],
.constellation = GnssConstellationType_V2_0::IRNSS,
.constellation = V2_0::GnssConstellationType::IRNSS,
};
SingleSatCorrection_V1_1 singleSatCorrection2 = {
measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection2 = {
.v1_0 = mockCorrections_1_0.satCorrections[1],
.constellation = GnssConstellationType_V2_0::IRNSS,
.constellation = V2_0::GnssConstellationType::IRNSS,
};
mockCorrections_1_0.satCorrections[0].constellation = GnssConstellationType_V1_0::UNKNOWN;
mockCorrections_1_0.satCorrections[1].constellation = GnssConstellationType_V1_0::UNKNOWN;
mockCorrections_1_0.satCorrections[0].constellation = V1_0::GnssConstellationType::UNKNOWN;
mockCorrections_1_0.satCorrections[1].constellation = V1_0::GnssConstellationType::UNKNOWN;
hidl_vec<SingleSatCorrection_V1_1> singleSatCorrections = {singleSatCorrection1,
singleSatCorrection2};
hidl_vec<measurement_corrections::V1_1::SingleSatCorrection> singleSatCorrections = {
singleSatCorrection1, singleSatCorrection2};
MeasurementCorrections_1_1 mockCorrections_1_1 = {
measurement_corrections::V1_1::MeasurementCorrections mockCorrections_1_1 = {
.v1_0 = mockCorrections_1_0,
.hasEnvironmentBearing = true,
.environmentBearingDegrees = 45.0,
@@ -177,22 +176,22 @@ const MeasurementCorrections_1_1 Utils::getMockMeasurementCorrections_1_1() {
* GnssConstellationType_1_0 type constellation. For constellations that do not have
* an equivalent value, maps to GnssConstellationType_1_0::UNKNOWN
*/
GnssConstellationType_1_0 Utils::mapConstellationType(GnssConstellationType_2_0 constellation) {
V1_0::GnssConstellationType Utils::mapConstellationType(V2_0::GnssConstellationType constellation) {
switch (constellation) {
case GnssConstellationType_2_0::GPS:
return GnssConstellationType_1_0::GPS;
case GnssConstellationType_2_0::SBAS:
return GnssConstellationType_1_0::SBAS;
case GnssConstellationType_2_0::GLONASS:
return GnssConstellationType_1_0::GLONASS;
case GnssConstellationType_2_0::QZSS:
return GnssConstellationType_1_0::QZSS;
case GnssConstellationType_2_0::BEIDOU:
return GnssConstellationType_1_0::BEIDOU;
case GnssConstellationType_2_0::GALILEO:
return GnssConstellationType_1_0::GALILEO;
case V2_0::GnssConstellationType::GPS:
return V1_0::GnssConstellationType::GPS;
case V2_0::GnssConstellationType::SBAS:
return V1_0::GnssConstellationType::SBAS;
case V2_0::GnssConstellationType::GLONASS:
return V1_0::GnssConstellationType::GLONASS;
case V2_0::GnssConstellationType::QZSS:
return V1_0::GnssConstellationType::QZSS;
case V2_0::GnssConstellationType::BEIDOU:
return V1_0::GnssConstellationType::BEIDOU;
case V2_0::GnssConstellationType::GALILEO:
return V1_0::GnssConstellationType::GALILEO;
default:
return GnssConstellationType_1_0::UNKNOWN;
return V1_0::GnssConstellationType::UNKNOWN;
}
}

View File

@@ -22,33 +22,21 @@
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
using namespace android::hardware::gnss::measurement_corrections::V1_0;
using MeasurementCorrections_1_0 =
android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
using MeasurementCorrections_1_1 =
android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
using SingleSatCorrection_V1_0 =
android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
using SingleSatCorrection_V1_1 =
android::hardware::gnss::measurement_corrections::V1_1::SingleSatCorrection;
namespace android {
namespace hardware {
namespace gnss {
namespace common {
struct Utils {
static void checkLocation(const GnssLocation& location, bool check_speed,
static void checkLocation(const V1_0::GnssLocation& location, bool check_speed,
bool check_more_accuracies);
static const MeasurementCorrections_1_0 getMockMeasurementCorrections();
static const MeasurementCorrections_1_1 getMockMeasurementCorrections_1_1();
static const measurement_corrections::V1_0::MeasurementCorrections
getMockMeasurementCorrections();
static const measurement_corrections::V1_1::MeasurementCorrections
getMockMeasurementCorrections_1_1();
static GnssConstellationType_1_0 mapConstellationType(GnssConstellationType_2_0 constellation);
static V1_0::GnssConstellationType mapConstellationType(
V2_0::GnssConstellationType constellation);
static bool isAutomotiveDevice();
};