Merge "Remove GnssAntennaInfo AIDL capability"
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index 7fcf523..fbe8686 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -30,6 +30,7 @@
using aidl::android::hardware::graphics::common::PlaneLayout;
using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
using MapperErrorV4 = android::hardware::graphics::mapper::V4_0::Error;
@@ -123,6 +124,21 @@
return layout;
}
+bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
+ MetadataType metadataType) {
+ auto buffer = const_cast<native_handle_t*>(buf);
+ mapper->get(buffer, metadataType, [] (const auto& tmpError,
+ const auto& tmpMetadata) {
+ if (tmpError == MapperErrorV4::NONE) {
+ return tmpMetadata.size() > 0;
+ } else {
+ ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError);
+ return false;
+ }});
+
+ return false;
+}
+
std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
auto buffer = const_cast<native_handle_t*>(buf);
std::vector<PlaneLayout> planeLayouts;
@@ -449,6 +465,55 @@
return -1;
}
+bool HandleImporter::isSmpte2086Present(const buffer_handle_t& buf) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2086);
+ } else {
+ ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+ }
+
+ return false;
+}
+
+bool HandleImporter::isSmpte2094_10Present(const buffer_handle_t& buf) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_10);
+ } else {
+ ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+ }
+
+ return false;
+}
+
+bool HandleImporter::isSmpte2094_40Present(const buffer_handle_t& buf) {
+ Mutex::Autolock lock(mLock);
+
+ if (!mInitialized) {
+ initializeLocked();
+ }
+
+ if (mMapperV4 != nullptr) {
+ return isMetadataPesent(mMapperV4, buf, gralloc4::MetadataType_Smpte2094_40);
+ } else {
+ ALOGE("%s: mMapperV4 is null! Query not supported!", __FUNCTION__);
+ }
+
+ return false;
+}
+
+
} // namespace helper
} // namespace V1_0
} // namespace common
diff --git a/camera/common/1.0/default/include/HandleImporter.h b/camera/common/1.0/default/include/HandleImporter.h
index e404439..83fa755 100644
--- a/camera/common/1.0/default/include/HandleImporter.h
+++ b/camera/common/1.0/default/include/HandleImporter.h
@@ -61,6 +61,11 @@
int unlock(buffer_handle_t& buf); // returns release fence
+ // Query Gralloc4 metadata
+ bool isSmpte2086Present(const buffer_handle_t& buf);
+ bool isSmpte2094_10Present(const buffer_handle_t& buf);
+ bool isSmpte2094_40Present(const buffer_handle_t& buf);
+
private:
void initializeLocked();
void cleanup();
diff --git a/camera/device/3.8/Android.bp b/camera/device/3.8/Android.bp
index 2a1f215..c3c2941 100644
--- a/camera/device/3.8/Android.bp
+++ b/camera/device/3.8/Android.bp
@@ -9,7 +9,6 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-
hidl_interface {
name: "android.hardware.camera.device@3.8",
root: "android.hardware",
@@ -17,6 +16,7 @@
"types.hal",
"ICameraDevice.hal",
"ICameraDeviceCallback.hal",
+ "ICameraDeviceSession.hal",
],
interfaces: [
"android.hardware.camera.common@1.0",
@@ -31,6 +31,7 @@
"android.hardware.camera.metadata@3.4",
"android.hardware.camera.metadata@3.5",
"android.hardware.camera.metadata@3.6",
+ "android.hardware.camera.metadata@3.8",
"android.hardware.graphics.common@1.0",
"android.hidl.base@1.0",
],
diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal
index 1101819..8832c68 100644
--- a/camera/device/3.8/ICameraDevice.hal
+++ b/camera/device/3.8/ICameraDevice.hal
@@ -26,8 +26,8 @@
* API at LIMITED or better hardware level.
*
* ICameraDevice.open() must return @3.2::ICameraDeviceSession,
- * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or
- * @3.7::ICameraDeviceSession.
+ * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession,
+ * @3.7::ICameraDeviceSession, or @3.8::ICameraDeviceSession.
*/
interface ICameraDevice extends @3.7::ICameraDevice {
/**
@@ -107,4 +107,15 @@
*
*/
getTorchStrengthLevel() generates (Status status, int32_t torchStrength);
+
+ /**
+ * isStreamCombinationSupported_3_8:
+ *
+ * Identical to @3.7::ICameraDevice.isStreamCombinationSupported, except
+ * that it takes a @3.8::StreamConfiguration parameter, which could contain
+ * additional information about a specific 10-bit dynamic range profile.
+ *
+ */
+ isStreamCombinationSupported_3_8(StreamConfiguration streams)
+ generates (Status status, bool queryStatus);
};
diff --git a/camera/device/3.8/ICameraDeviceSession.hal b/camera/device/3.8/ICameraDeviceSession.hal
new file mode 100644
index 0000000..88e4338
--- /dev/null
+++ b/camera/device/3.8/ICameraDeviceSession.hal
@@ -0,0 +1,95 @@
+/*
+ * 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.camera.device@3.8;
+
+import android.hardware.camera.common@1.0::Status;
+import @3.5::StreamConfiguration;
+import @3.7::ICameraDeviceSession;
+import @3.6::HalStreamConfiguration;
+
+/**
+ * Camera device active session interface.
+ *
+ * Obtained via ICameraDevice::open(), this interface contains the methods to
+ * configure and request captures from an active camera device.
+ */
+interface ICameraDeviceSession extends @3.7::ICameraDeviceSession {
+ /**
+ * configureStreams_3_8:
+ *
+ * Identical to @3.7::ICameraDeviceSession.configureStreams_3_7, except that:
+ *
+ * - The requestedConfiguration allows the camera framework to configure
+ * 10-bit dynamic range profile.
+ *
+ * @return status Status code for the operation, one of:
+ * OK:
+ * On successful stream configuration.
+ * INTERNAL_ERROR:
+ * If there has been a fatal error and the device is no longer
+ * operational. Only close() can be called successfully by the
+ * framework after this error is returned.
+ * ILLEGAL_ARGUMENT:
+ * If the requested stream configuration is invalid. Some examples
+ * of invalid stream configurations include:
+ * - Including more than 1 INPUT stream
+ * - Not including any OUTPUT streams
+ * - Including streams with unsupported formats, or an unsupported
+ * size for that format.
+ * - Including too many output streams of a certain format.
+ * - Unsupported rotation configuration
+ * - Stream sizes/formats don't satisfy the
+ * StreamConfigurationMode requirements
+ * for non-NORMAL mode, or the requested operation_mode is not
+ * supported by the HAL.
+ * - Unsupported usage flag
+ * - Unsupported stream groupIds, or unsupported multi-resolution
+ * input stream.
+ * - Invalid combination between a 10-bit dynamic range profile
+ * and none impl. defined 8-bit format for a particular stream.
+ * The camera service cannot filter out all possible illegal stream
+ * configurations, since some devices may support more simultaneous
+ * streams or larger stream resolutions than the minimum required
+ * for a given camera device hardware level. The HAL must return an
+ * ILLEGAL_ARGUMENT for any unsupported stream set, and then be
+ * ready to accept a future valid stream configuration in a later
+ * configureStreams call.
+ * @return halConfiguration The stream parameters desired by the HAL for
+ * each stream, including maximum buffers, the usage flags, and the
+ * override format and dataspace.
+ */
+ configureStreams_3_8(StreamConfiguration requestedConfiguration)
+ generates (Status status, @3.6::HalStreamConfiguration halConfiguration);
+
+ /**
+ * repeatingRequestEnd:
+ *
+ * Notification about the last frame number in a repeating request along with the
+ * ids of all streams included in the repeating request.
+ *
+ * This can be called at any point after 'processCaptureRequest' in response
+ * to camera clients disabling an active repeating request.
+ *
+ * Performance requirements:
+ * The call must not be blocked for extensive periods and should be extremely lightweight. There
+ * must be no frame rate degradation or frame jitter introduced.
+ *
+ * This method must always succeed, even if the device has encountered a
+ * serious error.
+ */
+ repeatingRequestEnd(uint32_t frameNumber, vec<int32_t> streamIds);
+};
diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal
index 843d050..9d1ac22 100644
--- a/camera/device/3.8/types.hal
+++ b/camera/device/3.8/types.hal
@@ -19,6 +19,11 @@
import @3.2::ErrorMsg;
import @3.2::MsgType;
import @3.2::ShutterMsg;
+import @3.2::CameraMetadata;
+import @3.2::StreamConfigurationMode;
+import @3.7::Stream;
+
+import android.hardware.camera.metadata@3.8::CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
/**
* ShutterMsg:
@@ -67,3 +72,75 @@
ShutterMsg shutter;
} msg;
};
+
+/**
+ * Stream:
+ *
+ * A descriptor for a single camera input or output stream. A stream is defined
+ * by the framework by its buffer resolution and format, and additionally by the
+ * HAL with the gralloc usage flags and the maximum in-flight buffer count.
+ *
+ * This version extends the @3.7 Stream with the dynamic range profile field.
+ */
+struct Stream {
+ /**
+ * The definition of Stream from the prior version.
+ */
+ @3.7::Stream v3_7;
+
+ /**
+ * The dynamic range profile for this stream.
+ *
+ * This field is valid and must only be considered for streams with format
+ * android.hardware.graphics.common.PixelFormat.YCBCR_P010 or
+ * android.hardware.graphics.common.PixelFormat.IMPLEMENTATION_DEFINED on devices supporting the
+ * ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_10_BIT capability.
+ *
+ */
+ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap dynamicRangeProfile;
+};
+
+/**
+ * StreamConfiguration:
+ *
+ * Identical to @3.7::StreamConfiguration, except that the streams
+ * vector contains @3.8::Stream.
+ */
+struct StreamConfiguration {
+ /**
+ * An array of camera stream pointers, defining the input/output
+ * configuration for the camera HAL device.
+ */
+ vec<Stream> streams;
+
+ /**
+ * The definition of operation mode from prior version.
+ *
+ */
+ @3.2::StreamConfigurationMode operationMode;
+
+ /**
+ * The definition of session parameters from prior version.
+ */
+ @3.2::CameraMetadata sessionParams;
+
+ /**
+ * The definition of stream configuration counter from prior version.
+ */
+ uint32_t streamConfigCounter;
+
+ /**
+ * If an input stream is configured, whether the input stream is expected to
+ * receive variable resolution images.
+ *
+ * This flag can only be set to true if the camera device supports
+ * multi-resolution input streams by advertising input stream configurations in
+ * physicalCameraMultiResolutionStreamConfigurations in its physical cameras'
+ * characteristics.
+ *
+ * When this flag is set to true, the input stream's width and height can be
+ * any one of the supported multi-resolution input stream sizes.
+ */
+ bool multiResolutionInputImage;
+};
+
diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal
index 11360da..4c70eb9 100644
--- a/camera/metadata/3.8/types.hal
+++ b/camera/metadata/3.8/types.hal
@@ -53,6 +53,21 @@
ANDROID_FLASH_INFO_END_3_8,
+ /** android.request.availableDynamicRangeProfilesMap [static, enum[], ndk_public]
+ *
+ * <p>A map of all available 10-bit dynamic range profiles along with their
+ * capture request constraints.</p>
+ */
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP = android.hardware.camera.metadata@3.4::CameraMetadataTag:ANDROID_REQUEST_END_3_4,
+
+ /** android.request.recommendedTenBitDynamicRangeProfile [static, int32, java_public]
+ *
+ * <p>Recommended 10-bit dynamic range profile.</p>
+ */
+ ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE,
+
+ ANDROID_REQUEST_END_3_8,
+
};
/*
@@ -66,3 +81,51 @@
@3.2::CameraMetadataEnumAndroidControlVideoStabilizationMode {
ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION,
};
+
+/** android.request.availableCapabilities enumeration values added since v3.6
+ * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES
+ */
+enum CameraMetadataEnumAndroidRequestAvailableCapabilities :
+ @3.6::CameraMetadataEnumAndroidRequestAvailableCapabilities {
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT,
+};
+
+/** android.request.availableDynamicRangeProfilesMap enumeration values
+ * @see ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP
+ */
+enum CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap : uint32_t {
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD
+ = 0x1,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS
+ = 0x8,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF
+ = 0x10,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO
+ = 0x20,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM
+ = 0x40,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO
+ = 0x80,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF
+ = 0x100,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO
+ = 0x200,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM
+ = 0x400,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO
+ = 0x800,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000,
+};
+
+/** android.scaler.availableRecommendedStreamConfigurations enumeration values added since v3.4
+ * @see ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS
+ */
+enum CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations :
+ @3.4::CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations {
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT
+ = 0x8,
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8
+ = 0x9,
+};
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 2c141ee..0e62265 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -51,11 +51,15 @@
"android.hardware.camera.device@3.7",
"android.hardware.camera.device@3.8",
"android.hardware.camera.metadata@3.4",
+ "android.hardware.camera.metadata@3.8",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
"android.hardware.camera.provider@2.7",
"android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@4.0",
"android.hidl.allocator@1.0",
"libgrallocusage",
"libhidlmemory",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index d39850d..dd45b0d 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -30,6 +30,7 @@
#include <CameraMetadata.h>
#include <CameraParameters.h>
+#include <HandleImporter.h>
#include <android/hardware/camera/device/1.0/ICameraDevice.h>
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
@@ -45,7 +46,9 @@
#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
#include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.8/ICameraDeviceSession.h>
#include <android/hardware/camera/metadata/3.4/types.h>
+#include <android/hardware/camera/metadata/3.8/types.h>
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
#include <android/hardware/camera/provider/2.6/ICameraProvider.h>
@@ -97,6 +100,7 @@
using ::android::hardware::camera::common::V1_0::TorchMode;
using ::android::hardware::camera::common::V1_0::TorchModeStatus;
using ::android::hardware::camera::common::V1_0::helper::CameraParameters;
+using ::android::hardware::camera::common::V1_0::helper::HandleImporter;
using ::android::hardware::camera::common::V1_0::helper::Size;
using ::android::hardware::camera::device::V1_0::CameraFacing;
using ::android::hardware::camera::device::V1_0::CameraFrameMetadata;
@@ -129,6 +133,8 @@
CameraMetadataEnumAndroidSensorInfoColorFilterArrangement;
using ::android::hardware::camera::metadata::V3_4::CameraMetadataTag;
using ::android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
+using ::android::hardware::camera::metadata::V3_8::
+ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap;
using ::android::hardware::camera::provider::V2_4::ICameraProvider;
using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
using ::android::hardware::camera::provider::V2_6::CameraIdAndStreamCombination;
@@ -136,7 +142,6 @@
using ::android::hardware::graphics::common::V1_0::Dataspace;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
using ::android::hidl::allocator::V1_0::IAllocator;
-using ::android::hidl::memory::V1_0::IMapper;
using ::android::hidl::memory::V1_0::IMemory;
using ResultMetadataQueue = MessageQueue<uint8_t, kSynchronizedReadWrite>;
using ::android::hidl::manager::V1_0::IServiceManager;
@@ -781,13 +786,15 @@
sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/,
- sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/);
+ sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/,
+ sp<device::V3_8::ICameraDeviceSession> *session3_8 /*out*/);
void castInjectionSession(
const sp<ICameraDeviceSession>& session,
sp<device::V3_7::ICameraInjectionSession>* injectionSession3_7 /*out*/);
void castDevice(const sp<device::V3_2::ICameraDevice>& device, int32_t deviceVersion,
sp<device::V3_5::ICameraDevice>* device3_5 /*out*/,
- sp<device::V3_7::ICameraDevice>* device3_7 /*out*/);
+ sp<device::V3_7::ICameraDevice>* device3_7 /*out*/,
+ sp<device::V3_8::ICameraDevice>* device3_8 /*out*/);
void createStreamConfiguration(
const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
StreamConfigurationMode configMode,
@@ -817,6 +824,16 @@
uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/,
sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter,
bool maxResolution);
+ void configureStreams3_8(const std::string& name, int32_t deviceVersion,
+ sp<ICameraProvider> provider, PixelFormat format,
+ sp<device::V3_8::ICameraDeviceSession>* session3_8 /*out*/,
+ V3_2::Stream* previewStream /*out*/,
+ device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/,
+ bool* supportsPartialResults /*out*/,
+ uint32_t* partialResultCount /*out*/, bool* useHalBufManager /*out*/,
+ sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter,
+ bool maxResolution,
+ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof);
void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
sp<ICameraProvider> provider,
@@ -896,6 +913,9 @@
static bool isDepthOnly(const camera_metadata_t* staticMeta);
static bool isUltraHighResolution(const camera_metadata_t* staticMeta);
+ static void get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta,
+ std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> *profiles);
+ static bool is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta);
static Status getAvailableOutputStreams(const camera_metadata_t* staticMeta,
std::vector<AvailableStream>& outputStreams,
@@ -1077,6 +1097,10 @@
expectedPhysicalResults(extraPhysicalResult) {}
};
+ static void verify10BitMetadata(HandleImporter& importer,
+ const InFlightRequest& request,
+ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile);
+
// Map from frame number to the in-flight request state
typedef ::android::KeyedVector<uint32_t, InFlightRequest*> InFlightMap;
@@ -1105,6 +1129,8 @@
// Camera provider type.
std::string mProviderType;
+
+ HandleImporter mHandleImporter;
};
Return<void> CameraHidlTest::Camera1DeviceCb::notifyCallback(
@@ -3342,10 +3368,13 @@
sp<device::V3_5::ICameraDeviceSession> sessionV3_5;
sp<device::V3_6::ICameraDeviceSession> sessionV3_6;
sp<device::V3_7::ICameraDeviceSession> sessionV3_7;
+ sp<device::V3_8::ICameraDeviceSession> sessionV3_8;
castSession(session, deviceVersion, &sessionV3_3,
&sessionV3_4, &sessionV3_5, &sessionV3_6,
- &sessionV3_7);
- if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7) {
+ &sessionV3_7, &sessionV3_8);
+ if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_8) {
+ ASSERT_TRUE(sessionV3_8.get() != nullptr);
+ } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) {
ASSERT_TRUE(sessionV3_7.get() != nullptr);
} else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
ASSERT_TRUE(sessionV3_6.get() != nullptr);
@@ -3513,14 +3542,17 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
openEmptyDeviceSession(name, mProvider,
&session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/);
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
- castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ &session3_6, &session3_7, &session3_8);
+ castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7,
+ &cameraDevice3_8);
outputStreams.clear();
ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
@@ -3616,9 +3648,11 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
::android::hardware::camera::device::V3_7::StreamConfiguration config3_7;
::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
@@ -3655,8 +3689,9 @@
openEmptyDeviceSession(name, mProvider2_6, &cti.session /*out*/,
&cti.staticMeta /*out*/, &cti.cameraDevice /*out*/);
castSession(cti.session, deviceVersion, &cti.session3_3, &cti.session3_4,
- &cti.session3_5, &cti.session3_6, &cti.session3_7);
- castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7);
+ &cti.session3_5, &cti.session3_6, &cti.session3_7, &cti.session3_8);
+ castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5, &cti.cameraDevice3_7,
+ &cti.cameraDevice3_8);
outputStreams.clear();
ASSERT_EQ(Status::OK, getMandatoryConcurrentStreams(cti.staticMeta, &outputStreams));
@@ -3785,14 +3820,17 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
- castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ &session3_6, &session3_7, &session3_8);
+ castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7,
+ &cameraDevice3_8);
outputStreams.clear();
ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
@@ -3998,14 +4036,17 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
- castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ &session3_6, &session3_7, &session3_8);
+ castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7,
+ &cameraDevice3_8);
Status rc = isZSLModeAvailable(staticMeta);
if (Status::METHOD_NOT_SUPPORTED == rc) {
@@ -4184,9 +4225,10 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
+ &session3_6, &session3_7, &session3_8);
if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
ASSERT_NE(session3_4, nullptr);
} else {
@@ -4325,14 +4367,17 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
- castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ &session3_6, &session3_7, &session3_8);
+ castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7,
+ &cameraDevice3_8);
// Check if camera support depth only
if (isDepthOnly(staticMeta)) {
@@ -4459,14 +4504,17 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
- castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ &session3_6, &session3_7, &session3_8);
+ castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7,
+ &cameraDevice3_8);
Status rc = isConstrainedModeAvailable(staticMeta);
if (Status::METHOD_NOT_SUPPORTED == rc) {
@@ -4706,14 +4754,17 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
- castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ &session3_6, &session3_7, &session3_8);
+ castDevice(cameraDevice, deviceVersion, &cameraDevice3_5, &cameraDevice3_7,
+ &cameraDevice3_8);
// Check if camera support depth only
if (isDepthOnly(staticMeta)) {
@@ -4997,6 +5048,20 @@
ASSERT_EQ(Status::OK, status);
ASSERT_EQ(numRequestProcessed, 1u);
+ if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8) {
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ sp<device::V3_4::ICameraDeviceSession> session3_4;
+ sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7, &session3_8);
+ ASSERT_TRUE(session3_8.get() != nullptr);
+ hidl_vec<int32_t> streamIds = { halStreamConfig.streams[0].id };
+ session3_8->repeatingRequestEnd(request.frameNumber, streamIds);
+ }
+
{
std::unique_lock<std::mutex> l(mLock);
while (!inflightReq.errorCodeValid &&
@@ -5640,6 +5705,188 @@
}
}
+// Generate and verify 10-bit dynamic range request
+TEST_P(CameraHidlTest, process10BitDynamicRangeRequest) {
+ hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+ uint64_t bufferId = 1;
+ uint32_t frameNumber = 1;
+ ::android::hardware::hidl_vec<uint8_t> settings;
+
+ for (const auto& name : cameraDeviceNames) {
+ int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+ if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_8) {
+ continue;
+ }
+ std::string version, deviceId;
+ ASSERT_TRUE(::matchDeviceName(name, mProviderType, &version, &deviceId));
+ camera_metadata_t* staticMeta;
+ Return<void> ret;
+ sp<ICameraDeviceSession> session;
+ openEmptyDeviceSession(name, mProvider, &session, &staticMeta);
+ if (!is10BitDynamicRangeCapable(staticMeta)) {
+ free_camera_metadata(staticMeta);
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ continue;
+ }
+ std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> profileList;
+ get10BitDynamicRangeProfiles(staticMeta, &profileList);
+ ASSERT_FALSE(profileList.empty());
+
+ android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
+ ret = session->constructDefaultRequestSettings(
+ RequestTemplate::STILL_CAPTURE,
+ [&defaultSettings](auto status, const auto& req) mutable {
+ ASSERT_EQ(Status::OK, status);
+
+ const camera_metadata_t* metadata =
+ reinterpret_cast<const camera_metadata_t*>(req.data());
+ size_t expectedSize = req.size();
+ int result = validate_camera_metadata_structure(metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+
+ size_t entryCount = get_camera_metadata_entry_count(metadata);
+ ASSERT_GT(entryCount, 0u);
+ defaultSettings = metadata;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ const camera_metadata_t* settingsBuffer = defaultSettings.getAndLock();
+ settings.setToExternal(
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(settingsBuffer)),
+ get_camera_metadata_size(settingsBuffer));
+ overrideRotateAndCrop(&settings);
+
+ free_camera_metadata(staticMeta);
+ ret = session->close();
+ ASSERT_TRUE(ret.isOk());
+ V3_6::HalStreamConfiguration halStreamConfig;
+ bool supportsPartialResults = false;
+ bool useHalBufManager = false;
+ uint32_t partialResultCount = 0;
+ V3_2::Stream previewStream;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
+ sp<DeviceCb> cb;
+ for (const auto& profile : profileList) {
+ configureStreams3_8(name, deviceVersion, mProvider, PixelFormat::IMPLEMENTATION_DEFINED,
+ &session3_8, &previewStream, &halStreamConfig,
+ &supportsPartialResults, &partialResultCount, &useHalBufManager,
+ &cb, 0, /*maxResolution*/ false, profile);
+ ASSERT_NE(session3_8, nullptr);
+
+ std::shared_ptr<ResultMetadataQueue> resultQueue;
+ auto resultQueueRet = session3_8->getCaptureResultMetadataQueue(
+ [&resultQueue](const auto& descriptor) {
+ resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
+ if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+ ALOGE("%s: HAL returns empty result metadata fmq,"
+ " not use it",
+ __func__);
+ resultQueue = nullptr;
+ // Don't use the queue onwards.
+ }
+ });
+ ASSERT_TRUE(resultQueueRet.isOk());
+
+ std::vector<hidl_handle> graphicBuffers;
+ graphicBuffers.reserve(halStreamConfig.streams.size());
+ ::android::hardware::hidl_vec<StreamBuffer> outputBuffers;
+ outputBuffers.resize(halStreamConfig.streams.size());
+ InFlightRequest inflightReq = {static_cast<ssize_t>(halStreamConfig.streams.size()),
+ false,
+ supportsPartialResults,
+ partialResultCount,
+ std::unordered_set<std::string>(),
+ resultQueue};
+
+ size_t k = 0;
+ for (const auto& halStream : halStreamConfig.streams) {
+ hidl_handle buffer_handle;
+ if (useHalBufManager) {
+ outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id,
+ 0,
+ buffer_handle,
+ BufferStatus::OK,
+ nullptr,
+ nullptr};
+ } else {
+ allocateGraphicBuffer(
+ previewStream.width, previewStream.height,
+ android_convertGralloc1To0Usage(halStream.v3_4.v3_3.v3_2.producerUsage,
+ halStream.v3_4.v3_3.v3_2.consumerUsage),
+ halStream.v3_4.v3_3.v3_2.overrideFormat, &buffer_handle);
+
+ graphicBuffers.push_back(buffer_handle);
+ outputBuffers[k] = {halStream.v3_4.v3_3.v3_2.id,
+ bufferId,
+ buffer_handle,
+ BufferStatus::OK,
+ nullptr,
+ nullptr};
+ bufferId++;
+ }
+ k++;
+ }
+
+ StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
+ V3_4::CaptureRequest request3_4;
+ request3_4.v3_2.frameNumber = frameNumber;
+ request3_4.v3_2.fmqSettingsSize = 0;
+ request3_4.v3_2.settings = settings;
+ request3_4.v3_2.inputBuffer = emptyInputBuffer;
+ request3_4.v3_2.outputBuffers = outputBuffers;
+ V3_7::CaptureRequest request3_7;
+ request3_7.v3_4 = request3_4;
+ request3_7.inputWidth = 0;
+ request3_7.inputHeight = 0;
+
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ mInflightMap.clear();
+ mInflightMap.add(frameNumber, &inflightReq);
+ }
+
+ Status stat = Status::INTERNAL_ERROR;
+ uint32_t numRequestProcessed = 0;
+ hidl_vec<BufferCache> cachesToRemove;
+ Return<void> returnStatus = session3_8->processCaptureRequest_3_7(
+ {request3_7}, cachesToRemove,
+ [&stat, &numRequestProcessed](auto s, uint32_t n) {
+ stat = s;
+ numRequestProcessed = n;
+ });
+ ASSERT_TRUE(returnStatus.isOk());
+ ASSERT_EQ(Status::OK, stat);
+ ASSERT_EQ(numRequestProcessed, 1u);
+
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ while (!inflightReq.errorCodeValid &&
+ ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) {
+ auto timeout = std::chrono::system_clock::now() +
+ std::chrono::seconds(kStreamBufferTimeoutSec);
+ ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+ }
+
+ ASSERT_FALSE(inflightReq.errorCodeValid);
+ ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+ verify10BitMetadata(mHandleImporter, inflightReq, profile);
+ }
+ if (useHalBufManager) {
+ hidl_vec<int32_t> streamIds(halStreamConfig.streams.size());
+ for (size_t i = 0; i < streamIds.size(); i++) {
+ streamIds[i] = halStreamConfig.streams[i].v3_4.v3_3.v3_2.id;
+ }
+ session3_8->signalStreamFlush(streamIds, /*streamConfigCounter*/ 0);
+ cb->waitForBuffersReturned();
+ }
+
+ ret = session3_8->close();
+ ASSERT_TRUE(ret.isOk());
+ }
+ }
+}
+
// Generate and verify a burst containing alternating sensor sensitivity values
TEST_P(CameraHidlTest, processCaptureRequestBurstISO) {
hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
@@ -7448,8 +7695,9 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6,
- session3_7);
+ session3_7, &session3_8);
ASSERT_NE(nullptr, (*session3_7).get());
*useHalBufManager = false;
@@ -7497,7 +7745,8 @@
ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_7);
sp<device::V3_5::ICameraDevice> cameraDevice3_5 = nullptr;
sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr;
- castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8 = nullptr;
+ castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8);
ASSERT_NE(cameraDevice3_7, nullptr);
bool supported = false;
ret = cameraDevice3_7->isStreamCombinationSupported_3_7(
@@ -7530,6 +7779,153 @@
ASSERT_TRUE(ret.isOk());
}
+// Configure streams
+void CameraHidlTest::configureStreams3_8(
+ const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider,
+ PixelFormat format, sp<device::V3_8::ICameraDeviceSession>* session3_8 /*out*/,
+ V3_2::Stream* previewStream /*out*/,
+ device::V3_6::HalStreamConfiguration* halStreamConfig /*out*/,
+ bool* supportsPartialResults /*out*/, uint32_t* partialResultCount /*out*/,
+ bool* useHalBufManager /*out*/, sp<DeviceCb>* outCb /*out*/, uint32_t streamConfigCounter,
+ bool maxResolution,
+ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap prof) {
+ ASSERT_NE(nullptr, session3_8);
+ ASSERT_NE(nullptr, halStreamConfig);
+ ASSERT_NE(nullptr, previewStream);
+ ASSERT_NE(nullptr, supportsPartialResults);
+ ASSERT_NE(nullptr, partialResultCount);
+ ASSERT_NE(nullptr, useHalBufManager);
+ ASSERT_NE(nullptr, outCb);
+ ASSERT_TRUE(deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8);
+
+ std::vector<AvailableStream> outputStreams;
+ ::android::sp<ICameraDevice> device3_x;
+ ALOGI("configureStreams: Testing camera device %s", name.c_str());
+ Return<void> ret;
+ ret = provider->getCameraDeviceInterface_V3_x(name, [&](auto status, const auto& device) {
+ ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(device, nullptr);
+ device3_x = device;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ camera_metadata_t* staticMeta;
+ ret = device3_x->getCameraCharacteristics([&](Status s, CameraMetadata metadata) {
+ ASSERT_EQ(Status::OK, s);
+ staticMeta =
+ clone_camera_metadata(reinterpret_cast<const camera_metadata_t*>(metadata.data()));
+ ASSERT_NE(nullptr, staticMeta);
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ camera_metadata_ro_entry entry;
+ auto status =
+ find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &entry);
+ if ((0 == status) && (entry.count > 0)) {
+ *partialResultCount = entry.data.i32[0];
+ *supportsPartialResults = (*partialResultCount > 1);
+ }
+
+ sp<DeviceCb> cb = new DeviceCb(this, deviceVersion, staticMeta);
+ sp<ICameraDeviceSession> session;
+ ret = device3_x->open(cb, [&session](auto status, const auto& newSession) {
+ ALOGI("device::open returns status:%d", (int)status);
+ ASSERT_EQ(Status::OK, status);
+ ASSERT_NE(newSession, nullptr);
+ session = newSession;
+ });
+ ASSERT_TRUE(ret.isOk());
+ *outCb = cb;
+
+ sp<device::V3_3::ICameraDeviceSession> session3_3;
+ sp<device::V3_4::ICameraDeviceSession> session3_4;
+ sp<device::V3_5::ICameraDeviceSession> session3_5;
+ sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6,
+ &session3_7, session3_8);
+ ASSERT_NE(nullptr, (*session3_8).get());
+
+ *useHalBufManager = false;
+ status = find_camera_metadata_ro_entry(
+ staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
+ if ((0 == status) && (entry.count == 1)) {
+ *useHalBufManager = (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ }
+
+ outputStreams.clear();
+ Size maxSize;
+ auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution);
+ ASSERT_EQ(Status::OK, rc);
+ free_camera_metadata(staticMeta);
+
+ ::android::hardware::hidl_vec<V3_8::Stream> streams3_8(1);
+ streams3_8[0].v3_7.groupId = -1;
+ streams3_8[0].v3_7.sensorPixelModesUsed = {
+ CameraMetadataEnumAndroidSensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT};
+ streams3_8[0].v3_7.v3_4.bufferSize = 0;
+ streams3_8[0].v3_7.v3_4.v3_2.id = 0;
+ streams3_8[0].v3_7.v3_4.v3_2.streamType = StreamType::OUTPUT;
+ streams3_8[0].v3_7.v3_4.v3_2.width = static_cast<uint32_t>(maxSize.width);
+ streams3_8[0].v3_7.v3_4.v3_2.height = static_cast<uint32_t>(maxSize.height);
+ streams3_8[0].v3_7.v3_4.v3_2.format = static_cast<PixelFormat>(format);
+ streams3_8[0].v3_7.v3_4.v3_2.usage = GRALLOC1_CONSUMER_USAGE_CPU_READ;
+ streams3_8[0].v3_7.v3_4.v3_2.dataSpace = 0;
+ streams3_8[0].v3_7.v3_4.v3_2.rotation = StreamRotation::ROTATION_0;
+ streams3_8[0].dynamicRangeProfile = prof;
+
+ ::android::hardware::camera::device::V3_8::StreamConfiguration config3_8;
+ config3_8.streams = streams3_8;
+ config3_8.operationMode = StreamConfigurationMode::NORMAL_MODE;
+ config3_8.streamConfigCounter = streamConfigCounter;
+ config3_8.multiResolutionInputImage = false;
+ RequestTemplate reqTemplate = RequestTemplate::STILL_CAPTURE;
+ ret = (*session3_8)
+ ->constructDefaultRequestSettings(reqTemplate,
+ [&config3_8](auto status, const auto& req) {
+ ASSERT_EQ(Status::OK, status);
+ config3_8.sessionParams = req;
+ });
+ ASSERT_TRUE(ret.isOk());
+
+ sp<device::V3_5::ICameraDevice> cameraDevice3_5 = nullptr;
+ sp<device::V3_7::ICameraDevice> cameraDevice3_7 = nullptr;
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8 = nullptr;
+ castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8);
+ ASSERT_NE(cameraDevice3_8, nullptr);
+ bool supported = false;
+ ret = cameraDevice3_8->isStreamCombinationSupported_3_8(
+ config3_8, [&supported](Status s, bool combStatus) {
+ ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s));
+ if (Status::OK == s) {
+ supported = combStatus;
+ }
+ });
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(supported, true);
+
+ if (*session3_8 != nullptr) {
+ ret = (*session3_8)
+ ->configureStreams_3_8(
+ config3_8,
+ [&](Status s, device::V3_6::HalStreamConfiguration halConfig) {
+ ASSERT_EQ(Status::OK, s);
+ *halStreamConfig = halConfig;
+ if (*useHalBufManager) {
+ hidl_vec<V3_4::Stream> streams(1);
+ hidl_vec<V3_2::HalStream> halStreams(1);
+ streams[0] = streams3_8[0].v3_7.v3_4;
+ halStreams[0] = halConfig.streams[0].v3_4.v3_3.v3_2;
+ cb->setCurrentStreamConfig(streams, halStreams);
+ }
+ });
+ }
+ *previewStream = streams3_8[0].v3_7.v3_4.v3_2;
+ ASSERT_TRUE(ret.isOk());
+}
+
// Configure multiple preview streams using different physical ids.
void CameraHidlTest::configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
sp<ICameraProvider> provider,
@@ -7604,8 +8000,9 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
castSession(session, deviceVersion, &session3_3, session3_4, session3_5,
- &session3_6, &session3_7);
+ &session3_6, &session3_7, &session3_8);
ASSERT_NE(nullptr, (*session3_4).get());
*useHalBufManager = false;
@@ -7650,7 +8047,8 @@
if (allowUnsupport) {
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
sp<device::V3_7::ICameraDevice> cameraDevice3_7;
- castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7);
+ sp<device::V3_8::ICameraDevice> cameraDevice3_8;
+ castDevice(device3_x, deviceVersion, &cameraDevice3_5, &cameraDevice3_7, &cameraDevice3_8);
bool supported = false;
ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
@@ -7843,6 +8241,95 @@
return false;
}
+void CameraHidlTest::get10BitDynamicRangeProfiles(const camera_metadata_t* staticMeta,
+ std::vector<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap> *profiles) {
+ ASSERT_NE(nullptr, staticMeta);
+ ASSERT_NE(nullptr, profiles);
+ camera_metadata_ro_entry entry;
+ std::unordered_set<int32_t> entries;
+ int rc = find_camera_metadata_ro_entry(staticMeta,
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP, &entry);
+ ASSERT_EQ(rc, 0);
+ ASSERT_TRUE(entry.count > 0);
+ ASSERT_EQ(entry.count % 2, 0);
+
+ for (uint32_t i = 0; i < entry.count; i += 2) {
+ ASSERT_NE(entry.data.i32[i],
+ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
+ ASSERT_EQ(entries.find(entry.data.i32[i]), entries.end());
+ entries.insert(static_cast<int32_t>(entry.data.i32[i]));
+ profiles->emplace_back(
+ static_cast<CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap>
+ (entry.data.i32[i]));
+ }
+
+ if (!entries.empty()) {
+ ASSERT_NE(entries.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10),
+ entries.end());
+ }
+}
+
+bool CameraHidlTest::is10BitDynamicRangeCapable(const camera_metadata_t* staticMeta) {
+ camera_metadata_ro_entry scalarEntry;
+ int rc = find_camera_metadata_ro_entry(staticMeta, ANDROID_REQUEST_AVAILABLE_CAPABILITIES,
+ &scalarEntry);
+ if (rc == 0) {
+ for (uint32_t i = 0; i < scalarEntry.count; i++) {
+ if (scalarEntry.data.u8[i] ==
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void CameraHidlTest::verify10BitMetadata(HandleImporter& importer,
+ const InFlightRequest& request,
+ CameraMetadataEnumAndroidRequestAvailableDynamicRangeProfilesMap profile) {
+ for (const auto& b : request.resultOutputBuffers) {
+ bool smpte2086Present = importer.isSmpte2086Present(b.buffer.buffer.getNativeHandle());
+ bool smpte2094_10Present = importer.isSmpte2094_10Present(
+ b.buffer.buffer.getNativeHandle());
+ bool smpte2094_40Present = importer.isSmpte2094_40Present(
+ b.buffer.buffer.getNativeHandle());
+
+ switch (static_cast<uint32_t>(profile)) {
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10:
+ ASSERT_FALSE(smpte2086Present);
+ ASSERT_FALSE(smpte2094_10Present);
+ ASSERT_FALSE(smpte2094_40Present);
+ break;
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10:
+ ASSERT_TRUE(smpte2086Present);
+ ASSERT_FALSE(smpte2094_10Present);
+ ASSERT_FALSE(smpte2094_40Present);
+ break;
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
+ ASSERT_FALSE(smpte2086Present);
+ ASSERT_FALSE(smpte2094_10Present);
+ ASSERT_TRUE(smpte2094_40Present);
+ break;
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM:
+ case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO:
+ ASSERT_FALSE(smpte2086Present);
+ ASSERT_TRUE(smpte2094_10Present);
+ ASSERT_FALSE(smpte2094_40Present);
+ break;
+ default:
+ ALOGE("%s: Unexpected 10-bit dynamic range profile: %d",
+ __FUNCTION__, profile);
+ ADD_FAILURE();
+ }
+ }
+}
+
bool CameraHidlTest::isDepthOnly(const camera_metadata_t* staticMeta) {
camera_metadata_ro_entry scalarEntry;
camera_metadata_ro_entry depthEntry;
@@ -8006,8 +8493,9 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
+ &session3_6, &session3_7, &session3_8);
*useHalBufManager = false;
status = find_camera_metadata_ro_entry(staticMeta,
@@ -8138,12 +8626,19 @@
void CameraHidlTest::castDevice(const sp<device::V3_2::ICameraDevice>& device,
int32_t deviceVersion,
sp<device::V3_5::ICameraDevice>* device3_5 /*out*/,
- sp<device::V3_7::ICameraDevice>* device3_7 /*out*/) {
+ sp<device::V3_7::ICameraDevice>* device3_7 /*out*/,
+ sp<device::V3_8::ICameraDevice>* device3_8 /*out*/) {
ASSERT_NE(nullptr, device3_5);
ASSERT_NE(nullptr, device3_7);
+ ASSERT_NE(nullptr, device3_8);
switch (deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_3_8:
+ case CAMERA_DEVICE_API_VERSION_3_8: {
+ auto castResult = device::V3_8::ICameraDevice::castFrom(device);
+ ASSERT_TRUE(castResult.isOk());
+ *device3_8 = castResult;
+ }
+ [[fallthrough]];
case CAMERA_DEVICE_API_VERSION_3_7: {
auto castResult = device::V3_7::ICameraDevice::castFrom(device);
ASSERT_TRUE(castResult.isOk());
@@ -8192,15 +8687,22 @@
sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/,
- sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/) {
+ sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/,
+ sp<device::V3_8::ICameraDeviceSession> *session3_8 /*out*/) {
ASSERT_NE(nullptr, session3_3);
ASSERT_NE(nullptr, session3_4);
ASSERT_NE(nullptr, session3_5);
ASSERT_NE(nullptr, session3_6);
ASSERT_NE(nullptr, session3_7);
+ ASSERT_NE(nullptr, session3_8);
switch (deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_3_8:
+ case CAMERA_DEVICE_API_VERSION_3_8: {
+ auto castResult = device::V3_8::ICameraDeviceSession::castFrom(session);
+ ASSERT_TRUE(castResult.isOk());
+ *session3_8 = castResult;
+ }
+ [[fallthrough]];
case CAMERA_DEVICE_API_VERSION_3_7: {
auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session);
ASSERT_TRUE(castResult.isOk());
@@ -9077,8 +9579,9 @@
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
sp<device::V3_7::ICameraDeviceSession> session3_7;
+ sp<device::V3_8::ICameraDeviceSession> session3_8;
castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
- &session3_6, &session3_7);
+ &session3_6, &session3_7, &session3_8);
ASSERT_NE(nullptr, session3_5.get());
hidl_vec<int32_t> streamIds(1);
@@ -9320,7 +9823,7 @@
size_t CONFIG_ENTRY_TYPE_OFFSET = 3;
size_t CONFIG_ENTRY_BITFIELD_OFFSET = 4;
uint32_t maxPublicUsecase =
- ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END;
+ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8;
uint32_t vendorUsecaseStart =
ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START;
uint32_t usecaseMask = (1 << vendorUsecaseStart) - 1;
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index a52fde4..3d2ef2c 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -265,6 +265,14 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.gnss.measurement_corrections</name>
+ <version>1</version>
+ <interface>
+ <name>IMeasurementCorrectionsInterface</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="false">
<name>android.hardware.graphics.allocator</name>
<!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp
index c59d5e7..f8fad94 100644
--- a/gnss/1.1/vts/functional/Android.bp
+++ b/gnss/1.1/vts/functional/Android.bp
@@ -36,6 +36,7 @@
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
"android.hardware.gnss@common-vts-lib",
+ "android.hardware.gnss-V2-cpp",
],
shared_libs: [
"android.hardware.gnss.measurement_corrections@1.0",
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 3bbd572..2042dd9 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -39,6 +39,10 @@
"android.hardware.gnss@2.0",
"android.hardware.gnss@2.1",
"android.hardware.gnss@common-vts-lib",
+ "android.hardware.gnss-V2-cpp",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
index aaddd96..d7b6eeb 100644
--- a/gnss/2.1/vts/functional/Android.bp
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -40,6 +40,7 @@
"android.hardware.gnss@2.0",
"android.hardware.gnss@2.1",
"android.hardware.gnss@common-vts-lib",
+ "android.hardware.gnss-V2-cpp",
],
shared_libs: [
"libvintf",
diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp
index d90cf0b..4d9c5cc 100644
--- a/gnss/aidl/Android.bp
+++ b/gnss/aidl/Android.bp
@@ -28,6 +28,7 @@
vendor_available: true,
srcs: [
"android/hardware/gnss/*.aidl",
+ "android/hardware/gnss/measurement_corrections/*.aidl",
"android/hardware/gnss/visibility_control/*.aidl",
],
stability: "vintf",
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 281c531..fb13e02 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -54,6 +54,7 @@
void deleteAidingData(in android.hardware.gnss.IGnss.GnssAidingData aidingDataFlags);
void setPositionMode(in android.hardware.gnss.IGnss.GnssPositionMode mode, in android.hardware.gnss.IGnss.GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode);
android.hardware.gnss.IGnssAntennaInfo getExtensionGnssAntennaInfo();
+ @nullable android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface getExtensionMeasurementCorrections();
const int ERROR_INVALID_ARGUMENT = 1;
const int ERROR_ALREADY_INIT = 2;
const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl
new file mode 100644
index 0000000..c4cf13f
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.measurement_corrections;
+@VintfStability
+interface IMeasurementCorrectionsCallback {
+ void setCapabilitiesCb(in int capabilities);
+ const int CAPABILITY_LOS_SATS = 1;
+ const int CAPABILITY_EXCESS_PATH_LENGTH = 2;
+ const int CAPABILITY_REFLECTING_PLANE = 4;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl
new file mode 100644
index 0000000..5dc5596
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.measurement_corrections;
+@VintfStability
+interface IMeasurementCorrectionsInterface {
+ void setCorrections(in android.hardware.gnss.measurement_corrections.MeasurementCorrections corrections);
+ void setCallback(in android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsCallback callback);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl
new file mode 100644
index 0000000..f32c8c2
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.measurement_corrections;
+@VintfStability
+parcelable MeasurementCorrections {
+ double latitudeDegrees;
+ double longitudeDegrees;
+ double altitudeMeters;
+ double horizontalPositionUncertaintyMeters;
+ double verticalPositionUncertaintyMeters;
+ long toaGpsNanosecondsOfWeek;
+ android.hardware.gnss.measurement_corrections.SingleSatCorrection[] satCorrections;
+ boolean hasEnvironmentBearing;
+ float environmentBearingDegrees;
+ float environmentBearingUncertaintyDegrees;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
new file mode 100644
index 0000000..90c3818
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.measurement_corrections;
+@VintfStability
+parcelable ReflectingPlane {
+ double latitudeDegrees;
+ double longitudeDegrees;
+ double altitudeMeters;
+ double azimuthDegrees;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
new file mode 100644
index 0000000..d18c1a7
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.measurement_corrections;
+@VintfStability
+parcelable SingleSatCorrection {
+ int singleSatCorrectionFlags;
+ android.hardware.gnss.GnssConstellationType constellation;
+ int svid;
+ long carrierFrequencyHz;
+ float probSatIsLos;
+ float excessPathLengthMeters;
+ float excessPathLengthUncertaintyMeters;
+ android.hardware.gnss.measurement_corrections.ReflectingPlane reflectingPlane;
+ const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 1;
+ const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 2;
+ const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 4;
+ const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 8;
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index e1d4670..1e1c0fa 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -28,6 +28,7 @@
import android.hardware.gnss.IGnssNavigationMessageInterface;
import android.hardware.gnss.IGnssPowerIndication;
import android.hardware.gnss.IGnssPsds;
+import android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface;
import android.hardware.gnss.visibility_control.IGnssVisibilityControl;
/**
@@ -285,4 +286,11 @@
* @return Handle to the IGnssAntennaInfo.
*/
IGnssAntennaInfo getExtensionGnssAntennaInfo();
+
+ /**
+ * This method returns the IMeasurementCorrectionsInterface.
+ *
+ * @return Handle to the IMeasurementCorrectionsInterface.
+ */
+ @nullable IMeasurementCorrectionsInterface getExtensionMeasurementCorrections();
}
diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl
new file mode 100644
index 0000000..d695e70
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsCallback.aidl
@@ -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.
+ */
+
+package android.hardware.gnss.measurement_corrections;
+
+/**
+ * GNSS measurement corrections callback interface.
+ */
+@VintfStability
+interface IMeasurementCorrectionsCallback {
+ /**
+ * Flags to indicate supported measurement corrections capabilities
+ *
+ * Either the LOS_SATS or the EXCESS_PATH_LENGTH capability must be supported.
+ */
+ /**
+ * Capability bit flag indicating that GNSS supports line-of-sight satellite identification
+ * measurement corrections
+ */
+ const int CAPABILITY_LOS_SATS = 1 << 0;
+ /**
+ * Capability bit flag indicating that GNSS supports per satellite excess-path-length
+ * measurement corrections
+ */
+ const int CAPABILITY_EXCESS_PATH_LENGTH = 1 << 1;
+ /**
+ * Capability bit flag indicating that GNSS supports reflecting planes measurement
+ * corrections
+ */
+ const int CAPABILITY_REFLECTING_PLANE = 1 << 2;
+
+ /**
+ * Callback to inform framework the measurement correction specific capabilities of the GNSS
+ * HAL implementation.
+ *
+ * The GNSS HAL must call this method immediately after the framework opens the measurement
+ * corrections interface.
+ *
+ * @param capabilities A bit field of flags indicating the capabilities of measurement
+ * corrections.
+ * It is mandatory to support either LOS_STATS or EXCESS_PATH_LENGTH capability.
+ */
+ void setCapabilitiesCb(in int capabilities);
+}
diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl
new file mode 100644
index 0000000..eeabc6d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.measurement_corrections;
+
+import android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsCallback;
+import android.hardware.gnss.measurement_corrections.MeasurementCorrections;
+
+/**
+ * Interface for measurement corrections support.
+ */
+@VintfStability
+interface IMeasurementCorrectionsInterface {
+ /**
+ * Injects measurement corrections to be used by the HAL to improve the GNSS location output.
+ *
+ * These are NOT to be used to adjust the IGnssMeasurementCallback output values -
+ * those remain raw, uncorrected measurements.
+ *
+ * In general, these are injected when conditions defined by the platform are met, such as when
+ * GNSS Location is being requested at a sufficiently high accuracy, based on the capabilities
+ * of the GNSS chipset as reported in the IGnssCallback.
+ *
+ * @param corrections The computed corrections to be used by the HAL.
+ */
+ void setCorrections(in MeasurementCorrections corrections);
+
+ /**
+ * Opens the interface and provides the callback routines to the implementation of this
+ * interface.
+ *
+ * @param callback Callback interface for IMeasurementCorrections.
+ */
+ void setCallback(in IMeasurementCorrectionsCallback callback);
+}
diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl
new file mode 100644
index 0000000..285c7d4
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/MeasurementCorrections.aidl
@@ -0,0 +1,102 @@
+/*
+ * 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.measurement_corrections;
+
+import android.hardware.gnss.measurement_corrections.SingleSatCorrection;
+
+/**
+ * A struct containing a set of measurement corrections for all used GNSS satellites at the location
+ * specified by latitudeDegrees, longitudeDegrees, altitudeMeters and at the time of week specified
+ * toaGpsNanosecondsOfWeek
+ */
+@VintfStability
+parcelable MeasurementCorrections {
+ /** Represents latitude in degrees at which the corrections are computed.. */
+ double latitudeDegrees;
+
+ /** Represents longitude in degrees at which the corrections are computed.. */
+ double longitudeDegrees;
+
+ /**
+ * Represents altitude in meters above the WGS 84 reference ellipsoid at which the corrections
+ * are computed.
+ */
+ double altitudeMeters;
+
+ /**
+ * Represents the horizontal uncertainty (63% to 68% confidence) in meters on the device
+ * position at which the corrections are provided.
+ *
+ * This value is useful for example to judge how accurate the provided corrections are.
+ */
+ double horizontalPositionUncertaintyMeters;
+
+ /**
+ * Represents the vertical uncertainty (63% to 68% confidence) in meters on the device position
+ * at which the corrections are provided.
+ *
+ * This value is useful for example to judge how accurate the provided corrections are.
+ */
+ double verticalPositionUncertaintyMeters;
+
+ /** Time Of Applicability, GPS time of week in nanoseconds. */
+ long toaGpsNanosecondsOfWeek;
+
+ /**
+ * A set of SingleSatCorrection each containing measurement corrections for a satellite in view
+ */
+ SingleSatCorrection[] satCorrections;
+
+ /**
+ * Boolean indicating if environment bearing is available.
+ */
+ boolean hasEnvironmentBearing;
+
+ /**
+ * Environment bearing in degrees clockwise from true North (0.0 to 360.0], in direction of
+ * user motion. Environment bearing is provided when it is known with high probability that
+ * velocity is aligned with an environment feature, such as a building or road.
+ *
+ * If user speed is zero, environmentBearingDegrees represents bearing of most recent speed
+ * that was > 0.
+ *
+ * As position approaches another road, environmentBearingUncertaintyDegrees will grow, and at
+ * some stage hasEnvironmentBearing = false.
+ *
+ * As position moves towards an open area, environmentBearingUncertaintyDegrees will grow, and
+ * at some stage hasEnvironmentBearing = false.
+ *
+ * If the road is curved in the vicinity of the user location, then
+ * environmentBearingUncertaintyDegrees will include the amount by which the road direction
+ * changes in the area of position uncertainty.
+ *
+ * hasEnvironmentBearing should be checked to verify the environment bearing is available
+ * before calling this method. The value is undefined if hasEnvironmentBearing is false.
+ */
+ float environmentBearingDegrees;
+
+ /**
+ * Environment bearing uncertainty [0 to 180]. It represents the standard deviation of the
+ * physical structure in the circle of position uncertainty. hasEnvironmentBearing becomes false
+ * as the uncertainty value passes a predefined threshold depending on the physical structure
+ * around the user.
+ *
+ * hasEnvironmentBearing should be checked to verify the environment bearing is available
+ * before calling this method. The value is undefined if hasEnvironmentBearing is false.
+ */
+ float environmentBearingUncertaintyDegrees;
+}
diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
new file mode 100644
index 0000000..9bf2b44
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/ReflectingPlane.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.measurement_corrections;
+
+/**
+ * A struct containing the characteristics of the reflecting plane that the satellite signal has
+ * bounced from.
+ *
+ * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane
+ * means either reflection planes serving is not supported or the satellite signal has gone
+ * through multiple reflections.
+ */
+@VintfStability
+parcelable ReflectingPlane {
+ /** Represents latitude of the reflecting plane in degrees. */
+ double latitudeDegrees;
+
+ /** Represents longitude of the reflecting plane in degrees. */
+ double longitudeDegrees;
+
+ /**
+ * Represents altitude of the reflecting point in the plane in meters above the WGS 84 reference
+ * ellipsoid.
+ */
+ double altitudeMeters;
+
+ /** Represents azimuth clockwise from north of the reflecting plane in degrees. */
+ double azimuthDegrees;
+}
diff --git a/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
new file mode 100644
index 0000000..d9f7105
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/measurement_corrections/SingleSatCorrection.aidl
@@ -0,0 +1,85 @@
+/*
+ * 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.measurement_corrections;
+
+import android.hardware.gnss.GnssConstellationType;
+import android.hardware.gnss.measurement_corrections.ReflectingPlane;
+
+/**
+ * A struct with measurement corrections for a single visible satellites
+ *
+ * The bit mask singleSatCorrectionFlags indicates which correction values are valid in the struct
+ */
+@VintfStability
+parcelable SingleSatCorrection {
+ /** Bit mask to indicate which values are valid in a SingleSatCorrection object. */
+ /** GnssSingleSatCorrectionFlags has valid satellite-is-line-of-sight-probability field. */
+ const int SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY = 0x0001;
+ /** GnssSingleSatCorrectionFlags has valid Excess Path Length field. */
+ const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH = 0x0002;
+ /** GnssSingleSatCorrectionFlags has valid Excess Path Length Uncertainty field. */
+ const int SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC = 0x0004;
+ /** GnssSingleSatCorrectionFlags has valid Reflecting Plane field. */
+ const int SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE = 0x0008;
+
+ /** Contains GnssSingleSatCorrectionFlags bits. */
+ int singleSatCorrectionFlags;
+
+ /**
+ * Defines the constellation of the given satellite.
+ */
+ GnssConstellationType constellation;
+
+ /**
+ * Satellite vehicle ID number, as defined in GnssSvInfo::svid
+ */
+ int svid;
+
+ /**
+ * Carrier frequency of the signal to be corrected, for example it can be the
+ * GPS center frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc.
+ *
+ * For a receiver with capabilities to track multiple frequencies for the same satellite,
+ * multiple corrections for the same satellite may be provided.
+ */
+ long carrierFrequencyHz;
+
+ /**
+ * The probability that the satellite is estimated to be in Line-of-Sight condition at the given
+ * location.
+ */
+ float probSatIsLos;
+
+ /**
+ * Excess path length to be subtracted from pseudorange before using it in calculating location.
+ *
+ * Note this value is NOT to be used to adjust the GnsseasurementCallback outputs.
+ */
+ float excessPathLengthMeters;
+
+ /** Error estimate (1-sigma) for the Excess path length estimate */
+ float excessPathLengthUncertaintyMeters;
+
+ /**
+ * Defines the reflecting plane characteristics such as location and azimuth
+ *
+ * The value is only valid if HAS_REFLECTING_PLANE flag is set. An invalid reflecting plane
+ * means either reflection planes serving is not supported or the satellite signal has gone
+ * through multiple reflections.
+ */
+ ReflectingPlane reflectingPlane;
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 0031dcf..3be7fb9 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -68,6 +68,7 @@
"GnssConfiguration.cpp",
"GnssMeasurementInterface.cpp",
"GnssVisibilityControl.cpp",
+ "MeasurementCorrectionsInterface.cpp",
"service.cpp",
],
static_libs: [
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 797570b..c11a99a 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -30,6 +30,7 @@
#include "GnssNavigationMessageInterface.h"
#include "GnssPsds.h"
#include "GnssVisibilityControl.h"
+#include "MeasurementCorrectionsInterface.h"
#include "NmeaFixInfo.h"
#include "Utils.h"
@@ -288,4 +289,14 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionMeasurementCorrections(
+ std::shared_ptr<measurement_corrections::IMeasurementCorrectionsInterface>*
+ iMeasurementCorrections) {
+ ALOGD("Gnss::getExtensionMeasurementCorrections");
+
+ *iMeasurementCorrections =
+ SharedRefBase::make<measurement_corrections::MeasurementCorrectionsInterface>();
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index b92f4fb..478dc94 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -25,6 +25,7 @@
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
#include <aidl/android/hardware/gnss/BnGnssPsds.h>
+#include <aidl/android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsInterface.h>
#include <aidl/android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
#include <atomic>
#include <mutex>
@@ -72,6 +73,10 @@
iGnssVisibilityControl) override;
ndk::ScopedAStatus getExtensionGnssAntennaInfo(
std::shared_ptr<IGnssAntennaInfo>* iGnssAntennaInfo) override;
+ ndk::ScopedAStatus getExtensionMeasurementCorrections(
+ std::shared_ptr<android::hardware::gnss::measurement_corrections::
+ IMeasurementCorrectionsInterface>* iMeasurementCorrections)
+ override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/MeasurementCorrectionsInterface.cpp b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp
new file mode 100644
index 0000000..0f1851c
--- /dev/null
+++ b/gnss/aidl/default/MeasurementCorrectionsInterface.cpp
@@ -0,0 +1,68 @@
+/*
+ * 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 "MeasurementCorrectionsInterface"
+
+#include "MeasurementCorrectionsInterface.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss::measurement_corrections {
+
+std::shared_ptr<IMeasurementCorrectionsCallback> MeasurementCorrectionsInterface::sCallback =
+ nullptr;
+
+ndk::ScopedAStatus MeasurementCorrectionsInterface::setCorrections(
+ const MeasurementCorrections& corrections) {
+ ALOGD("setCorrections");
+ ALOGD("corrections = lat: %f, lng: %f, alt: %f, hUnc: %f, vUnc: %f, toa: %llu, "
+ "satCorrections.size: %d",
+ corrections.latitudeDegrees, corrections.longitudeDegrees, corrections.altitudeMeters,
+ corrections.horizontalPositionUncertaintyMeters,
+ corrections.verticalPositionUncertaintyMeters,
+ static_cast<unsigned long long>(corrections.toaGpsNanosecondsOfWeek),
+ static_cast<int>(corrections.satCorrections.size()));
+ for (auto singleSatCorrection : corrections.satCorrections) {
+ ALOGD("singleSatCorrection = flags: %d, constellation: %d, svid: %d"
+ ", cfHz: %" PRId64 ", probLos: %f, epl: %f, eplUnc: %f",
+ singleSatCorrection.singleSatCorrectionFlags, singleSatCorrection.constellation,
+ singleSatCorrection.svid, singleSatCorrection.carrierFrequencyHz,
+ singleSatCorrection.probSatIsLos, singleSatCorrection.excessPathLengthMeters,
+ singleSatCorrection.excessPathLengthUncertaintyMeters);
+ ALOGD("reflecting plane = lat: %f, lng: %f, alt: %f, azm: %f",
+ singleSatCorrection.reflectingPlane.latitudeDegrees,
+ singleSatCorrection.reflectingPlane.longitudeDegrees,
+ singleSatCorrection.reflectingPlane.altitudeMeters,
+ singleSatCorrection.reflectingPlane.azimuthDegrees);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus MeasurementCorrectionsInterface::setCallback(
+ const std::shared_ptr<IMeasurementCorrectionsCallback>& callback) {
+ ALOGD("MeasurementCorrections::setCallback");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+ auto ret = sCallback->setCapabilitiesCb(
+ IMeasurementCorrectionsCallback::CAPABILITY_LOS_SATS |
+ IMeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH |
+ IMeasurementCorrectionsCallback::CAPABILITY_REFLECTING_PLANE);
+ if (!ret.isOk()) {
+ ALOGE("%s: Unable to invoke callback", __func__);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::gnss::measurement_corrections
diff --git a/gnss/aidl/default/MeasurementCorrectionsInterface.h b/gnss/aidl/default/MeasurementCorrectionsInterface.h
new file mode 100644
index 0000000..af58725
--- /dev/null
+++ b/gnss/aidl/default/MeasurementCorrectionsInterface.h
@@ -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 <aidl/android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsInterface.h>
+
+namespace aidl::android::hardware::gnss::measurement_corrections {
+
+struct MeasurementCorrectionsInterface : public BnMeasurementCorrectionsInterface {
+ public:
+ ndk::ScopedAStatus setCorrections(const MeasurementCorrections& corrections) override;
+ ndk::ScopedAStatus setCallback(
+ const std::shared_ptr<IMeasurementCorrectionsCallback>& callback) override;
+
+ private:
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+ // Guarded by mMutex
+ static std::shared_ptr<IMeasurementCorrectionsCallback> sCallback;
+};
+
+} // namespace aidl::android::hardware::gnss::measurement_corrections
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index b23a646..4244ab3 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -39,6 +39,7 @@
"GnssNavigationMessageCallback.cpp",
"GnssPowerIndicationCallback.cpp",
"GnssVisibilityControlCallback.cpp",
+ "MeasurementCorrectionsCallback.cpp",
"VtsHalGnssTargetTest.cpp",
],
shared_libs: [
diff --git a/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp b/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp
new file mode 100644
index 0000000..db1f7a6
--- /dev/null
+++ b/gnss/aidl/vts/MeasurementCorrectionsCallback.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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 "MeasurementCorrectionsCallback"
+
+#include "MeasurementCorrectionsCallback.h"
+#include <log/log.h>
+
+android::binder::Status MeasurementCorrectionsCallback::setCapabilitiesCb(const int capabilities) {
+ ALOGI("Capabilities received %d", capabilities);
+ capabilities_cbq_.store(capabilities);
+ return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/MeasurementCorrectionsCallback.h b/gnss/aidl/vts/MeasurementCorrectionsCallback.h
new file mode 100644
index 0000000..27e5b3c
--- /dev/null
+++ b/gnss/aidl/vts/MeasurementCorrectionsCallback.h
@@ -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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsCallback.h>
+#include "GnssCallbackEventQueue.h"
+
+class MeasurementCorrectionsCallback
+ : public android::hardware::gnss::measurement_corrections::BnMeasurementCorrectionsCallback {
+ public:
+ MeasurementCorrectionsCallback() : capabilities_cbq_("capabilities"){};
+ ~MeasurementCorrectionsCallback(){};
+ android::binder::Status setCapabilitiesCb(const int capabilities) override;
+
+ android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
+ int last_capabilities_;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index f5f0aa4..6e363f9 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -25,6 +25,7 @@
#include <android/hardware/gnss/IGnssMeasurementInterface.h>
#include <android/hardware/gnss/IGnssPowerIndication.h>
#include <android/hardware/gnss/IGnssPsds.h>
+#include <android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.h>
#include <android/hardware/gnss/visibility_control/IGnssVisibilityControl.h>
#include <cutils/properties.h>
#include "AGnssCallbackAidl.h"
@@ -35,6 +36,8 @@
#include "GnssNavigationMessageCallback.h"
#include "GnssPowerIndicationCallback.h"
#include "GnssVisibilityControlCallback.h"
+#include "MeasurementCorrectionsCallback.h"
+#include "Utils.h"
#include "gnss_hal_test.h"
using android::sp;
@@ -62,6 +65,8 @@
using android::hardware::gnss::IGnssPsds;
using android::hardware::gnss::PsdsType;
using android::hardware::gnss::SatellitePvt;
+using android::hardware::gnss::common::Utils;
+using android::hardware::gnss::measurement_corrections::IMeasurementCorrectionsInterface;
using android::hardware::gnss::visibility_control::IGnssVisibilityControl;
using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
@@ -909,7 +914,6 @@
}
/*
- * TestAGnssExtension:
* TestGnssVisibilityControlExtension:
* 1. Gets the IGnssVisibilityControl extension.
* 2. Sets GnssVisibilityControlCallback
@@ -1095,3 +1099,43 @@
iGnssAntennaInfo->close();
}
+
+/*
+ * TestGnssMeasurementCorrections:
+ * If measurement corrections capability is supported, verifies that the measurement corrections
+ * capabilities are reported and the mandatory LOS_SATS or the EXCESS_PATH_LENGTH
+ * capability flag is set.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementCorrections) {
+ if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+ return;
+ }
+ if (!(aidl_gnss_cb_->last_capabilities_ &
+ (int)GnssCallbackAidl::CAPABILITY_MEASUREMENT_CORRECTIONS)) {
+ return;
+ }
+
+ sp<IMeasurementCorrectionsInterface> iMeasurementCorrectionsAidl;
+ auto status = aidl_gnss_hal_->getExtensionMeasurementCorrections(&iMeasurementCorrectionsAidl);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(iMeasurementCorrectionsAidl != nullptr);
+
+ // Setup measurement corrections callback.
+ auto gnssMeasurementCorrectionsCallback = sp<MeasurementCorrectionsCallback>::make();
+ status = iMeasurementCorrectionsAidl->setCallback(gnssMeasurementCorrectionsCallback);
+ ASSERT_TRUE(status.isOk());
+
+ const int kTimeoutSec = 5;
+ EXPECT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.retrieve(
+ gnssMeasurementCorrectionsCallback->last_capabilities_, kTimeoutSec));
+ ASSERT_TRUE(gnssMeasurementCorrectionsCallback->capabilities_cbq_.calledCount() > 0);
+
+ ASSERT_TRUE((gnssMeasurementCorrectionsCallback->last_capabilities_ &
+ (MeasurementCorrectionsCallback::CAPABILITY_LOS_SATS |
+ MeasurementCorrectionsCallback::CAPABILITY_EXCESS_PATH_LENGTH)) != 0);
+
+ // Set a mock MeasurementCorrections.
+ status = iMeasurementCorrectionsAidl->setCorrections(
+ Utils::getMockMeasurementCorrections_aidl());
+ ASSERT_TRUE(status.isOk());
+}
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index 06bce9d..da4c07f 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -15,6 +15,7 @@
*/
#include <Utils.h>
+#include <android/hardware/gnss/BnGnss.h>
#include <android/hardware/gnss/IGnss.h>
#include "gtest/gtest.h"
@@ -28,6 +29,12 @@
using namespace measurement_corrections::V1_0;
using V1_0::GnssLocationFlags;
+using MeasurementCorrectionsAidl =
+ android::hardware::gnss::measurement_corrections::MeasurementCorrections;
+using ReflectingPlaneAidl = android::hardware::gnss::measurement_corrections::ReflectingPlane;
+using SingleSatCorrectionAidl =
+ android::hardware::gnss::measurement_corrections::SingleSatCorrection;
+
template <>
int64_t Utils::getLocationTimestampMillis(const android::hardware::gnss::GnssLocation& location) {
return location.timestampMillis;
@@ -63,6 +70,7 @@
.singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC,
+
.constellation = V1_0::GnssConstellationType::GPS,
.svid = 9,
.carrierFrequencyHz = 1.59975e+09,
@@ -114,6 +122,56 @@
return mockCorrections_1_1;
}
+const MeasurementCorrectionsAidl Utils::getMockMeasurementCorrections_aidl() {
+ ReflectingPlaneAidl reflectingPlane;
+ reflectingPlane.latitudeDegrees = 37.4220039;
+ reflectingPlane.longitudeDegrees = -122.0840991;
+ reflectingPlane.altitudeMeters = 250.35;
+ reflectingPlane.azimuthDegrees = 203.0;
+
+ SingleSatCorrectionAidl singleSatCorrection1;
+ singleSatCorrection1.singleSatCorrectionFlags =
+ SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY |
+ SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH |
+ SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC |
+ SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_REFLECTING_PLANE;
+ singleSatCorrection1.constellation = android::hardware::gnss::GnssConstellationType::GPS;
+ singleSatCorrection1.svid = 12;
+ singleSatCorrection1.carrierFrequencyHz = 1.59975e+09;
+ singleSatCorrection1.probSatIsLos = 0.50001;
+ singleSatCorrection1.excessPathLengthMeters = 137.4802;
+ singleSatCorrection1.excessPathLengthUncertaintyMeters = 25.5;
+ singleSatCorrection1.reflectingPlane = reflectingPlane;
+
+ SingleSatCorrectionAidl singleSatCorrection2;
+ singleSatCorrection2.singleSatCorrectionFlags =
+ SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_SAT_IS_LOS_PROBABILITY |
+ SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH |
+ SingleSatCorrectionAidl::SINGLE_SAT_CORRECTION_HAS_EXCESS_PATH_LENGTH_UNC;
+ singleSatCorrection2.constellation = GnssConstellationType::GPS;
+ singleSatCorrection2.svid = 9;
+ singleSatCorrection2.carrierFrequencyHz = 1.59975e+09;
+ singleSatCorrection2.probSatIsLos = 0.873;
+ singleSatCorrection2.excessPathLengthMeters = 26.294;
+ singleSatCorrection2.excessPathLengthUncertaintyMeters = 10.0;
+
+ std::vector<SingleSatCorrectionAidl> singleSatCorrections = {singleSatCorrection1,
+ singleSatCorrection2};
+ MeasurementCorrectionsAidl mockCorrections;
+ mockCorrections.latitudeDegrees = 37.4219999;
+ mockCorrections.longitudeDegrees = -122.0840575;
+ mockCorrections.altitudeMeters = 30.60062531;
+ mockCorrections.horizontalPositionUncertaintyMeters = 9.23542;
+ mockCorrections.verticalPositionUncertaintyMeters = 15.02341;
+ mockCorrections.toaGpsNanosecondsOfWeek = 2935633453L;
+ mockCorrections.hasEnvironmentBearing = true;
+ mockCorrections.environmentBearingDegrees = 45.0;
+ mockCorrections.environmentBearingUncertaintyDegrees = 4.0;
+ mockCorrections.satCorrections = singleSatCorrections;
+
+ return mockCorrections;
+}
+
/*
* MapConstellationType:
* Given a GnssConstellationType_2_0 type constellation, maps to its equivalent
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index 40f31d2..4ea6cd6 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -21,6 +21,8 @@
#include <android/hardware/gnss/2.0/IGnss.h>
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
+#include <android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsInterface.h>
+
#include <gtest/gtest.h>
namespace android {
@@ -36,6 +38,8 @@
getMockMeasurementCorrections();
static const measurement_corrections::V1_1::MeasurementCorrections
getMockMeasurementCorrections_1_1();
+ static const android::hardware::gnss::measurement_corrections::MeasurementCorrections
+ getMockMeasurementCorrections_aidl();
static V1_0::GnssConstellationType mapConstellationType(
V2_0::GnssConstellationType constellation);
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index f67fd34..2460fba 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -58,25 +58,52 @@
bool measureTiming;
OutputType outputType;
MemoryType memoryType;
+ bool reusable;
// `reportSkipping` indicates if a test should print an info message in case
// it is skipped. The field is set to true by default and is set to false in
// quantization coupling tests to suppress skipping a test
bool reportSkipping;
- TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType)
+ TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType,
+ bool reusable)
: executor(executor),
measureTiming(measureTiming),
outputType(outputType),
memoryType(memoryType),
+ reusable(reusable),
reportSkipping(true) {}
TestConfig(Executor executor, bool measureTiming, OutputType outputType, MemoryType memoryType,
- bool reportSkipping)
+ bool reusable, bool reportSkipping)
: executor(executor),
measureTiming(measureTiming),
outputType(outputType),
memoryType(memoryType),
+ reusable(reusable),
reportSkipping(reportSkipping) {}
};
+std::string toString(OutputType type) {
+ switch (type) {
+ case OutputType::FULLY_SPECIFIED:
+ return "FULLY_SPECIFIED";
+ case OutputType::UNSPECIFIED:
+ return "UNSPECIFIED";
+ case OutputType::INSUFFICIENT:
+ return "INSUFFICIENT";
+ case OutputType::MISSED_DEADLINE:
+ return "MISSED_DEADLINE";
+ }
+}
+
+std::string toString(const TestConfig& config) {
+ std::stringstream ss;
+ ss << "TestConfig{.executor=" << toString(config.executor)
+ << ", .measureTiming=" << (config.measureTiming ? "true" : "false")
+ << ", .outputType=" << toString(config.outputType)
+ << ", .memoryType=" << toString(config.memoryType)
+ << ", .reusable=" << (config.reusable ? "true" : "false") << "}";
+ return ss.str();
+}
+
enum class IOType { INPUT, OUTPUT };
class DeviceMemoryAllocator {
@@ -558,209 +585,241 @@
loopTimeoutDurationNs = 1 * kMillisecond;
}
- ErrorStatus executionStatus;
- std::vector<OutputShape> outputShapes;
- Timing timing = kNoTiming;
- switch (testConfig.executor) {
- case Executor::SYNC: {
- SCOPED_TRACE("synchronous");
+ std::shared_ptr<IExecution> execution;
+ if (testConfig.reusable) {
+ const auto ret = preparedModel->createReusableExecution(request, testConfig.measureTiming,
+ loopTimeoutDurationNs, &execution);
+ ASSERT_TRUE(ret.isOk()) << static_cast<nn::ErrorStatus>(ret.getServiceSpecificError());
+ ASSERT_NE(nullptr, execution.get());
+ }
- ExecutionResult executionResult;
- // execute
- const auto ret = preparedModel->executeSynchronously(request, testConfig.measureTiming,
- kNoDeadline, loopTimeoutDurationNs,
- &executionResult);
- ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
- << ret.getDescription();
- if (ret.isOk()) {
- executionStatus = executionResult.outputSufficientSize
- ? ErrorStatus::NONE
- : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE;
- outputShapes = std::move(executionResult.outputShapes);
- timing = executionResult.timing;
- } else {
- executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError());
- }
- break;
- }
- case Executor::BURST: {
- SCOPED_TRACE("burst");
+ const auto executeAndCheckResults = [&preparedModel, &execution, &testConfig, &testModel,
+ &context, &request, loopTimeoutDurationNs, skipped]() {
+ ErrorStatus executionStatus;
+ std::vector<OutputShape> outputShapes;
+ Timing timing = kNoTiming;
+ switch (testConfig.executor) {
+ case Executor::SYNC: {
+ SCOPED_TRACE("synchronous");
- // create burst
- std::shared_ptr<IBurst> burst;
- auto ret = preparedModel->configureExecutionBurst(&burst);
- ASSERT_TRUE(ret.isOk()) << ret.getDescription();
- ASSERT_NE(nullptr, burst.get());
-
- // associate a unique slot with each memory pool
- int64_t currentSlot = 0;
- std::vector<int64_t> slots;
- slots.reserve(request.pools.size());
- for (const auto& pool : request.pools) {
- if (pool.getTag() == RequestMemoryPool::Tag::pool) {
- slots.push_back(currentSlot++);
+ ExecutionResult executionResult;
+ // execute
+ ::ndk::ScopedAStatus ret;
+ if (testConfig.reusable) {
+ ret = execution->executeSynchronously(kNoDeadline, &executionResult);
} else {
- EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token);
- slots.push_back(-1);
+ ret = preparedModel->executeSynchronously(request, testConfig.measureTiming,
+ kNoDeadline, loopTimeoutDurationNs,
+ &executionResult);
}
+ ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
+ << ret.getDescription();
+ if (ret.isOk()) {
+ executionStatus = executionResult.outputSufficientSize
+ ? ErrorStatus::NONE
+ : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE;
+ outputShapes = std::move(executionResult.outputShapes);
+ timing = executionResult.timing;
+ } else {
+ executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError());
+ }
+ break;
}
+ case Executor::BURST: {
+ SCOPED_TRACE("burst");
- ExecutionResult executionResult;
- // execute
- ret = burst->executeSynchronously(request, slots, testConfig.measureTiming, kNoDeadline,
- loopTimeoutDurationNs, &executionResult);
- ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
- << ret.getDescription();
- if (ret.isOk()) {
- executionStatus = executionResult.outputSufficientSize
- ? ErrorStatus::NONE
- : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE;
- outputShapes = std::move(executionResult.outputShapes);
- timing = executionResult.timing;
- } else {
- executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError());
- }
-
- // Mark each slot as unused after the execution. This is unnecessary because the burst
- // is freed after this scope ends, but this is here to test the functionality.
- for (int64_t slot : slots) {
- ret = burst->releaseMemoryResource(slot);
+ // create burst
+ std::shared_ptr<IBurst> burst;
+ auto ret = preparedModel->configureExecutionBurst(&burst);
ASSERT_TRUE(ret.isOk()) << ret.getDescription();
- }
+ ASSERT_NE(nullptr, burst.get());
- break;
- }
- case Executor::FENCED: {
- SCOPED_TRACE("fenced");
- ErrorStatus result = ErrorStatus::NONE;
- FencedExecutionResult executionResult;
- auto ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming,
- kNoDeadline, loopTimeoutDurationNs, kNoDuration,
- &executionResult);
- ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
- << ret.getDescription();
- if (!ret.isOk()) {
- result = static_cast<ErrorStatus>(ret.getServiceSpecificError());
- executionStatus = result;
- } else if (executionResult.syncFence.get() != -1) {
- std::vector<ndk::ScopedFileDescriptor> waitFor;
- auto dupFd = dup(executionResult.syncFence.get());
- ASSERT_NE(dupFd, -1);
- waitFor.emplace_back(dupFd);
- // If a sync fence is returned, try start another run waiting for the sync fence.
- ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming,
- kNoDeadline, loopTimeoutDurationNs, kNoDuration,
- &executionResult);
- ASSERT_TRUE(ret.isOk());
- waitForSyncFence(executionResult.syncFence.get());
- }
- if (result == ErrorStatus::NONE) {
- ASSERT_NE(executionResult.callback, nullptr);
- Timing timingFenced;
- auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced,
- &executionStatus);
- ASSERT_TRUE(ret.isOk());
- }
- break;
- }
- default: {
- FAIL() << "Unsupported execution mode for AIDL interface.";
- }
- }
-
- if (testConfig.outputType != OutputType::FULLY_SPECIFIED &&
- executionStatus == ErrorStatus::GENERAL_FAILURE) {
- if (skipped != nullptr) {
- *skipped = true;
- }
- if (!testConfig.reportSkipping) {
- return;
- }
- LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
- "execute model that it does not support.";
- std::cout << "[ ] Early termination of test because vendor service cannot "
- "execute model that it does not support."
- << std::endl;
- GTEST_SKIP();
- }
- if (!testConfig.measureTiming) {
- EXPECT_EQ(timing, kNoTiming);
- } else {
- if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) {
- EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs);
- }
- }
-
- switch (testConfig.outputType) {
- case OutputType::FULLY_SPECIFIED:
- if (testConfig.executor == Executor::FENCED && hasZeroSizedOutput(testModel)) {
- // Executor::FENCED does not support zero-sized output.
- ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus);
- return;
- }
- // If the model output operands are fully specified, outputShapes must be either
- // either empty, or have the same number of elements as the number of outputs.
- ASSERT_EQ(ErrorStatus::NONE, executionStatus);
- ASSERT_TRUE(outputShapes.size() == 0 ||
- outputShapes.size() == testModel.main.outputIndexes.size());
- break;
- case OutputType::UNSPECIFIED:
- if (testConfig.executor == Executor::FENCED) {
- // For Executor::FENCED, the output shape must be fully specified.
- ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus);
- return;
- }
- // If the model output operands are not fully specified, outputShapes must have
- // the same number of elements as the number of outputs.
- ASSERT_EQ(ErrorStatus::NONE, executionStatus);
- ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size());
- break;
- case OutputType::INSUFFICIENT:
- if (testConfig.executor == Executor::FENCED) {
- // For Executor::FENCED, the output shape must be fully specified.
- ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus);
- return;
- }
- ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus);
- ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size());
- // Check that all returned output dimensions are at least as fully specified as the
- // union of the information about the corresponding operand in the model and in the
- // request. In this test, all model outputs have known rank with all dimensions
- // unspecified, and no dimensional information is provided in the request.
- for (uint32_t i = 0; i < outputShapes.size(); i++) {
- ASSERT_EQ(outputShapes[i].isSufficient, i != kInsufficientOutputIndex);
- const auto& actual = outputShapes[i].dimensions;
- const auto& golden =
- testModel.main.operands[testModel.main.outputIndexes[i]].dimensions;
- ASSERT_EQ(actual.size(), golden.size());
- for (uint32_t j = 0; j < actual.size(); j++) {
- if (actual[j] == 0) continue;
- EXPECT_EQ(actual[j], golden[j]) << "index: " << j;
+ // associate a unique slot with each memory pool
+ int64_t currentSlot = 0;
+ std::vector<int64_t> slots;
+ slots.reserve(request.pools.size());
+ for (const auto& pool : request.pools) {
+ if (pool.getTag() == RequestMemoryPool::Tag::pool) {
+ slots.push_back(currentSlot++);
+ } else {
+ EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token);
+ slots.push_back(-1);
+ }
}
+
+ ExecutionResult executionResult;
+ // execute
+ ret = burst->executeSynchronously(request, slots, testConfig.measureTiming,
+ kNoDeadline, loopTimeoutDurationNs,
+ &executionResult);
+ ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
+ << ret.getDescription();
+ if (ret.isOk()) {
+ executionStatus = executionResult.outputSufficientSize
+ ? ErrorStatus::NONE
+ : ErrorStatus::OUTPUT_INSUFFICIENT_SIZE;
+ outputShapes = std::move(executionResult.outputShapes);
+ timing = executionResult.timing;
+ } else {
+ executionStatus = static_cast<ErrorStatus>(ret.getServiceSpecificError());
+ }
+
+ // Mark each slot as unused after the execution. This is unnecessary because the
+ // burst is freed after this scope ends, but this is here to test the functionality.
+ for (int64_t slot : slots) {
+ ret = burst->releaseMemoryResource(slot);
+ ASSERT_TRUE(ret.isOk()) << ret.getDescription();
+ }
+
+ break;
}
- return;
- case OutputType::MISSED_DEADLINE:
- ASSERT_TRUE(executionStatus == ErrorStatus::MISSED_DEADLINE_TRANSIENT ||
- executionStatus == ErrorStatus::MISSED_DEADLINE_PERSISTENT)
- << "executionStatus = " << executionStatus;
- return;
+ case Executor::FENCED: {
+ SCOPED_TRACE("fenced");
+ ErrorStatus result = ErrorStatus::NONE;
+ FencedExecutionResult executionResult;
+ ::ndk::ScopedAStatus ret;
+ if (testConfig.reusable) {
+ ret = execution->executeFenced({}, kNoDeadline, kNoDuration, &executionResult);
+ } else {
+ ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming,
+ kNoDeadline, loopTimeoutDurationNs,
+ kNoDuration, &executionResult);
+ }
+ ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
+ << ret.getDescription();
+ if (!ret.isOk()) {
+ result = static_cast<ErrorStatus>(ret.getServiceSpecificError());
+ executionStatus = result;
+ } else if (executionResult.syncFence.get() != -1) {
+ std::vector<ndk::ScopedFileDescriptor> waitFor;
+ auto dupFd = dup(executionResult.syncFence.get());
+ ASSERT_NE(dupFd, -1);
+ waitFor.emplace_back(dupFd);
+ // If a sync fence is returned, try start another run waiting for the sync
+ // fence.
+ ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming,
+ kNoDeadline, loopTimeoutDurationNs,
+ kNoDuration, &executionResult);
+ ASSERT_TRUE(ret.isOk());
+ waitForSyncFence(executionResult.syncFence.get());
+ }
+ if (result == ErrorStatus::NONE) {
+ ASSERT_NE(executionResult.callback, nullptr);
+ Timing timingFenced;
+ auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced,
+ &executionStatus);
+ ASSERT_TRUE(ret.isOk());
+ }
+ break;
+ }
+ default: {
+ FAIL() << "Unsupported execution mode for AIDL interface.";
+ }
+ }
+
+ if (testConfig.outputType != OutputType::FULLY_SPECIFIED &&
+ executionStatus == ErrorStatus::GENERAL_FAILURE) {
+ if (skipped != nullptr) {
+ *skipped = true;
+ }
+ if (!testConfig.reportSkipping) {
+ return;
+ }
+ LOG(INFO) << "NN VTS: Early termination of test because vendor service cannot "
+ "execute model that it does not support.";
+ std::cout << "[ ] Early termination of test because vendor service cannot "
+ "execute model that it does not support."
+ << std::endl;
+ GTEST_SKIP();
+ }
+ if (!testConfig.measureTiming) {
+ EXPECT_EQ(timing, kNoTiming);
+ } else {
+ if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) {
+ EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs);
+ }
+ }
+
+ switch (testConfig.outputType) {
+ case OutputType::FULLY_SPECIFIED:
+ if (testConfig.executor == Executor::FENCED && hasZeroSizedOutput(testModel)) {
+ // Executor::FENCED does not support zero-sized output.
+ ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus);
+ return;
+ }
+ // If the model output operands are fully specified, outputShapes must be either
+ // either empty, or have the same number of elements as the number of outputs.
+ ASSERT_EQ(ErrorStatus::NONE, executionStatus);
+ ASSERT_TRUE(outputShapes.size() == 0 ||
+ outputShapes.size() == testModel.main.outputIndexes.size());
+ break;
+ case OutputType::UNSPECIFIED:
+ if (testConfig.executor == Executor::FENCED) {
+ // For Executor::FENCED, the output shape must be fully specified.
+ ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus);
+ return;
+ }
+ // If the model output operands are not fully specified, outputShapes must have
+ // the same number of elements as the number of outputs.
+ ASSERT_EQ(ErrorStatus::NONE, executionStatus);
+ ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size());
+ break;
+ case OutputType::INSUFFICIENT:
+ if (testConfig.executor == Executor::FENCED) {
+ // For Executor::FENCED, the output shape must be fully specified.
+ ASSERT_EQ(ErrorStatus::INVALID_ARGUMENT, executionStatus);
+ return;
+ }
+ ASSERT_EQ(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, executionStatus);
+ ASSERT_EQ(outputShapes.size(), testModel.main.outputIndexes.size());
+ // Check that all returned output dimensions are at least as fully specified as the
+ // union of the information about the corresponding operand in the model and in the
+ // request. In this test, all model outputs have known rank with all dimensions
+ // unspecified, and no dimensional information is provided in the request.
+ for (uint32_t i = 0; i < outputShapes.size(); i++) {
+ ASSERT_EQ(outputShapes[i].isSufficient, i != kInsufficientOutputIndex);
+ const auto& actual = outputShapes[i].dimensions;
+ const auto& golden =
+ testModel.main.operands[testModel.main.outputIndexes[i]].dimensions;
+ ASSERT_EQ(actual.size(), golden.size());
+ for (uint32_t j = 0; j < actual.size(); j++) {
+ if (actual[j] == 0) continue;
+ EXPECT_EQ(actual[j], golden[j]) << "index: " << j;
+ }
+ }
+ return;
+ case OutputType::MISSED_DEADLINE:
+ ASSERT_TRUE(executionStatus == ErrorStatus::MISSED_DEADLINE_TRANSIENT ||
+ executionStatus == ErrorStatus::MISSED_DEADLINE_PERSISTENT)
+ << "executionStatus = " << executionStatus;
+ return;
+ }
+
+ // Go through all outputs, check returned output shapes.
+ for (uint32_t i = 0; i < outputShapes.size(); i++) {
+ EXPECT_TRUE(outputShapes[i].isSufficient);
+ const auto& expect =
+ testModel.main.operands[testModel.main.outputIndexes[i]].dimensions;
+ const auto unsignedActual = nn::toUnsigned(outputShapes[i].dimensions);
+ ASSERT_TRUE(unsignedActual.has_value());
+ const std::vector<uint32_t>& actual = unsignedActual.value();
+ EXPECT_EQ(expect, actual);
+ }
+
+ // Retrieve execution results.
+ const std::vector<TestBuffer> outputs = context.getOutputBuffers(testModel, request);
+
+ // We want "close-enough" results.
+ checkResults(testModel, outputs);
+ };
+
+ executeAndCheckResults();
+
+ // For reusable execution tests, run the execution twice.
+ if (testConfig.reusable) {
+ SCOPED_TRACE("Second execution");
+ executeAndCheckResults();
}
-
- // Go through all outputs, check returned output shapes.
- for (uint32_t i = 0; i < outputShapes.size(); i++) {
- EXPECT_TRUE(outputShapes[i].isSufficient);
- const auto& expect = testModel.main.operands[testModel.main.outputIndexes[i]].dimensions;
- const auto unsignedActual = nn::toUnsigned(outputShapes[i].dimensions);
- ASSERT_TRUE(unsignedActual.has_value());
- const std::vector<uint32_t>& actual = unsignedActual.value();
- EXPECT_EQ(expect, actual);
- }
-
- // Retrieve execution results.
- const std::vector<TestBuffer> outputs = context.getOutputBuffers(testModel, request);
-
- // We want "close-enough" results.
- checkResults(testModel, outputs);
}
void EvaluatePreparedModel(const std::shared_ptr<IDevice>& device,
@@ -770,6 +829,13 @@
std::vector<bool> measureTimingList;
std::vector<Executor> executorList;
std::vector<MemoryType> memoryTypeList;
+ std::vector<bool> reusableList = {false};
+
+ int deviceVersion;
+ ASSERT_TRUE(device->getInterfaceVersion(&deviceVersion).isOk());
+ if (deviceVersion >= kMinAidlLevelForFL8) {
+ reusableList.push_back(true);
+ }
switch (testKind) {
case TestKind::GENERAL: {
@@ -812,8 +878,13 @@
for (const bool measureTiming : measureTimingList) {
for (const Executor executor : executorList) {
for (const MemoryType memoryType : memoryTypeList) {
- const TestConfig testConfig(executor, measureTiming, outputType, memoryType);
- EvaluatePreparedModel(device, preparedModel, testModel, testConfig);
+ for (const bool reusable : reusableList) {
+ if (executor == Executor::BURST && reusable) continue;
+ const TestConfig testConfig(executor, measureTiming, outputType, memoryType,
+ reusable);
+ SCOPED_TRACE(toString(testConfig));
+ EvaluatePreparedModel(device, preparedModel, testModel, testConfig);
+ }
}
}
}
@@ -833,7 +904,7 @@
for (const bool measureTiming : measureTimingList) {
for (const Executor executor : executorList) {
const TestConfig testConfig(executor, measureTiming, outputType, MemoryType::ASHMEM,
- /*reportSkipping=*/false);
+ /*reusable=*/false, /*reportSkipping=*/false);
bool baseSkipped = false;
EvaluatePreparedModel(device, preparedModel, testModel, testConfig, &baseSkipped);
bool coupledSkipped = false;
diff --git a/neuralnetworks/aidl/vts/functional/Utils.cpp b/neuralnetworks/aidl/vts/functional/Utils.cpp
index 325a436..efd5bca 100644
--- a/neuralnetworks/aidl/vts/functional/Utils.cpp
+++ b/neuralnetworks/aidl/vts/functional/Utils.cpp
@@ -177,6 +177,17 @@
return os << toString(errorStatus);
}
+std::string toString(MemoryType type) {
+ switch (type) {
+ case MemoryType::ASHMEM:
+ return "ASHMEM";
+ case MemoryType::BLOB_AHWB:
+ return "BLOB_AHWB";
+ case MemoryType::DEVICE:
+ return "DEVICE";
+ }
+}
+
Request ExecutionContext::createRequest(const TestModel& testModel, MemoryType memoryType) {
CHECK(memoryType == MemoryType::ASHMEM || memoryType == MemoryType::BLOB_AHWB);
diff --git a/neuralnetworks/aidl/vts/functional/Utils.h b/neuralnetworks/aidl/vts/functional/Utils.h
index ca81418..0db3f8c 100644
--- a/neuralnetworks/aidl/vts/functional/Utils.h
+++ b/neuralnetworks/aidl/vts/functional/Utils.h
@@ -111,6 +111,8 @@
enum class MemoryType { ASHMEM, BLOB_AHWB, DEVICE };
+std::string toString(MemoryType type);
+
// Manages the lifetime of memory resources used in an execution.
class ExecutionContext {
DISALLOW_COPY_AND_ASSIGN(ExecutionContext);
diff --git a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
index 29e2471..e8debf7 100644
--- a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
@@ -36,6 +36,51 @@
///////////////////////// UTILITY FUNCTIONS /////////////////////////
+// Test request validation with reusable execution.
+static void validateReusableExecution(const std::shared_ptr<IPreparedModel>& preparedModel,
+ const std::string& message, const Request& request,
+ bool measure) {
+ // createReusableExecution
+ std::shared_ptr<IExecution> execution;
+ {
+ SCOPED_TRACE(message + " [createReusableExecution]");
+ const auto createStatus = preparedModel->createReusableExecution(
+ request, measure, kOmittedTimeoutDuration, &execution);
+ if (!createStatus.isOk()) {
+ ASSERT_EQ(createStatus.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorStatus>(createStatus.getServiceSpecificError()),
+ ErrorStatus::INVALID_ARGUMENT);
+ ASSERT_EQ(nullptr, execution);
+ return;
+ } else {
+ ASSERT_NE(nullptr, execution);
+ }
+ }
+
+ // synchronous
+ {
+ SCOPED_TRACE(message + " [executeSynchronously]");
+ ExecutionResult executionResult;
+ const auto executeStatus = execution->executeSynchronously(kNoDeadline, &executionResult);
+ ASSERT_FALSE(executeStatus.isOk());
+ ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()),
+ ErrorStatus::INVALID_ARGUMENT);
+ }
+
+ // fenced
+ {
+ SCOPED_TRACE(message + " [executeFenced]");
+ FencedExecutionResult executionResult;
+ const auto executeStatus =
+ execution->executeFenced({}, kNoDeadline, kNoDuration, &executionResult);
+ ASSERT_FALSE(executeStatus.isOk());
+ ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()),
+ ErrorStatus::INVALID_ARGUMENT);
+ }
+}
+
// Primary validation function. This function will take a valid request, apply a
// mutation to it to invalidate the request, then pass it to interface calls
// that use the request.
@@ -101,6 +146,14 @@
ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()),
ErrorStatus::INVALID_ARGUMENT);
}
+
+ int32_t aidlVersion;
+ ASSERT_TRUE(preparedModel->getInterfaceVersion(&aidlVersion).isOk());
+
+ // validate reusable execution
+ if (aidlVersion >= kMinAidlLevelForFL8) {
+ validateReusableExecution(preparedModel, message, request, measure);
+ }
}
std::shared_ptr<IBurst> createBurst(const std::shared_ptr<IPreparedModel>& preparedModel) {
diff --git a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h
index 4312d3a..a900590 100644
--- a/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/aidl/vts/functional/VtsHalNeuralnetworks.h
@@ -30,6 +30,8 @@
using NamedDevice = Named<std::shared_ptr<IDevice>>;
using NeuralNetworksAidlTestParam = NamedDevice;
+constexpr int kMinAidlLevelForFL8 = 4;
+
class NeuralNetworksAidlTest : public testing::TestWithParam<NeuralNetworksAidlTestParam> {
protected:
void SetUp() override;
diff --git a/wifi/1.6/default/Android.bp b/wifi/1.6/default/Android.bp
index 6333b6e..d48d183 100644
--- a/wifi/1.6/default/Android.bp
+++ b/wifi/1.6/default/Android.bp
@@ -33,6 +33,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi@1.6",
"libbase",
"libcutils",
"libhidlbase",
@@ -84,6 +85,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi@1.6",
"libbase",
"libcutils",
"libhidlbase",
diff --git a/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc
index bc6bb6a..ee8c818 100644
--- a/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc
+++ b/wifi/1.6/default/android.hardware.wifi@1.0-service-lazy.rc
@@ -5,6 +5,7 @@
interface android.hardware.wifi@1.3::IWifi default
interface android.hardware.wifi@1.4::IWifi default
interface android.hardware.wifi@1.5::IWifi default
+ interface android.hardware.wifi@1.6::IWifi default
oneshot
disabled
class hal
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl
index 890d986..4d78640 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Bandwidth.aidl
@@ -41,8 +41,9 @@
BANDWIDTH_80 = 4,
BANDWIDTH_80P80 = 5,
BANDWIDTH_160 = 6,
- BANDWIDTH_2160 = 7,
- BANDWIDTH_4320 = 8,
- BANDWIDTH_6480 = 9,
- BANDWIDTH_8640 = 10,
+ BANDWIDTH_320 = 7,
+ BANDWIDTH_2160 = 8,
+ BANDWIDTH_4320 = 9,
+ BANDWIDTH_6480 = 10,
+ BANDWIDTH_8640 = 11,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
index 6b60d17..af0e960 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/Generation.aidl
@@ -40,4 +40,5 @@
WIFI_STANDARD_11AC = 2,
WIFI_STANDARD_11AX = 3,
WIFI_STANDARD_11AD = 4,
+ WIFI_STANDARD_11BE = 5,
}
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl
index 844c838..8d8d7bb 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/HwModeParams.aidl
@@ -43,4 +43,5 @@
boolean enableHeMultiUserBeamformer;
boolean enableHeTargetWakeTime;
boolean enableEdmg;
+ boolean enable80211BE;
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl
index c982402..e605153 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Bandwidth.aidl
@@ -29,8 +29,9 @@
BANDWIDTH_80 = 4,
BANDWIDTH_80P80 = 5,
BANDWIDTH_160 = 6,
- BANDWIDTH_2160 = 7,
- BANDWIDTH_4320 = 8,
- BANDWIDTH_6480 = 9,
- BANDWIDTH_8640 = 10,
+ BANDWIDTH_320 = 7,
+ BANDWIDTH_2160 = 8,
+ BANDWIDTH_4320 = 9,
+ BANDWIDTH_6480 = 10,
+ BANDWIDTH_8640 = 11,
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl
index 2cda55b..f4e3eb0 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/Generation.aidl
@@ -27,6 +27,7 @@
* WIFI_STANDARD_11AC = hw_mode is HOSTAPD_MODE_IEEE80211A and VHT is 1.
* WIFI_STANDARD_11AX = hw_mode is HOSTAPD_MODE_IEEE80211A and High Efficiency supported.
* WIFI_STANDARD_11AD = hw_mode is HOSTAPD_MODE_IEEE80211AD.
+ * WIFI_STANDARD_11BE = hw_mode is HOSTAPD_MODE_IEEE80211A and Extreme High Throughput supported.
*/
@VintfStability
@Backing(type="int")
@@ -37,4 +38,5 @@
WIFI_STANDARD_11AC = 2,
WIFI_STANDARD_11AX = 3,
WIFI_STANDARD_11AD = 4,
+ WIFI_STANDARD_11BE = 5,
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl
index 210e99f..e66a24a 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/HwModeParams.aidl
@@ -68,4 +68,10 @@
* Enable EDMG (802.11ay), this option is only allowed for the 60GHz band.
*/
boolean enableEdmg;
+ /**
+ * Whether IEEE 802.11be (Extreme High Throughput) is enabled or not.
+ * Note: hw_mode=a is used to specify that 5 GHz band or 6 GHz band is
+ * used with Extreme High Throughput.
+ */
+ boolean enable80211BE;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl
index ad36e68..bf5081e 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl
@@ -39,4 +39,5 @@
HT = 2,
VHT = 3,
HE = 4,
+ EHT = 5,
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl
index 00c16b4..d364c75 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl
@@ -39,4 +39,8 @@
* For 802.11ax
*/
HE = 4,
+ /**
+ * For 802.11be
+ */
+ EHT = 5,
}