Merge "Remove GNSS HAL v3.0 (hardware/interfaces)"
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 0f0cdcf..0ebe4c2 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -128,7 +128,7 @@
INSTANTIATE_TEST_CASE_P(SingleConfigOutputStream, SingleConfigOutputStreamTest,
::testing::ValuesIn(getOutputDeviceSingleConfigParameters()),
&DeviceConfigParameterToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigOutputStream);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigOutputStreamTest);
class SingleConfigInputStreamTest : public InputStreamTest {};
TEST_P(SingleConfigInputStreamTest, CloseDeviceWithOpenedInputStreams) {
@@ -142,7 +142,7 @@
INSTANTIATE_TEST_CASE_P(SingleConfigInputStream, SingleConfigInputStreamTest,
::testing::ValuesIn(getInputDeviceSingleConfigParameters()),
&DeviceConfigParameterToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigInputStream);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigInputStreamTest);
TEST_P(AudioPatchHidlTest, UpdatePatchInvalidHandle) {
doc::test("Verify that passing an invalid handle to updateAudioPatch is checked");
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index ef4daba..7fca610 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -296,7 +296,7 @@
InputBufferSizeInvalidConfig, InvalidInputConfigNoFlagsTest,
::testing::ValuesIn(getInputDeviceInvalidConfigParameters(false /*generateInvalidFlags*/)),
&DeviceConfigParameterToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputBufferSizeInvalidConfig);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InvalidInputConfigNoFlagsTest);
static const DeviceAddress& getValidInputDeviceAddress() {
static const DeviceAddress valid = {
@@ -682,9 +682,7 @@
::testing::Values(getValidInputDeviceAddress()),
::testing::ValuesIn(wrapMetadata(getInvalidSinkMetadatas()))),
&StreamOpenParameterToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputStreamInvalidConfig);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputStreamInvalidAddress);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputStreamInvalidMetadata);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StreamOpenTest);
INSTANTIATE_TEST_CASE_P(
OutputStreamInvalidConfig, StreamOpenTest,
@@ -706,9 +704,6 @@
::testing::Values(getValidOutputDeviceAddress()),
::testing::ValuesIn(wrapMetadata(getInvalidSourceMetadatas()))),
&StreamOpenParameterToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamInvalidConfig);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamInvalidAddress);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamInvalidMetadata);
#define TEST_SINGLE_CONFIG_IO_STREAM(test_name, documentation, code) \
TEST_P(SingleConfigInputStreamTest, test_name) { \
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
new file mode 100644
index 0000000..3043000
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+@VintfStability
+parcelable AuthenticationFrame {
+ android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
new file mode 100644
index 0000000..27821e3
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
@@ -0,0 +1,28 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+@VintfStability
+parcelable BaseFrame {
+ android.hardware.biometrics.face.AcquiredInfo acquiredInfo;
+ int vendorCode;
+ float pan;
+ float tilt;
+ float distance;
+ boolean isCancellable;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
new file mode 100644
index 0000000..17c1ba3
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+@VintfStability
+parcelable Cell {
+ int x;
+ int y;
+ int z;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
new file mode 100644
index 0000000..c736e7e
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+@VintfStability
+parcelable EnrollmentFrame {
+ @nullable android.hardware.biometrics.face.Cell cell;
+ android.hardware.biometrics.face.EnrollmentStage stage;
+ android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
new file mode 100644
index 0000000..af6be90
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -0,0 +1,28 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum EnrollmentStage {
+ FIRST_FRAME_RECEIVED = 0,
+ WAITING_FOR_CENTERING = 1,
+ HOLD_STILL_IN_CENTER = 2,
+ ENROLLING_MOVEMENT_1 = 3,
+ ENROLLING_MOVEMENT_2 = 4,
+ ENROLLMENT_FINISHED = 5,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
new file mode 100644
index 0000000..268ce52
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+@VintfStability
+parcelable EnrollmentStageConfig {
+ android.hardware.biometrics.face.EnrollmentStage stage;
+ List<android.hardware.biometrics.face.Cell> cells;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
new file mode 100644
index 0000000..7295b3b
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+@Backing(type="byte") @VintfStability
+enum EnrollmentType {
+ DEFAULT = 0,
+ ACCESSIBILITY = 1,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index 7d70971..203e275 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -21,7 +21,7 @@
interface ISession {
void generateChallenge(in int cookie, in int timeoutSec);
void revokeChallenge(in int cookie, in long challenge);
- android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface);
+ android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.biometrics.face.EnrollmentType enrollmentType, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.common.NativeHandle previewSurface);
android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
android.hardware.biometrics.common.ICancellationSignal detectInteraction(in int cookie);
void enumerateEnrollments(in int cookie);
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
index 4cea0f0..a81c79a 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -22,7 +22,8 @@
void onStateChanged(in int cookie, in android.hardware.biometrics.face.SessionState state);
void onChallengeGenerated(in long challenge);
void onChallengeRevoked(in long challenge);
- void onAcquired(in android.hardware.biometrics.face.AcquiredInfo info, in int vendorCode);
+ void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame);
+ void onEnrollmentFrame(in android.hardware.biometrics.face.EnrollmentFrame frame);
void onError(in android.hardware.biometrics.face.Error error, in int vendorCode);
void onEnrollmentProgress(in int enrollmentId, int remaining);
void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
index 56a600f..217a9bb 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
new file mode 100644
index 0000000..47cad3c
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -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.
+ */
+
+package android.hardware.biometrics.face;
+
+import android.hardware.biometrics.face.BaseFrame;
+
+/**
+ * Describes an individual frame captured during authentication.
+ */
+@VintfStability
+parcelable AuthenticationFrame {
+
+ /**
+ * The frame metadata. Can be used by the framework to provide user feedback.
+ */
+ BaseFrame data;
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
new file mode 100644
index 0000000..9e6b98a
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
@@ -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.
+ */
+
+package android.hardware.biometrics.face;
+
+import android.hardware.biometrics.face.AcquiredInfo;
+
+/**
+ * Metadata of an individual frame. Can be used by the framework to provide user feedback.
+ * This parcelable is part of AuthenticationFrame and EnrollmentFrame, and shouldn't be used
+ * independently of those parcelables.
+ */
+@VintfStability
+parcelable BaseFrame {
+ /**
+ * Information about the frame that can be used by the framework to provide feedback to the
+ * user, for example ask the user to move their face in a certain way.
+ */
+ AcquiredInfo acquiredInfo;
+
+ /**
+ * If acquiredInfo is set to AcquiredInfo::VENDOR. This is the index into the configuration
+ * "com.android.internal.R.array.face_acquired_vendor" that's installed on the vendor partition.
+ * Otherwise, this value must be ignored.
+ */
+ int vendorCode;
+
+ /**
+ * Pan value. It is recommended to use the range of [-1, 1] to represent valid values, and
+ * anything outside of that range to represent errors. However, vendors are free to define
+ * their own way of representing valid values and errors.
+ */
+ float pan;
+
+ /**
+ * Tilt value. It is recommended to use the range of [-1, 1] to represent valid values, and
+ * anything outside of that range to represent errors. However, vendors are free to define
+ * their own way of representing valid values and errors.
+ */
+ float tilt;
+
+ /**
+ * Distance value. It is recommended to use the range of [-1, 1] to represent valid values, and
+ * anything outside of that range to represent errors. However, vendors are free to define
+ * their own way of representing valid values and errors.
+ */
+ float distance;
+
+ /**
+ * Indicates that the HAL can no longer continue with authentication or enrollment. This allows
+ * the framework to correlate a failure condition with a particular AcquiredInfo, rather than
+ * having a sequence of AcquiredInfo + Error.
+ */
+ boolean isCancellable;
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
new file mode 100644
index 0000000..77f33b9
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.biometrics.face;
+
+/**
+ * Coordinates of an enrollment UI cell in a vendor-defined coordinate system.
+ */
+@VintfStability
+parcelable Cell {
+ int x;
+ int y;
+ int z;
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
new file mode 100644
index 0000000..d4f9771
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.biometrics.face;
+
+import android.hardware.biometrics.face.Cell;
+import android.hardware.biometrics.face.EnrollmentStage;
+import android.hardware.biometrics.face.BaseFrame;
+
+/**
+ * Describes an individual frame captured during enrollment.
+ */
+@VintfStability
+parcelable EnrollmentFrame {
+ /**
+ * The enrollment UI cell that was captured in this frame, or null if no cell was captured.
+ */
+ @nullable Cell cell;
+
+ /**
+ * The enrollment stage for which this frame was captured.
+ */
+ EnrollmentStage stage;
+
+ /**
+ * The frame metadata. Can be used by the framework to provide user feedback.
+ */
+ BaseFrame data;
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
new file mode 100644
index 0000000..bbc874f
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.biometrics.face;
+
+/**
+ * Enrollment stages that can be mapped to the enrollment UI actions in the framework.
+ */
+@VintfStability
+@Backing(type="byte")
+enum EnrollmentStage {
+
+ /**
+ * HAL has obtained the first camera frame.
+ */
+ FIRST_FRAME_RECEIVED,
+
+ /**
+ * HAL is waiting for the user's face to be centered.
+ */
+ WAITING_FOR_CENTERING,
+
+ /**
+ * HAL is expecting the user's face to stay centered.
+ */
+ HOLD_STILL_IN_CENTER,
+
+ /**
+ * Vendor defined movement 1.
+ */
+ ENROLLING_MOVEMENT_1,
+
+ /**
+ * Vendor defined movement 2.
+ */
+ ENROLLING_MOVEMENT_2,
+
+ /**
+ * HAL has finished the enrollment.
+ */
+ ENROLLMENT_FINISHED,
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
new file mode 100644
index 0000000..0b64e2b
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.biometrics.face;
+
+import android.hardware.biometrics.face.Cell;
+import android.hardware.biometrics.face.EnrollmentStage;
+
+@VintfStability
+parcelable EnrollmentStageConfig {
+ /**
+ * The stage that's being configured.
+ */
+ EnrollmentStage stage;
+
+ /**
+ * Optional list of cells that must be completed to finish this stage.
+ */
+ List<Cell> cells;
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
new file mode 100644
index 0000000..d7f3175
--- /dev/null
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.biometrics.face;
+
+@VintfStability
+@Backing(type="byte")
+enum EnrollmentType {
+ DEFAULT,
+ ACCESSIBILITY,
+}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
index 1d02456..d88370f 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
index 766f732..2a5dd20 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
index e9a66e2..f9ed4b1 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 425b352..34a1f8b 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -17,6 +17,7 @@
package android.hardware.biometrics.face;
import android.hardware.biometrics.common.ICancellationSignal;
+import android.hardware.biometrics.face.EnrollmentType;
import android.hardware.keymaster.HardwareAuthToken;
import android.hardware.common.NativeHandle;
@@ -85,6 +86,18 @@
void revokeChallenge(in int cookie, in long challenge);
/**
+ * getEnrollmentConfig:
+ *
+ * Returns the enrollment configuration depending on the provided enrollment type. Enrollment
+ * configuration determines how many stages the enrollment will have and the requirements for
+ * each of the stages.
+ *
+ * @param enrollmentType See the EnrollmentType enum.
+ * @return A list of EnrollmentStageConfig that describes each enrollment stage.
+ *
+ List<EnrollmentStageConfig> getEnrollmentConfig(in EnrollmentType enrollmentType);
+
+ /**
* enroll:
*
* A request to add a face enrollment.
@@ -118,6 +131,7 @@
*
* @param cookie An identifier used to track subsystem operations related to this call path. The
* client must guarantee that it is unique per ISession.
+ * @param enrollmentType See the EnrollmentType enum.
* @param previewSurface A surface provided by the framework if SensorProps#halControlsPreview is
* set to true. The HAL must send the preview frames to previewSurface if
* it's not null.
@@ -125,7 +139,8 @@
* @return ICancellationSignal An object that can be used by the framework to cancel this
* operation.
*/
- ICancellationSignal enroll(in int cookie, in HardwareAuthToken hat, in NativeHandle previewSurface);
+ ICancellationSignal enroll(in int cookie, in EnrollmentType enrollmentType,
+ in HardwareAuthToken hat, in NativeHandle previewSurface);
/**
* authenticate:
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
index d59ce2e..9178e3a 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
@@ -17,6 +17,8 @@
package android.hardware.biometrics.face;
import android.hardware.biometrics.face.AcquiredInfo;
+import android.hardware.biometrics.face.AuthenticationFrame;
+import android.hardware.biometrics.face.EnrollmentFrame;
import android.hardware.biometrics.face.Error;
import android.hardware.biometrics.face.SessionState;
import android.hardware.keymaster.HardwareAuthToken;
@@ -40,20 +42,26 @@
/**
* This method must only be used to notify the framework during the following states:
- * 1) SessionState::ENROLLING
- * 2) SessionState::AUTHENTICATING
- * 3) SessionState::DETECTING_INTERACTION
+ * 1) SessionState::AUTHENTICATING
+ * 2) SessionState::DETECTING_INTERACTION
*
* These messages may be used to provide user guidance multiple times if necessary per
* operation.
*
- * @param info See the AcquiredInfo enum.
- * @param vendorCode Only valid if info == AcquiredInfo::VENDOR. The vendorCode must be used to
- * index into the configuration
- * com.android.internal.R.array.face_acquired_vendor that's installed
- * on the vendor partition.
+ * @param frame See the AuthenticationFrame enum.
*/
- void onAcquired(in AcquiredInfo info, in int vendorCode);
+ void onAuthenticationFrame(in AuthenticationFrame frame);
+
+ /**
+ * This method must only be used to notify the framework during the SessionState::ENROLLING
+ * state.
+ *
+ * These messages may be used to provide user guidance multiple times if necessary per
+ * operation.
+ *
+ * @param frame See the EnrollmentFrame enum.
+ */
+ void onEnrollmentFrame(in EnrollmentFrame frame);
/**
* This method must only be used to notify the framework during the following states:
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
index 9c2f9a1..335f2f9 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl
index 1878f7c..e56f5d8 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SessionState.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * 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.
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index c5d7d23..df51879 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -23,6 +23,7 @@
class CancellationSignal : public common::BnCancellationSignal {
private:
std::shared_ptr<ISessionCallback> cb_;
+
public:
explicit CancellationSignal(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
@@ -53,10 +54,10 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Session::enroll(int32_t /*cookie*/, const keymaster::HardwareAuthToken& /*hat*/,
- const NativeHandle& /*previewSurface*/,
- std::shared_ptr<biometrics::common::ICancellationSignal>*
- /*returnVal*/) {
+ndk::ScopedAStatus Session::enroll(
+ int32_t /*cookie*/, biometrics::face::EnrollmentType /*enrollmentType*/,
+ const keymaster::HardwareAuthToken& /*hat*/, const NativeHandle& /*previewSurface*/,
+ std::shared_ptr<biometrics::common::ICancellationSignal>* /*return_val*/) {
return ndk::ScopedAStatus::ok();
}
@@ -86,9 +87,9 @@
ndk::ScopedAStatus Session::removeEnrollments(int32_t /*cookie*/,
const std::vector<int32_t>& /*enrollmentIds*/) {
if (cb_) {
- cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS);
- cb_->onEnrollmentsRemoved(std::vector<int32_t>());
- cb_->onStateChanged(0, SessionState::IDLING);
+ cb_->onStateChanged(0, SessionState::REMOVING_ENROLLMENTS);
+ cb_->onEnrollmentsRemoved(std::vector<int32_t>());
+ cb_->onStateChanged(0, SessionState::IDLING);
}
return ndk::ScopedAStatus::ok();
}
@@ -115,4 +116,5 @@
}
return ndk::ScopedAStatus::ok();
}
+
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 2bb5c42..347d202 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -35,9 +35,9 @@
ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override;
ndk::ScopedAStatus enroll(
- int32_t cookie, const keymaster::HardwareAuthToken& hat,
- const NativeHandle& previewSurface,
- std::shared_ptr<biometrics::common::ICancellationSignal>* returnVal) override;
+ int32_t cookie, biometrics::face::EnrollmentType enrollmentType,
+ const keymaster::HardwareAuthToken& hat, const NativeHandle& previewSurface,
+ std::shared_ptr<biometrics::common::ICancellationSignal>* return_val) override;
ndk::ScopedAStatus authenticate(
int32_t cookie, int64_t keystoreOperationId,
diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
index f6d0aab..5b02a57 100644
--- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
+++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
@@ -59,7 +59,11 @@
return ndk::ScopedAStatus::ok();
}
- ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
+ ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame& /*frame*/) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame& /*frame*/) override {
return ndk::ScopedAStatus::ok();
}
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index ca57243..ce50f25 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -415,7 +415,7 @@
TEST_P(BroadcastRadioHalTest, FmTune) {
ASSERT_TRUE(openSession());
- uint64_t freq = 100100; // 100.1 FM
+ uint64_t freq = 90900; // 90.9 FM
auto sel = make_selector_amfm(freq);
/* TODO(b/69958777): there is a race condition between tune() and onCurrentProgramInfoChanged
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index d836095..91ca312 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -277,14 +277,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.health.storage</name>
- <version>1.0</version>
- <interface>
- <name>IStorage</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.health.storage</name>
<version>1</version>
@@ -612,6 +604,14 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.weaver</name>
+ <version>1</version>
+ <interface>
+ <name>IWeaver</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.wifi</name>
<version>1.3-5</version>
diff --git a/drm/1.4/IDrmPlugin.hal b/drm/1.4/IDrmPlugin.hal
index 9cc0600..e8af230 100644
--- a/drm/1.4/IDrmPlugin.hal
+++ b/drm/1.4/IDrmPlugin.hal
@@ -15,6 +15,8 @@
*/
package android.hardware.drm@1.4;
+import @1.0::Status;
+import @1.0::SessionId;
import @1.1::SecurityLevel;
import @1.2::IDrmPlugin;
@@ -47,4 +49,16 @@
*/
requiresSecureDecoderDefault(string mime) generates (bool secureRequired);
+ /**
+ * Set playback id of a drm session. The playback id can be used to join drm session metrics
+ * with metrics from other low level media components, e.g. codecs, or metrics from the high
+ * level player.
+ *
+ * @param sessionId drm session id
+ * @param playbackId high level playback id
+ * @return status the status of the call. The status must be OK on success, or
+ * ERROR_DRM_SESSION_NOT_OPENED if the drm session cannot be found
+ */
+ setPlaybackId(SessionId sessionId, string playbackId) generates (@1.0::Status status);
+
};
diff --git a/health/1.0/Android.bp b/health/1.0/Android.bp
index 7845871..7786c08 100644
--- a/health/1.0/Android.bp
+++ b/health/1.0/Android.bp
@@ -5,7 +5,6 @@
root: "android.hardware",
srcs: [
"types.hal",
- "IHealth.hal",
],
interfaces: [
"android.hidl.base@1.0",
diff --git a/health/1.0/IHealth.hal b/health/1.0/IHealth.hal
deleted file mode 100644
index 3828589..0000000
--- a/health/1.0/IHealth.hal
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 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.health@1.0;
-
-interface IHealth {
- /**
- * This function lets you change healthd configuration from default if
- * desired. It must be called exactly once at startup time.
- *
- * The configuration values are described in 'struct HealthConfig'.
- * To use default configuration, simply return without modifying the
- * fields of the config parameter.
- *
- * @param default healthd configuration.
- */
- init(HealthConfig config) generates (HealthConfig configOut);
-
- /**
- * This function is a hook to update/change device's HealthInfo (as described
- * in 'struct HealthInfo').
- *
- * 'HealthInfo' describes device's battery and charging status, typically
- * read from kernel. These values may be modified in this call.
- *
- * @param Device Health info as described in 'struct HealthInfo'.
- * @return skipLogging Indication to the caller to add 'or' skip logging the health
- * information. Return 'true' to skip logging the update.
- * @return infoOut HealthInfo to be sent to client code. (May or may
- * not be modified).
- */
- update(HealthInfo info) generates (bool skipLogging, HealthInfo infoOut);
-
- /**
- * This function is called by healthd when framework queries for remaining
- * energy in the Battery through BatteryManager APIs.
- *
- * @return result Result of querying enery counter for the battery.
- * @return energy Battery remaining energy in nanowatt-hours.
- * Must be '0' if result is anything other than Result::SUCCESS.
- */
- energyCounter() generates (Result result, int64_t energy);
-};
diff --git a/health/1.0/default/include/hal_conversion.h b/health/1.0/default/include/hal_conversion.h
index a92b208..a8ddb73 100644
--- a/health/1.0/default/include/hal_conversion.h
+++ b/health/1.0/default/include/hal_conversion.h
@@ -17,7 +17,7 @@
#ifndef HARDWARE_INTERFACES_HEALTH_V1_0_DEFAULT_INCLUDE_HAL_CONVERSION_H_
#define HARDWARE_INTERFACES_HEALTH_V1_0_DEFAULT_INCLUDE_HAL_CONVERSION_H_
-#include <android/hardware/health/1.0/IHealth.h>
+#include <android/hardware/health/1.0/types.h>
#include <healthd/healthd.h>
namespace android {
diff --git a/oemlock/aidl/vts/OWNERS b/oemlock/aidl/vts/OWNERS
new file mode 100644
index 0000000..40d95e4
--- /dev/null
+++ b/oemlock/aidl/vts/OWNERS
@@ -0,0 +1,2 @@
+chengyouho@google.com
+frankwoo@google.com
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 93a216f..766c02d 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -37,7 +37,7 @@
os << "(Empty)" << ::std::endl;
else {
os << "\n";
- for (size_t i = 0; i < set.size(); ++i) os << set[i] << ::std::endl;
+ for (auto& entry : set) os << entry << ::std::endl;
}
return os;
}
@@ -131,6 +131,17 @@
*key_blob = std::move(creationResult.keyBlob);
*key_characteristics = std::move(creationResult.keyCharacteristics);
cert_chain_ = std::move(creationResult.certificateChain);
+
+ auto algorithm = key_desc.GetTagValue(TAG_ALGORITHM);
+ EXPECT_TRUE(algorithm);
+ if (algorithm &&
+ (algorithm.value() == Algorithm::RSA || algorithm.value() == Algorithm::EC)) {
+ EXPECT_GE(cert_chain_.size(), 1);
+ if (key_desc.Contains(TAG_ATTESTATION_CHALLENGE)) EXPECT_GT(cert_chain_.size(), 1);
+ } else {
+ // For symmetric keys there should be no certificates.
+ EXPECT_EQ(cert_chain_.size(), 0);
+ }
}
return GetReturnErrorCode(result);
@@ -162,6 +173,17 @@
*key_blob = std::move(creationResult.keyBlob);
*key_characteristics = std::move(creationResult.keyCharacteristics);
cert_chain_ = std::move(creationResult.certificateChain);
+
+ auto algorithm = key_desc.GetTagValue(TAG_ALGORITHM);
+ EXPECT_TRUE(algorithm);
+ if (algorithm &&
+ (algorithm.value() == Algorithm::RSA || algorithm.value() == Algorithm::EC)) {
+ EXPECT_GE(cert_chain_.size(), 1);
+ if (key_desc.Contains(TAG_ATTESTATION_CHALLENGE)) EXPECT_GT(cert_chain_.size(), 1);
+ } else {
+ // For symmetric keys there should be no certificates.
+ EXPECT_EQ(cert_chain_.size(), 0);
+ }
}
return GetReturnErrorCode(result);
@@ -195,6 +217,20 @@
key_blob_ = std::move(creationResult.keyBlob);
key_characteristics_ = std::move(creationResult.keyCharacteristics);
cert_chain_ = std::move(creationResult.certificateChain);
+
+ AuthorizationSet allAuths;
+ for (auto& entry : key_characteristics_) {
+ allAuths.push_back(AuthorizationSet(entry.authorizations));
+ }
+ auto algorithm = allAuths.GetTagValue(TAG_ALGORITHM);
+ EXPECT_TRUE(algorithm);
+ if (algorithm &&
+ (algorithm.value() == Algorithm::RSA || algorithm.value() == Algorithm::EC)) {
+ EXPECT_GE(cert_chain_.size(), 1);
+ } else {
+ // For symmetric keys there should be no certificates.
+ EXPECT_EQ(cert_chain_.size(), 0);
+ }
}
return GetReturnErrorCode(result);
@@ -788,6 +824,24 @@
return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
}
+const vector<KeyParameter>& KeyMintAidlTestBase::HwEnforcedAuthorizations(
+ const vector<KeyCharacteristics>& key_characteristics) {
+ auto found =
+ std::find_if(key_characteristics.begin(), key_characteristics.end(), [](auto& entry) {
+ return entry.securityLevel == SecurityLevel::STRONGBOX ||
+ entry.securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT;
+ });
+ return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
+}
+
+const vector<KeyParameter>& KeyMintAidlTestBase::SwEnforcedAuthorizations(
+ const vector<KeyCharacteristics>& key_characteristics) {
+ auto found = std::find_if(
+ key_characteristics.begin(), key_characteristics.end(),
+ [](auto& entry) { return entry.securityLevel == SecurityLevel::SOFTWARE; });
+ return (found == key_characteristics.end()) ? kEmptyAuthList : found->authorizations;
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index f36c397..c1a1dd9 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -27,7 +27,11 @@
#include <keymint_support/authorization_set.h>
-namespace aidl::android::hardware::security::keymint::test {
+namespace aidl::android::hardware::security::keymint {
+
+::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set);
+
+namespace test {
using ::android::sp;
using Status = ::ndk::ScopedAStatus;
@@ -37,8 +41,6 @@
constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF;
-::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set);
-
class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
public:
void SetUp() override;
@@ -173,6 +175,10 @@
inline const vector<KeyParameter>& SecLevelAuthorizations() {
return SecLevelAuthorizations(key_characteristics_);
}
+ const vector<KeyParameter>& HwEnforcedAuthorizations(
+ const vector<KeyCharacteristics>& key_characteristics);
+ const vector<KeyParameter>& SwEnforcedAuthorizations(
+ const vector<KeyCharacteristics>& key_characteristics);
private:
std::shared_ptr<IKeyMintDevice> keymint_;
@@ -190,4 +196,6 @@
testing::ValuesIn(KeyMintAidlTestBase::build_params()), \
::android::PrintInstanceNameToString)
-} // namespace aidl::android::hardware::security::keymint::test
+} // namespace test
+
+} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index bd36b8e..e7c94f3 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -180,9 +180,280 @@
void operator()(RSA* p) { RSA_free(p); }
};
-/* TODO(seleneh) add attestation verification codes like verify_chain() and
- * attestation tests after we decided on the keymint 1 attestation changes.
- */
+char nibble2hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+string bin2hex(const vector<uint8_t>& data) {
+ string retval;
+ retval.reserve(data.size() * 2 + 1);
+ for (uint8_t byte : data) {
+ retval.push_back(nibble2hex[0x0F & (byte >> 4)]);
+ retval.push_back(nibble2hex[0x0F & byte]);
+ }
+ return retval;
+}
+
+X509* parse_cert_blob(const vector<uint8_t>& blob) {
+ const uint8_t* p = blob.data();
+ return d2i_X509(nullptr, &p, blob.size());
+}
+
+bool verify_chain(const vector<Certificate>& chain) {
+ for (size_t i = 0; i < chain.size(); ++i) {
+ X509_Ptr key_cert(parse_cert_blob(chain[i].encodedCertificate));
+ X509_Ptr signing_cert;
+ if (i < chain.size() - 1) {
+ signing_cert.reset(parse_cert_blob(chain[i + 1].encodedCertificate));
+ } else {
+ signing_cert.reset(parse_cert_blob(chain[i].encodedCertificate));
+ }
+ EXPECT_TRUE(!!key_cert.get() && !!signing_cert.get());
+ if (!key_cert.get() || !signing_cert.get()) return false;
+
+ EVP_PKEY_Ptr signing_pubkey(X509_get_pubkey(signing_cert.get()));
+ EXPECT_TRUE(!!signing_pubkey.get());
+ if (!signing_pubkey.get()) return false;
+
+ EXPECT_EQ(1, X509_verify(key_cert.get(), signing_pubkey.get()))
+ << "Verification of certificate " << i << " failed "
+ << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
+
+ char* cert_issuer = //
+ X509_NAME_oneline(X509_get_issuer_name(key_cert.get()), nullptr, 0);
+ char* signer_subj =
+ X509_NAME_oneline(X509_get_subject_name(signing_cert.get()), nullptr, 0);
+ EXPECT_STREQ(cert_issuer, signer_subj) << "Cert " << i << " has wrong issuer.";
+ if (i == 0) {
+ char* cert_sub = X509_NAME_oneline(X509_get_subject_name(key_cert.get()), nullptr, 0);
+ EXPECT_STREQ("/CN=Android Keystore Key", cert_sub)
+ << "Cert " << i << " has wrong subject.";
+ OPENSSL_free(cert_sub);
+ }
+
+ OPENSSL_free(cert_issuer);
+ OPENSSL_free(signer_subj);
+
+ if (dump_Attestations) std::cout << bin2hex(chain[i].encodedCertificate) << std::endl;
+ }
+
+ return true;
+}
+
+// Extract attestation record from cert. Returned object is still part of cert; don't free it
+// separately.
+ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
+ ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
+ EXPECT_TRUE(!!oid.get());
+ if (!oid.get()) return nullptr;
+
+ int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
+ EXPECT_NE(-1, location) << "Attestation extension not found in certificate";
+ if (location == -1) return nullptr;
+
+ X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
+ EXPECT_TRUE(!!attest_rec_ext)
+ << "Found attestation extension but couldn't retrieve it? Probably a BoringSSL bug.";
+ if (!attest_rec_ext) return nullptr;
+
+ ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
+ EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data";
+ return attest_rec;
+}
+
+bool tag_in_list(const KeyParameter& entry) {
+ // Attestations don't contain everything in key authorization lists, so we need to filter
+ // the key lists to produce the lists that we expect to match the attestations.
+ auto tag_list = {
+ Tag::BLOB_USAGE_REQUIREMENTS, //
+ Tag::CREATION_DATETIME, //
+ Tag::EC_CURVE,
+ Tag::HARDWARE_TYPE,
+ Tag::INCLUDE_UNIQUE_ID,
+ };
+ return std::find(tag_list.begin(), tag_list.end(), entry.tag) != tag_list.end();
+}
+
+AuthorizationSet filtered_tags(const AuthorizationSet& set) {
+ AuthorizationSet filtered;
+ std::remove_copy_if(set.begin(), set.end(), std::back_inserter(filtered), tag_in_list);
+ return filtered;
+}
+
+bool avb_verification_enabled() {
+ char value[PROPERTY_VALUE_MAX];
+ return property_get("ro.boot.vbmeta.device_state", value, "") != 0;
+}
+
+bool verify_attestation_record(const string& challenge, //
+ const string& app_id, //
+ AuthorizationSet expected_sw_enforced, //
+ AuthorizationSet expected_hw_enforced, //
+ SecurityLevel security_level,
+ const vector<uint8_t>& attestation_cert) {
+ X509_Ptr cert(parse_cert_blob(attestation_cert));
+ EXPECT_TRUE(!!cert.get());
+ if (!cert.get()) return false;
+
+ ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+ EXPECT_TRUE(!!attest_rec);
+ if (!attest_rec) return false;
+
+ AuthorizationSet att_sw_enforced;
+ AuthorizationSet att_hw_enforced;
+ uint32_t att_attestation_version;
+ uint32_t att_keymaster_version;
+ SecurityLevel att_attestation_security_level;
+ SecurityLevel att_keymaster_security_level;
+ vector<uint8_t> att_challenge;
+ vector<uint8_t> att_unique_id;
+ vector<uint8_t> att_app_id;
+
+ auto error = parse_attestation_record(attest_rec->data, //
+ attest_rec->length, //
+ &att_attestation_version, //
+ &att_attestation_security_level, //
+ &att_keymaster_version, //
+ &att_keymaster_security_level, //
+ &att_challenge, //
+ &att_sw_enforced, //
+ &att_hw_enforced, //
+ &att_unique_id);
+ EXPECT_EQ(ErrorCode::OK, error);
+ if (error != ErrorCode::OK) return false;
+
+ EXPECT_GE(att_attestation_version, 3U);
+
+ expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID,
+ vector<uint8_t>(app_id.begin(), app_id.end()));
+
+ EXPECT_GE(att_keymaster_version, 4U);
+ EXPECT_EQ(security_level, att_keymaster_security_level);
+ EXPECT_EQ(security_level, att_attestation_security_level);
+
+ EXPECT_EQ(challenge.length(), att_challenge.size());
+ EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length()));
+
+ char property_value[PROPERTY_VALUE_MAX] = {};
+ // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
+ // keymaster implementation will report YYYYMM dates instead of YYYYMMDD
+ // for the BOOT_PATCH_LEVEL.
+ if (avb_verification_enabled()) {
+ for (int i = 0; i < att_hw_enforced.size(); i++) {
+ if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
+ att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
+ std::string date =
+ std::to_string(att_hw_enforced[i].value.get<KeyParameterValue::dateTime>());
+ // strptime seems to require delimiters, but the tag value will
+ // be YYYYMMDD
+ date.insert(6, "-");
+ date.insert(4, "-");
+ EXPECT_EQ(date.size(), 10);
+ struct tm time;
+ strptime(date.c_str(), "%Y-%m-%d", &time);
+
+ // Day of the month (0-31)
+ EXPECT_GE(time.tm_mday, 0);
+ EXPECT_LT(time.tm_mday, 32);
+ // Months since Jan (0-11)
+ EXPECT_GE(time.tm_mon, 0);
+ EXPECT_LT(time.tm_mon, 12);
+ // Years since 1900
+ EXPECT_GT(time.tm_year, 110);
+ EXPECT_LT(time.tm_year, 200);
+ }
+ }
+ }
+
+ // Check to make sure boolean values are properly encoded. Presence of a boolean tag indicates
+ // true. A provided boolean tag that can be pulled back out of the certificate indicates correct
+ // encoding. No need to check if it's in both lists, since the AuthorizationSet compare below
+ // will handle mismatches of tags.
+ if (security_level == SecurityLevel::SOFTWARE) {
+ EXPECT_TRUE(expected_sw_enforced.Contains(TAG_NO_AUTH_REQUIRED));
+ } else {
+ EXPECT_TRUE(expected_hw_enforced.Contains(TAG_NO_AUTH_REQUIRED));
+ }
+
+ // Alternatively this checks the opposite - a false boolean tag (one that isn't provided in
+ // the authorization list during key generation) isn't being attested to in the certificate.
+ EXPECT_FALSE(expected_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
+ EXPECT_FALSE(att_sw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
+ EXPECT_FALSE(expected_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
+ EXPECT_FALSE(att_hw_enforced.Contains(TAG_TRUSTED_USER_PRESENCE_REQUIRED));
+
+ if (att_hw_enforced.Contains(TAG_ALGORITHM, Algorithm::EC)) {
+ // For ECDSA keys, either an EC_CURVE or a KEY_SIZE can be specified, but one must be.
+ EXPECT_TRUE(att_hw_enforced.Contains(TAG_EC_CURVE) ||
+ att_hw_enforced.Contains(TAG_KEY_SIZE));
+ }
+
+ // Test root of trust elements
+ vector<uint8_t> verified_boot_key;
+ VerifiedBoot verified_boot_state;
+ bool device_locked;
+ vector<uint8_t> verified_boot_hash;
+ error = parse_root_of_trust(attest_rec->data, attest_rec->length, &verified_boot_key,
+ &verified_boot_state, &device_locked, &verified_boot_hash);
+ EXPECT_EQ(ErrorCode::OK, error);
+
+ if (avb_verification_enabled()) {
+ EXPECT_NE(property_get("ro.boot.vbmeta.digest", property_value, ""), 0);
+ string prop_string(property_value);
+ EXPECT_EQ(prop_string.size(), 64);
+ EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
+
+ EXPECT_NE(property_get("ro.boot.vbmeta.device_state", property_value, ""), 0);
+ if (!strcmp(property_value, "unlocked")) {
+ EXPECT_FALSE(device_locked);
+ } else {
+ EXPECT_TRUE(device_locked);
+ }
+
+ // Check that the device is locked if not debuggable, e.g., user build
+ // images in CTS. For VTS, debuggable images are used to allow adb root
+ // and the device is unlocked.
+ if (!property_get_bool("ro.debuggable", false)) {
+ EXPECT_TRUE(device_locked);
+ } else {
+ EXPECT_FALSE(device_locked);
+ }
+ }
+
+ // Verified boot key should be all 0's if the boot state is not verified or self signed
+ std::string empty_boot_key(32, '\0');
+ std::string verified_boot_key_str((const char*)verified_boot_key.data(),
+ verified_boot_key.size());
+ EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
+ if (!strcmp(property_value, "green")) {
+ EXPECT_EQ(verified_boot_state, VerifiedBoot::VERIFIED);
+ EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+ verified_boot_key.size()));
+ } else if (!strcmp(property_value, "yellow")) {
+ EXPECT_EQ(verified_boot_state, VerifiedBoot::SELF_SIGNED);
+ EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+ verified_boot_key.size()));
+ } else if (!strcmp(property_value, "orange")) {
+ EXPECT_EQ(verified_boot_state, VerifiedBoot::UNVERIFIED);
+ EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+ verified_boot_key.size()));
+ } else if (!strcmp(property_value, "red")) {
+ EXPECT_EQ(verified_boot_state, VerifiedBoot::FAILED);
+ } else {
+ EXPECT_EQ(verified_boot_state, VerifiedBoot::UNVERIFIED);
+ EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+ verified_boot_key.size()));
+ }
+
+ att_sw_enforced.Sort();
+ expected_sw_enforced.Sort();
+ EXPECT_EQ(filtered_tags(expected_sw_enforced), filtered_tags(att_sw_enforced));
+
+ att_hw_enforced.Sort();
+ expected_hw_enforced.Sort();
+ EXPECT_EQ(filtered_tags(expected_hw_enforced), filtered_tags(att_hw_enforced));
+
+ return true;
+}
std::string make_string(const uint8_t* data, size_t length) {
return std::string(reinterpret_cast<const char*>(data), length);
@@ -289,6 +560,51 @@
}
/*
+ * NewKeyGenerationTest.Rsa
+ *
+ * Verifies that keymint can generate all required RSA key sizes, and that the resulting keys
+ * have correct characteristics.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithAttestation) {
+ for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+ auto challenge = "hello";
+ auto app_id = "foo";
+
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED),
+ &key_blob, &key_characteristics));
+
+ ASSERT_GT(key_blob.size(), 0U);
+ CheckBaseParams(key_characteristics);
+
+ AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+ EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
+ EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+ << "Key size " << key_size << "missing";
+ EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+ EXPECT_TRUE(verify_chain(cert_chain_));
+ ASSERT_GT(cert_chain_.size(), 0);
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+ EXPECT_TRUE(verify_attestation_record(challenge, app_id, //
+ sw_enforced, hw_enforced, SecLevel(),
+ cert_chain_[0].encodedCertificate));
+
+ CheckedDeleteKey(&key_blob);
+ }
+}
+
+/*
* NewKeyGenerationTest.NoInvalidRsaSizes
*
* Verifies that keymint cannot generate any RSA key sizes that are designated as invalid.
@@ -3895,16 +4211,6 @@
INSTANTIATE_KEYMINT_AIDL_TEST(AddEntropyTest);
-typedef KeyMintAidlTestBase AttestationTest;
-
-/*
- * AttestationTest.RsaAttestation
- *
- * Verifies that attesting to RSA keys works and generates the expected output.
- */
-// TODO(seleneh) add attestation tests back after decided on the new attestation
-// behavior under generateKey and importKey
-
typedef KeyMintAidlTestBase KeyDeletionTest;
/**
diff --git a/security/keymint/support/include/keymint_support/authorization_set.h b/security/keymint/support/include/keymint_support/authorization_set.h
index 596bb89..1407c5f 100644
--- a/security/keymint/support/include/keymint_support/authorization_set.h
+++ b/security/keymint/support/include/keymint_support/authorization_set.h
@@ -259,6 +259,12 @@
size - 1); // drop the terminating '\0'
}
+ template <Tag tag>
+ AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag,
+ const std::string& data) {
+ return Authorization(ttag, reinterpret_cast<const uint8_t*>(data.data()), data.size());
+ }
+
AuthorizationSetBuilder& Authorizations(const AuthorizationSet& set) {
for (const auto& entry : set) {
push_back(entry);
@@ -294,6 +300,20 @@
AuthorizationSetBuilder& Digest(std::vector<Digest> digests);
AuthorizationSetBuilder& Padding(std::initializer_list<PaddingMode> paddings);
+ AuthorizationSetBuilder& AttestationChallenge(const std::string& challenge) {
+ return Authorization(TAG_ATTESTATION_CHALLENGE, challenge);
+ }
+ AuthorizationSetBuilder& AttestationChallenge(std::vector<uint8_t> challenge) {
+ return Authorization(TAG_ATTESTATION_CHALLENGE, challenge);
+ }
+
+ AuthorizationSetBuilder& AttestationApplicationId(const std::string& id) {
+ return Authorization(TAG_ATTESTATION_APPLICATION_ID, id);
+ }
+ AuthorizationSetBuilder& AttestationApplicationId(std::vector<uint8_t> id) {
+ return Authorization(TAG_ATTESTATION_APPLICATION_ID, id);
+ }
+
template <typename... T>
AuthorizationSetBuilder& BlockMode(T&&... a) {
return BlockMode({std::forward<T>(a)...});
diff --git a/tests/lazy/1.1/ILazy.hal b/tests/lazy/1.1/ILazy.hal
index b0a6a2a..eb48fd3 100644
--- a/tests/lazy/1.1/ILazy.hal
+++ b/tests/lazy/1.1/ILazy.hal
@@ -20,10 +20,10 @@
interface ILazy extends @1.0::ILazy {
/**
- * Ask the process hosting the service to install a callback that notifies
- * it when the number of active (i.e. with clients) services changes.
+ * Ask the process hosting the service to install a callback that notifies if there are
+ * services with clients.
* For testing purposes, this callback exercises the code to unregister/re-register
* the services and eventually shuts down the process.
*/
- setCustomActiveServicesCountCallback();
+ setCustomActiveServicesCallback();
};
diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp
new file mode 100644
index 0000000..5637e0a
--- /dev/null
+++ b/weaver/aidl/Android.bp
@@ -0,0 +1,16 @@
+aidl_interface {
+ name: "android.hardware.weaver",
+ vendor_available: true,
+ srcs: ["android/hardware/weaver/*.aidl"],
+ stability: "vintf",
+ backend: {
+ java: {
+ platform_apis: true,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/IWeaver.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/IWeaver.aidl
new file mode 100644
index 0000000..29bd9a9
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/IWeaver.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 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.weaver;
+@VintfStability
+interface IWeaver {
+ android.hardware.weaver.WeaverConfig getConfig();
+ android.hardware.weaver.WeaverReadResponse read(in int slotId, in byte[] key);
+ void write(in int slotId, in byte[] key, in byte[] value);
+ const int STATUS_FAILED = 1;
+ const int INCORRECT_KEY = 2;
+ const int THROTTLE = 3;
+}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverConfig.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverConfig.aidl
new file mode 100644
index 0000000..239cdac
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 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.weaver;
+@VintfStability
+parcelable WeaverConfig {
+ long slots;
+ long keySize;
+ long valueSize;
+}
diff --git a/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
new file mode 100644
index 0000000..7e5db59
--- /dev/null
+++ b/weaver/aidl/aidl_api/android.hardware.weaver/current/android/hardware/weaver/WeaverReadResponse.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020 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.weaver;
+@VintfStability
+parcelable WeaverReadResponse {
+ long timeout;
+ byte[] value;
+}
diff --git a/weaver/aidl/android/hardware/weaver/IWeaver.aidl b/weaver/aidl/android/hardware/weaver/IWeaver.aidl
new file mode 100644
index 0000000..ebbfabe
--- /dev/null
+++ b/weaver/aidl/android/hardware/weaver/IWeaver.aidl
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020 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.weaver;
+
+import android.hardware.weaver.WeaverConfig;
+import android.hardware.weaver.WeaverReadResponse;
+
+/**
+ * Weaver provides secure storage of secret values that may only be read if the
+ * corresponding key has been presented.
+ *
+ * The storage must be secure as the device's user authentication and encryption
+ * relies on the security of these values. The cardinality of the domains of the
+ * key and value must be suitably large such that they cannot be easily guessed.
+ *
+ * Weaver is structured as an array of slots, each containing a key-value pair.
+ * Slots are uniquely identified by an ID in the range [0, `getConfig().slots`).
+ */
+@VintfStability
+interface IWeaver {
+ /**
+ * Retrieves the config information for this implementation of Weaver.
+ *
+ * The config is static i.e. every invocation returns the same information.
+ *
+ * @return config data for this implementation of Weaver if status is OK,
+ * otherwise undefined.
+ */
+ WeaverConfig getConfig();
+
+ /**
+ * Read binder calls may return a ServiceSpecificException with the following error codes.
+ */
+ const int STATUS_FAILED = 1;
+ const int INCORRECT_KEY = 2;
+ const int THROTTLE = 3;
+
+ /**
+ * Attempts to retrieve the value stored in the identified slot.
+ *
+ * The value is only returned if the provided key matches the key stored in
+ * the slot. The value is never returned if the wrong key is provided.
+ *
+ * Throttling must be used to limit the frequency of failed read attempts.
+ * The value is only returned when throttling is not active, even if the
+ * correct key is provided. If called when throttling is active, the time
+ * until the next attempt can be made is returned.
+ *
+ * Service status return:
+ *
+ * OK if the value was successfully read from slot.
+ * INCORRECT_KEY if the key does not match the key in the slot.
+ * THROTTLE if throttling is active.
+ * STATUS_FAILED if the read was unsuccessful for another reason.
+ *
+ * @param slotId of the slot to read from, this must be positive to be valid.
+ * @param key that is stored in the slot.
+ * @return The WeaverReadResponse for this read request. If the status is OK,
+ * value is set to the value in the slot and timeout is 0. Otherwise, value is
+ * empty and timeout is set accordingly.
+ */
+ WeaverReadResponse read(in int slotId, in byte[] key);
+
+ /**
+ * Overwrites the identified slot with the provided key and value.
+ *
+ * The new values are written regardless of the current state of the slot in
+ * order to remain idempotent.
+ *
+ * Service status return:
+ *
+ * OK if the write was successfully completed.
+ * FAILED if the write was unsuccessful.
+ *
+ * @param slotId of the slot to write to.
+ * @param key to write to the slot.
+ * @param value to write to slot.
+ */
+ void write(in int slotId, in byte[] key, in byte[] value);
+}
diff --git a/weaver/aidl/android/hardware/weaver/WeaverConfig.aidl b/weaver/aidl/android/hardware/weaver/WeaverConfig.aidl
new file mode 100644
index 0000000..75d961e
--- /dev/null
+++ b/weaver/aidl/android/hardware/weaver/WeaverConfig.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 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.weaver;
+
+@VintfStability
+parcelable WeaverConfig {
+ /**
+ * The number of slots available.
+ */
+ long slots;
+ /**
+ * The number of bytes used for a key.
+ */
+ long keySize;
+ /**
+ * The number of bytes used for a value.
+ */
+ long valueSize;
+}
+
diff --git a/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
new file mode 100644
index 0000000..ec006e8
--- /dev/null
+++ b/weaver/aidl/android/hardware/weaver/WeaverReadResponse.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2020 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.weaver;
+
+@VintfStability
+parcelable WeaverReadResponse {
+ /**
+ * The time to wait, in milliseconds, before making the next request.
+ */
+ long timeout;
+ /**
+ * The value read from the slot or empty if the value was not read.
+ */
+ byte[] value;
+}
+
diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp
new file mode 100644
index 0000000..d936828
--- /dev/null
+++ b/weaver/aidl/default/Android.bp
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2020 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.
+//
+
+cc_binary {
+ name: "android.hardware.weaver-service.example",
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.weaver-service.example.rc"],
+ vintf_fragments: ["android.hardware.weaver-service.example.xml"],
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "Weaver.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.weaver-ndk_platform",
+ "libbase",
+ "libbinder_ndk",
+ ],
+}
diff --git a/weaver/aidl/default/Weaver.cpp b/weaver/aidl/default/Weaver.cpp
new file mode 100644
index 0000000..56d9c4d
--- /dev/null
+++ b/weaver/aidl/default/Weaver.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Weaver.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace weaver {
+
+// Methods from ::android::hardware::weaver::IWeaver follow.
+
+::ndk::ScopedAStatus Weaver::getConfig(WeaverConfig* out_config) {
+ (void)out_config;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Weaver::read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* out_response) {
+ (void)in_slotId;
+ (void)in_key;
+ (void)out_response;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Weaver::write(int32_t in_slotId, const std::vector<uint8_t>& in_key, const std::vector<uint8_t>& in_value) {
+ (void)in_slotId;
+ (void)in_key;
+ (void)in_value;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} //namespace weaver
+} //namespace hardware
+} //namespace android
+} //namespace aidl
diff --git a/weaver/aidl/default/Weaver.h b/weaver/aidl/default/Weaver.h
new file mode 100644
index 0000000..b50018e
--- /dev/null
+++ b/weaver/aidl/default/Weaver.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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/weaver/BnWeaver.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace weaver {
+
+using ::aidl::android::hardware::weaver::WeaverConfig;
+using ::aidl::android::hardware::weaver::WeaverReadResponse;
+
+struct Weaver : public BnWeaver {
+public:
+ Weaver() = default;
+
+ // Methods from ::android::hardware::weaver::IWeaver follow.
+ ::ndk::ScopedAStatus getConfig(WeaverConfig* _aidl_return) override;
+ ::ndk::ScopedAStatus read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* _aidl_return) override;
+ ::ndk::ScopedAStatus write(int32_t in_slotId, const std::vector<uint8_t>& in_key, const std::vector<uint8_t>& in_value) override;
+};
+
+} // namespace weaver
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/weaver/aidl/default/android.hardware.weaver-service.example.rc b/weaver/aidl/default/android.hardware.weaver-service.example.rc
new file mode 100644
index 0000000..ec77774
--- /dev/null
+++ b/weaver/aidl/default/android.hardware.weaver-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.weaver_default /vendor/bin/hw/android.hardware.weaver-service.example
+ class hal
+ user hsm
+ group hsm
diff --git a/weaver/aidl/default/android.hardware.weaver-service.example.xml b/weaver/aidl/default/android.hardware.weaver-service.example.xml
new file mode 100644
index 0000000..ed291cd
--- /dev/null
+++ b/weaver/aidl/default/android.hardware.weaver-service.example.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.weaver</name>
+ <version>1</version>
+ <interface>
+ <name>IWeaver</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/weaver/aidl/default/service.cpp b/weaver/aidl/default/service.cpp
new file mode 100644
index 0000000..1495bc9
--- /dev/null
+++ b/weaver/aidl/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "Weaver.h"
+
+using ::aidl::android::hardware::weaver::Weaver;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ std::shared_ptr<Weaver> weaver = ndk::SharedRefBase::make<Weaver>();
+
+ const std::string instance = std::string() + Weaver::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(weaver->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return -1; // Should never be reached
+}
diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp
new file mode 100644
index 0000000..d7e3ab7
--- /dev/null
+++ b/weaver/aidl/vts/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2020 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.
+//
+
+cc_test {
+ name: "VtsHalWeaverTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalWeaverTargetTest.cpp"],
+ shared_libs: [
+ "libbinder_ndk",
+ "libbase",
+ ],
+ static_libs: ["android.hardware.weaver-ndk_platform"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/weaver/aidl/vts/OWNERS b/weaver/aidl/vts/OWNERS
new file mode 100644
index 0000000..40d95e4
--- /dev/null
+++ b/weaver/aidl/vts/OWNERS
@@ -0,0 +1,2 @@
+chengyouho@google.com
+frankwoo@google.com
diff --git a/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp b/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp
new file mode 100644
index 0000000..7d8daa2
--- /dev/null
+++ b/weaver/aidl/vts/VtsHalWeaverTargetTest.cpp
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/weaver/IWeaver.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include <limits>
+
+using ::aidl::android::hardware::weaver::IWeaver;
+using ::aidl::android::hardware::weaver::WeaverConfig;
+using ::aidl::android::hardware::weaver::WeaverReadResponse;
+
+using ::ndk::SpAIBinder;
+
+const std::vector<uint8_t> KEY{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+const std::vector<uint8_t> WRONG_KEY{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
+const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
+
+struct WeaverAidlTest : public ::testing::TestWithParam<std::string> {
+ virtual void SetUp() override {
+ weaver = IWeaver::fromBinder(
+ SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(weaver, nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ std::shared_ptr<IWeaver> weaver;
+};
+
+/*
+ * Checks config values are suitably large
+ */
+TEST_P(WeaverAidlTest, GetConfig) {
+ WeaverConfig config;
+
+ auto ret = weaver->getConfig(&config);
+
+ ASSERT_TRUE(ret.isOk());
+
+ EXPECT_GE(config.slots, 16u);
+ EXPECT_GE(config.keySize, 16u);
+ EXPECT_GE(config.valueSize, 16u);
+}
+
+/*
+ * Gets the config twice and checks they are the same
+ */
+TEST_P(WeaverAidlTest, GettingConfigMultipleTimesGivesSameResult) {
+ WeaverConfig config1;
+ WeaverConfig config2;
+
+ auto ret = weaver->getConfig(&config1);
+ ASSERT_TRUE(ret.isOk());
+
+ ret = weaver->getConfig(&config2);
+ ASSERT_TRUE(ret.isOk());
+
+ EXPECT_EQ(config1, config2);
+}
+
+/*
+ * Gets the number of slots from the config and writes a key and value to the last one
+ */
+TEST_P(WeaverAidlTest, WriteToLastSlot) {
+ WeaverConfig config;
+ const auto configRet = weaver->getConfig(&config);
+
+ ASSERT_TRUE(configRet.isOk());
+
+ const uint32_t lastSlot = config.slots - 1;
+ const auto writeRet = weaver->write(lastSlot, KEY, VALUE);
+ ASSERT_TRUE(writeRet.isOk());
+}
+
+/*
+ * Writes a key and value to a slot
+ * Reads the slot with the same key and receives the value that was previously written
+ */
+TEST_P(WeaverAidlTest, WriteFollowedByReadGivesTheSameValue) {
+ constexpr uint32_t slotId = 0;
+ const auto ret = weaver->write(slotId, KEY, VALUE);
+ ASSERT_TRUE(ret.isOk());
+
+ WeaverReadResponse response;
+ std::vector<uint8_t> readValue;
+ uint32_t timeout;
+ const auto readRet = weaver->read(slotId, KEY, &response);
+
+ readValue = response.value;
+ timeout = response.timeout;
+
+ ASSERT_TRUE(readRet.isOk());
+ EXPECT_EQ(readValue, VALUE);
+ EXPECT_EQ(timeout, 0u);
+}
+
+/*
+ * Writes a key and value to a slot
+ * Overwrites the slot with a new key and value
+ * Reads the slot with the new key and receives the new value
+ */
+TEST_P(WeaverAidlTest, OverwritingSlotUpdatesTheValue) {
+ constexpr uint32_t slotId = 0;
+ const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE);
+ ASSERT_TRUE(initialWriteRet.isOk());
+
+ const auto overwriteRet = weaver->write(slotId, KEY, OTHER_VALUE);
+ ASSERT_TRUE(overwriteRet.isOk());
+
+ WeaverReadResponse response;
+ std::vector<uint8_t> readValue;
+ uint32_t timeout;
+ const auto readRet = weaver->read(slotId, KEY, &response);
+
+ readValue = response.value;
+ timeout = response.timeout;
+
+ ASSERT_TRUE(readRet.isOk());
+ EXPECT_EQ(readValue, OTHER_VALUE);
+ EXPECT_EQ(timeout, 0u);
+}
+
+/*
+ * Writes a key and value to a slot
+ * Reads the slot with a different key so does not receive the value
+ */
+TEST_P(WeaverAidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
+ constexpr uint32_t slotId = 0;
+ const auto ret = weaver->write(slotId, KEY, VALUE);
+ ASSERT_TRUE(ret.isOk());
+
+ WeaverReadResponse response;
+ std::vector<uint8_t> readValue;
+ const auto readRet =
+ weaver->read(slotId, WRONG_KEY, &response);
+
+ readValue = response.value;
+
+ ASSERT_FALSE(readRet.isOk());
+ ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
+ ASSERT_EQ(IWeaver::INCORRECT_KEY, readRet.getServiceSpecificError());
+ EXPECT_TRUE(readValue.empty());
+}
+
+/*
+ * Writing to an invalid slot fails
+ */
+TEST_P(WeaverAidlTest, WritingToInvalidSlotFails) {
+ WeaverConfig config;
+ const auto configRet = weaver->getConfig(&config);
+ ASSERT_TRUE(configRet.isOk());
+
+ if (config.slots == std::numeric_limits<uint32_t>::max()) {
+ // If there are no invalid slots then pass
+ return;
+ }
+
+ const auto writeRet = weaver->write(config.slots, KEY, VALUE);
+ ASSERT_FALSE(writeRet.isOk());
+}
+
+/*
+ * Reading from an invalid slot fails rather than incorrect key
+ */
+TEST_P(WeaverAidlTest, ReadingFromInvalidSlotFails) {
+ WeaverConfig config;
+ const auto configRet = weaver->getConfig(&config);
+ ASSERT_TRUE(configRet.isOk());
+
+ if (config.slots == std::numeric_limits<uint32_t>::max()) {
+ // If there are no invalid slots then pass
+ return;
+ }
+
+ WeaverReadResponse response;
+ std::vector<uint8_t> readValue;
+ uint32_t timeout;
+ const auto readRet =
+ weaver->read(config.slots, KEY, &response);
+
+ readValue = response.value;
+ timeout = response.timeout;
+
+ ASSERT_FALSE(readRet.isOk());
+ ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
+ ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
+ EXPECT_TRUE(readValue.empty());
+ EXPECT_EQ(timeout, 0u);
+}
+
+/*
+ * Writing a key that is too large fails
+ */
+TEST_P(WeaverAidlTest, WriteWithTooLargeKeyFails) {
+ WeaverConfig config;
+ const auto configRet = weaver->getConfig(&config);
+ ASSERT_TRUE(configRet.isOk());
+
+ std::vector<uint8_t> bigKey(config.keySize + 1);
+
+ constexpr uint32_t slotId = 0;
+ const auto writeRet = weaver->write(slotId, bigKey, VALUE);
+ ASSERT_FALSE(writeRet.isOk());
+}
+
+/*
+ * Writing a value that is too large fails
+ */
+TEST_P(WeaverAidlTest, WriteWithTooLargeValueFails) {
+ WeaverConfig config;
+ const auto configRet = weaver->getConfig(&config);
+ ASSERT_TRUE(configRet.isOk());
+
+ std::vector<uint8_t> bigValue(config.valueSize + 1);
+
+ constexpr uint32_t slotId = 0;
+ const auto writeRet = weaver->write(slotId, KEY, bigValue);
+ ASSERT_FALSE(writeRet.isOk());
+}
+
+/*
+ * Reading with a key that is loo large fails
+ */
+TEST_P(WeaverAidlTest, ReadWithTooLargeKeyFails) {
+ WeaverConfig config;
+ const auto configRet = weaver->getConfig(&config);
+ ASSERT_TRUE(configRet.isOk());
+
+ std::vector<uint8_t> bigKey(config.keySize + 1);
+
+ constexpr uint32_t slotId = 0;
+ WeaverReadResponse response;
+ std::vector<uint8_t> readValue;
+ uint32_t timeout;
+ const auto readRet =
+ weaver->read(slotId, bigKey, &response);
+
+ readValue = response.value;
+ timeout = response.timeout;
+
+ ASSERT_FALSE(readRet.isOk());
+ ASSERT_EQ(EX_SERVICE_SPECIFIC, readRet.getExceptionCode());
+ ASSERT_EQ(IWeaver::STATUS_FAILED, readRet.getServiceSpecificError());
+ EXPECT_TRUE(readValue.empty());
+ EXPECT_EQ(timeout, 0u);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WeaverAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WeaverAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IWeaver::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}