Merge "Remove AIDL-libs from VNDK"
diff --git a/automotive/OWNERS b/automotive/OWNERS
index 43c5f3e..09e257c 100644
--- a/automotive/OWNERS
+++ b/automotive/OWNERS
@@ -1,6 +1 @@
-pirozzoj@google.com
-twasilczyk@google.com
-krachuri@google.com
-gurunagarajan@google.com
-keunyoung@google.com
-felipeal@google.com
+include platform/packages/services/Car:/OWNERS
diff --git a/automotive/audiocontrol/OWNERS b/automotive/audiocontrol/OWNERS
new file mode 100644
index 0000000..f55eff3
--- /dev/null
+++ b/automotive/audiocontrol/OWNERS
@@ -0,0 +1 @@
+oscarazu@google.com
diff --git a/automotive/can/OWNERS b/automotive/can/OWNERS
new file mode 100644
index 0000000..ffa4828
--- /dev/null
+++ b/automotive/can/OWNERS
@@ -0,0 +1,3 @@
+kevinme@google.com
+chrisweir@google.com
+twasilczyk@google.com
diff --git a/automotive/sv/OWNERS b/automotive/sv/OWNERS
new file mode 100644
index 0000000..af6788b
--- /dev/null
+++ b/automotive/sv/OWNERS
@@ -0,0 +1 @@
+tanmayp@google.com
diff --git a/automotive/vehicle/README.md b/automotive/vehicle/README.md
new file mode 100644
index 0000000..e0f03e2
--- /dev/null
+++ b/automotive/vehicle/README.md
@@ -0,0 +1,26 @@
+# Vehicle Hardware Abstraction Layer (VHAL)
+---
+
+This directory stores the VHAL interface definition and VHAL reference
+implementation.
+
+## 2.0 (deprecated)
+
+HIDL based VHAL interface and reference implementation.
+
+## aidl
+
+AIDL based VHAL interfadce and reference implementation.
+
+## proto
+
+Protobuf used to pass message between emulator VHAL and emulator.
+
+## tools
+
+Dev tools related to VHAL.
+
+## vts
+
+VTS test for VHAL. The VTS test works for both AIDL and HIDL VHAL
+implementation. Vendor implementation of VHAL must passes VTS.
diff --git a/automotive/vehicle/aidl/README.md b/automotive/vehicle/aidl/README.md
new file mode 100644
index 0000000..09f03b4
--- /dev/null
+++ b/automotive/vehicle/aidl/README.md
@@ -0,0 +1,23 @@
+# AIDL Vehicle Hardware Abstraction Layer (VHAL)
+---
+
+This directory stores the AIDL VHAL interface and reference implementation.
+
+## aidl_api
+
+Auto-generated current and previous versions of AIDL VHAL api.
+
+## aidl_test
+
+Contains a test to test that all HIDL VHAL properties are supported in
+AIDL VHAL.
+
+## android
+
+Contains AIDL VHAL interface definition. The main interface file is
+`android/hardware/automotive/vehicle/IVehicle.aidl`.
+
+## impl
+
+Reference implementation for AIDL VHAL and useful libraries for implementing
+vendor AIDL VHAL.
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
new file mode 100644
index 0000000..0d3a061
--- /dev/null
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum GsrComplianceRequirementType {
+ GSR_COMPLIANCE_NOT_REQUIRED = 0,
+ GSR_COMPLIANCE_REQUIRED_THROUGH_SYSTEM_IMAGE = 1,
+}
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 04f8fa3..2d0cde5 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -206,4 +206,5 @@
EV_REGENERATIVE_BRAKING_STATE = 289410884,
TRAILER_PRESENT = 289410885,
VEHICLE_CURB_WEIGHT = 289410886,
+ GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = 289410887,
}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
new file mode 100644
index 0000000..e0609d5
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/GsrComplianceRequirementType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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.automotive.vehicle;
+
+/**
+ * Used by GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT to indicate what
+ * kind of general safety regulation compliance requirement is enforced.
+ */
+@VintfStability
+@Backing(type="int")
+enum GsrComplianceRequirementType {
+ /**
+ * GSR compliance is not required.
+ */
+ GSR_COMPLIANCE_NOT_REQUIRED = 0,
+ /**
+ * GSR compliance is required through system image.
+ */
+ GSR_COMPLIANCE_REQUIRED_THROUGH_SYSTEM_IMAGE = 1,
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 727b949..15d8e58 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -2840,4 +2840,17 @@
VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
+ 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+ /**
+ * EU's General security regulation compliance requirement.
+ *
+ * Returns whether general security regulation compliance is required, if
+ * so, what type of requirement.
+ *
+ * @change_mode VehiclePropertyChangeMode:STATIC
+ * @access VehiclePropertyAccess:READ
+ * @data_enum GsrComplianceRequirementType
+ */
+ GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = 0x0F47 + 0x10000000 + 0x01000000
+ + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+
}
diff --git a/automotive/vehicle/aidl/impl/Android.bp b/automotive/vehicle/aidl/impl/Android.bp
index d24a739..196f431 100644
--- a/automotive/vehicle/aidl/impl/Android.bp
+++ b/automotive/vehicle/aidl/impl/Android.bp
@@ -19,10 +19,16 @@
}
cc_defaults {
+ name: "VehicleHalInterfaceDefaults",
+ static_libs: [
+ "android.hardware.automotive.vehicle-V1-ndk",
+ ],
+}
+
+cc_defaults {
name: "VehicleHalDefaults",
static_libs: [
"android-automotive-large-parcelable-lib",
- "android.hardware.automotive.vehicle-V1-ndk",
"libmath",
],
shared_libs: [
@@ -37,6 +43,7 @@
"-Wthread-safety",
],
defaults: [
+ "VehicleHalInterfaceDefaults",
"android-automotive-large-parcelable-defaults",
],
}
diff --git a/automotive/vehicle/aidl/impl/README.md b/automotive/vehicle/aidl/impl/README.md
new file mode 100644
index 0000000..121ffd1
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/README.md
@@ -0,0 +1,58 @@
+# AIDL VHAL libraries and reference implementation.
+---
+
+This directory stores the libraries useful for implementing vendor AIDL VHAL.
+This directory also stores a reference fake implementation for AIDL VHAL.
+
+## default_config
+
+Stores the default vehicle property configurations for reference vehicle HAL.
+Vendor implementation could copy this library but must update the configuration
+to meet their own requirements, e.g. enable or disable certain properties or
+update the initial value for certain properties.
+
+## fake_impl
+
+Contains libraries used specifically for the fake reference VHAL implementation.
+These libraries are for test only and must not be directly used for vendor
+VHAL implementation.
+
+These libraries contain test-spcific logic and must not run directly on a real
+vehicle.
+
+## grpc
+
+Stores code for GRPC based VHAL implementation.
+
+## hardware
+
+Defines an interface `IVehicleHardware.h` which vendor must implement for
+vehicle-specific logic if they want to follow our reference VHAL design.
+
+## proto
+
+Stores Some protobuf files translated from AIDL VHAL interface types. These
+files are used in GRPC VHAL implementation.
+
+## utils
+
+Defines a library `VehicleHalUtils` which provides useful utility functions for
+VHAL implementation. Vendor VHAL could use this library.
+
+## vhal
+
+Defines a library `DefaultVehicleHal` which provides generic logic for all VHAL
+implementations (including reference VHAL). Vendor VHAL implementation could
+use this library, along with their own implementation for `IVehicleHardware`
+interface.
+
+Also defines a binary `android.hardware.automotive.vehicle@V1-default-service`
+which is the reference VHAL implementation. It implements `IVehicle.aidl`
+interface. It uses `DefaultVehicleHal`, along with `FakeVehicleHardware`
+(in fake_impl). It simulates the vehicle bus interaction by using an
+in-memory map. Meaning that all properties (except for some special ones) are
+just written into a hash map and read from a hash map without relying on any
+hardware. As a result, the reference implementation can run on emulator or
+any host environment.
+
+Vendor must not directly use the reference implementation for a real vehicle.
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
index 5430f14..f465dc0 100644
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
@@ -724,6 +724,16 @@
{.config =
{
+ .prop = toInt(VehicleProperty::ENGINE_COOLANT_TEMP),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+ .minSampleRate = 1.0f,
+ .maxSampleRate = 10.0f,
+ },
+ .initialValue = {.floatValues = {75.0f}}},
+
+ {.config =
+ {
.prop = toInt(VehicleProperty::ENGINE_OIL_LEVEL),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -835,7 +845,7 @@
{.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REQ),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
- .configArray = {3}}},
+ .configArray = {0}}},
{.config = {.prop = toInt(VehicleProperty::AP_POWER_STATE_REPORT),
.access = VehiclePropertyAccess::READ_WRITE,
diff --git a/automotive/vehicle/aidl/impl/fake_impl/README.md b/automotive/vehicle/aidl/impl/fake_impl/README.md
new file mode 100644
index 0000000..e86dcee
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/fake_impl/README.md
@@ -0,0 +1,28 @@
+# Fake reference AIDL VHAL implementation libraries
+---
+
+This directory stores libraries for implementing a fake reference AIDL VHAL.
+
+WARNING: All the libraries here are for TEST ONLY.
+
+## GeneratorHub
+
+Defines a library `FakeVehicleHalValueGenerators` that could generate fake
+vehicle property values for testing.
+
+## hardware
+
+Defines a fake implementation for device-specifc interface `IVehicleHardware`:
+`FakeVehicleHardware`. This implementation uses a in-memory map for storing
+property values and does not communicate with or depending on any specific
+vehicle bus.
+
+## obd2frame
+
+Defines a library `FakeObd2Frame` that generates fake OBD2 frame for OBD2
+properties.
+
+## userhal
+
+Defines a library `FakeUserHal` that emulates a real User HAL behavior by
+parsing debug commands.
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 7f9b63a..a0fda79 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -67,6 +67,7 @@
using ::android::base::EqualsIgnoreCase;
using ::android::base::Error;
+using ::android::base::GetIntProperty;
using ::android::base::ParseFloat;
using ::android::base::Result;
using ::android::base::ScopedLockAssertion;
@@ -75,6 +76,7 @@
const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/automotive/vhaloverride/";
const char* OVERRIDE_PROPERTY = "persist.vendor.vhal_init_value_override";
+const char* POWER_STATE_REQ_CONFIG_PROPERTY = "ro.vendor.fake_vhal.ap_power_state_req.config";
// A list of supported options for "--set" command.
const std::unordered_set<std::string> SET_PROP_OPTIONS = {
@@ -163,7 +165,10 @@
VehiclePropConfig cfg = it.config;
VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
- if (cfg.prop == OBD2_FREEZE_FRAME) {
+ if (cfg.prop == toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
+ int config = GetIntProperty(POWER_STATE_REQ_CONFIG_PROPERTY, /*default_value=*/0);
+ cfg.configArray[0] = config;
+ } else if (cfg.prop == OBD2_FREEZE_FRAME) {
tokenFunction = [](const VehiclePropValue& propValue) { return propValue.timestamp; };
}
diff --git a/automotive/vehicle/aidl/impl/utils/README.md b/automotive/vehicle/aidl/impl/utils/README.md
new file mode 100644
index 0000000..87bb7e3
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/utils/README.md
@@ -0,0 +1,62 @@
+# Utility classes for VHAL implementation
+---
+
+This directory stores utility classes for VHAL implementation. Vendor
+implementation could use utility classes from `common` folder in their
+VHAL implementation.
+
+## common
+
+Defines common utility libraries.
+
+### ConcurrentQueue
+
+Provides a thread-safe concurrent queue object. Useful for adding object to
+a queue in one thread (usually binder thread) and handle the objects in a
+separate handler thread.
+
+### ParcelableUtils
+
+Provides functions to convert between a regular parcelable and a
+`LargeParcelabe`.
+
+A `LargeParcelable` is a parcelable that marshals the payload
+into a shared memory file if the payload is too large to pass across binder.
+It is used to pass large data across binder. Before sending the data, VHAL
+impl should convert a regular parcelabe to a `LargeParcelable`. After receving
+data, VHAL impl should convert a `LargeParcelable` back to regular parcelabe.
+
+### PendingRequestPool
+
+Defines A class for managing pending requests and automatically call timeout
+callback if the request timed-out.
+
+### PropertyUtils
+
+Defines some useful constants.
+
+### RecurrentTimer
+
+Defines a thread-safe recurrent timer that can call a function periodically.
+
+### VehicleHalTypes
+
+Provides a header file that includes many commonly used header files. Useful
+when you are using multiple types defined in VHAL interface.
+
+### VehicleObjectPool
+
+Defines a reusable in-memory pool for `VehiclePropValue`.
+
+### VehiclePropertyStore
+
+Defines an in-memory map for storing vehicle properties. Allows easier insert,
+delete and lookup.
+
+### VehicleUtils
+
+Defines many useful utility functions.
+
+## test
+
+Defines utility libraries for test only.
diff --git a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
index ac17d6d..572a8b6 100644
--- a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
+++ b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
@@ -25,9 +25,8 @@
// Helper library to implement the IBootControl HAL using the misc partition.
class BootControl {
- using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus;
-
public:
+ using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus;
bool Init();
unsigned int GetNumberSlots();
unsigned int GetCurrentSlot();
diff --git a/boot/aidl/Android.bp b/boot/aidl/Android.bp
new file mode 100644
index 0000000..be38245
--- /dev/null
+++ b/boot/aidl/Android.bp
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2022 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+ name: "android.hardware.boot",
+ vendor_available: true,
+ srcs: ["android/hardware/boot/*.aidl"],
+ stability: "vintf",
+ recovery_available: true,
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ },
+ cpp: {
+ enabled: false,
+ },
+ },
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl
new file mode 100644
index 0000000..c8ab51e
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2022 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.boot;
+@VintfStability
+interface IBootControl {
+ int getActiveBootSlot();
+ int getCurrentSlot();
+ int getNumberSlots();
+ android.hardware.boot.MergeStatus getSnapshotMergeStatus();
+ String getSuffix(in int slot);
+ boolean isSlotBootable(in int slot);
+ boolean isSlotMarkedSuccessful(in int slot);
+ void markBootSuccessful();
+ void setActiveBootSlot(in int slot);
+ void setSlotAsUnbootable(in int slot);
+ void setSnapshotMergeStatus(in android.hardware.boot.MergeStatus status);
+ const int INVALID_SLOT = -1;
+ const int COMMAND_FAILED = -2;
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl
new file mode 100644
index 0000000..53c6204
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 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.boot;
+@Backing(type="int") @VintfStability
+enum MergeStatus {
+ NONE = 0,
+ UNKNOWN = 1,
+ SNAPSHOTTED = 2,
+ MERGING = 3,
+ CANCELLED = 4,
+}
diff --git a/boot/aidl/android/hardware/boot/IBootControl.aidl b/boot/aidl/android/hardware/boot/IBootControl.aidl
new file mode 100644
index 0000000..6c9e8ce
--- /dev/null
+++ b/boot/aidl/android/hardware/boot/IBootControl.aidl
@@ -0,0 +1,158 @@
+//
+// Copyright (C) 2022 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.boot;
+
+import android.hardware.boot.MergeStatus;
+
+@VintfStability
+interface IBootControl {
+ const int INVALID_SLOT = -1;
+ const int COMMAND_FAILED = -2;
+ /**
+ * Returns the active slot to boot into on the next boot. If
+ * setActiveBootSlot() has been called, the getter function should return the
+ * same slot as the one provided in the last setActiveBootSlot() call.
+ * The returned value is always guaranteed to be strictly less than the
+ * value returned by getNumberSlots. Slots start at 0 and finish at
+ * getNumberSlots() - 1. For instance, a system with A/B must return 0 or 1.
+ * @return the active slot to boot into on the next boot.
+ */
+ int getActiveBootSlot();
+
+ /**
+ * getCurrentSlot() returns the slot number of that the current boot is booted
+ * from, for example slot number 0 (Slot A). It is assumed that if the current
+ * slot is A, then the block devices underlying B can be accessed directly
+ * without any risk of corruption.
+ * The returned value is always guaranteed to be strictly less than the
+ * value returned by getNumberSlots. Slots start at 0 and finish at
+ * getNumberSlots() - 1. The value returned here must match the suffix passed
+ * from the bootloader, regardless of which slot is active or successful.
+ * @return the slot number of that the current boot is booted
+ */
+ int getCurrentSlot();
+
+ /**
+ * getNumberSlots() returns the number of available slots.
+ * For instance, a system with a single set of partitions must return
+ * 1, a system with A/B must return 2, A/B/C -> 3 and so on. A system with
+ * less than two slots doesn't support background updates, for example if
+ * running from a virtual machine with only one copy of each partition for the
+ * purpose of testing.
+ * @return number of available slots
+ */
+ int getNumberSlots();
+
+ /**
+ * Returns whether a snapshot-merge of any dynamic partition is in progress.
+ *
+ * This function must return the merge status set by the last setSnapshotMergeStatus call and
+ * recorded by the bootloader with one exception. If the partitions are being flashed from the
+ * bootloader such that the pending merge must be canceled (for example, if the super partition
+ * is being flashed), this function must return CANCELLED.
+ *
+ * @param out success True if the merge status is read successfully, false otherwise.
+ * @return Merge status.
+ */
+ MergeStatus getSnapshotMergeStatus();
+
+ /**
+ * getSuffix() returns the string suffix used by partitions that correspond to
+ * the slot number passed in as a parameter. The bootloader must pass the
+ * suffix of the currently active slot either through a kernel command line
+ * property at androidboot.slot_suffix, or the device tree at
+ * /firmware/android/slot_suffix.
+ * @return suffix for the input slot, or the empty string "" if slot
+ * does not match an existing slot.
+ */
+ String getSuffix(in int slot);
+
+ /**
+ * isSlotBootable() returns if the slot passed in parameter is bootable. Note
+ * that slots can be made unbootable by both the bootloader and by the OS
+ * using setSlotAsUnbootable.
+ * @return true if the slot is bootable, false if it's not.
+ * @throws service specific error INVALID_SLOT if slot is invalid.
+ */
+ boolean isSlotBootable(in int slot);
+
+ /**
+ * isSlotMarkedSuccessful() returns if the slot passed in parameter has been
+ * marked as successful using markBootSuccessful. Note that only the current
+ * slot can be marked as successful but any slot can be queried.
+ * @return true if the slot has been marked as successful, false if it has
+ * not.
+ * @throws service specific error INVALID_SLOT if slot is invalid.
+ */
+ boolean isSlotMarkedSuccessful(in int slot);
+
+ /**
+ * markBootSuccessful() marks the current slot as having booted successfully.
+ *
+ * @throws Service specific error COMMAND_FAILED if command failed.
+ */
+ void markBootSuccessful();
+
+ /**
+ * setActiveBootSlot() marks the slot passed in parameter as the active boot
+ * slot (see getCurrentSlot for an explanation of the "slot" parameter). This
+ * overrides any previous call to setSlotAsUnbootable.
+ * @throws Service specific error INVALID_SLOT if slot is invalid, or COMMAND_FAILED if
+ * operation failed.
+ */
+ void setActiveBootSlot(in int slot);
+
+ /**
+ * setSlotAsUnbootable() marks the slot passed in parameter as
+ * an unbootable. This can be used while updating the contents of the slot's
+ * partitions, so that the system must not attempt to boot a known bad set up.
+ * @throws Service specific error INVALID_SLOT if slot is invalid, or COMMAND_FAILED if
+ * operation failed.
+ */
+ void setSlotAsUnbootable(in int slot);
+
+ /**
+ * Sets whether a snapshot-merge of any dynamic partition is in progress.
+ *
+ * After the merge status is set to a given value, subsequent calls to
+ * getSnapshotMergeStatus must return the set value.
+ *
+ * The merge status must be persistent across reboots. That is, getSnapshotMergeStatus
+ * must return the same value after a reboot if the merge status is not altered in any way
+ * (e.g. set by setSnapshotMergeStatus or set to CANCELLED by bootloader).
+ *
+ * Read/write access to the merge status must be atomic. When the HAL is processing a
+ * setSnapshotMergeStatus call, all subsequent calls to getSnapshotMergeStatus must block until
+ * setSnapshotMergeStatus has returned.
+ *
+ * A MERGING state indicates that dynamic partitions are partially comprised by blocks in the
+ * userdata partition.
+ *
+ * When the merge status is set to MERGING, the following operations must be prohibited from the
+ * bootloader:
+ * - Flashing or erasing "userdata" or "metadata".
+ *
+ * The following operations may be prohibited when the status is set to MERGING. If not
+ * prohibited, it is recommended that the user receive a warning.
+ * - Changing the active slot (e.g. via "fastboot set_active")
+ *
+ * @param status Merge status.
+ *
+ * @throws service specific error COMMAND_FAILED if operation failed.
+ */
+ void setSnapshotMergeStatus(in MergeStatus status);
+}
diff --git a/boot/aidl/android/hardware/boot/MergeStatus.aidl b/boot/aidl/android/hardware/boot/MergeStatus.aidl
new file mode 100644
index 0000000..16ac85f
--- /dev/null
+++ b/boot/aidl/android/hardware/boot/MergeStatus.aidl
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 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.boot;
+
+@VintfStability
+@Backing(type="int")
+enum MergeStatus {
+ /**
+ * No snapshot or merge is in progress.
+ */
+ NONE = 0,
+ /**
+ * The merge status could not be determined.
+ */
+ UNKNOWN,
+ /**
+ * Partitions are being snapshotted, but no merge has been started.
+ */
+ SNAPSHOTTED,
+ /**
+ * At least one partition has merge is in progress.
+ */
+ MERGING,
+ /**
+ * A merge was in progress, but it was canceled by the bootloader.
+ */
+ CANCELLED,
+}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 5aadbe9..386db52 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -169,6 +169,13 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.boot</name>
+ <interface>
+ <name>IBootControl</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.broadcastradio</name>
<version>1.0-1</version>
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 407ac0c..0e1218e 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -141,18 +141,18 @@
}
SetPositionMode(min_interval_msec, low_power_mode);
- auto status = aidl_gnss_hal_->start();
- EXPECT_TRUE(status.isOk());
-
if (start_sv_status) {
- status = aidl_gnss_hal_->startSvStatus();
+ auto status = aidl_gnss_hal_->startSvStatus();
EXPECT_TRUE(status.isOk());
}
if (start_nmea) {
- status = aidl_gnss_hal_->startNmea();
+ auto status = aidl_gnss_hal_->startNmea();
EXPECT_TRUE(status.isOk());
}
+ auto status = aidl_gnss_hal_->start();
+ EXPECT_TRUE(status.isOk());
+
/*
* GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
* so allow time to demodulate ephemeris over the air.
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index f926c40..3696233 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -291,10 +291,12 @@
EXPECT_GT(aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, kNumSvInfoLists,
kTimeoutSeconds),
0);
- last_sv_info_list = sv_info_lists.back();
- } while (last_sv_info_list.size() == 0);
+ if (!sv_info_lists.empty()) {
+ last_sv_info_list = sv_info_lists.back();
+ ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size());
+ }
+ } while (!sv_info_lists.empty() && last_sv_info_list.size() == 0);
- ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size());
bool nonZeroCn0Found = false;
for (auto sv_info : last_sv_info_list) {
EXPECT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
diff --git a/graphics/composer/2.1/utils/vts/ComposerVts.cpp b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
index e777010..4603dd1 100644
--- a/graphics/composer/2.1/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
@@ -316,8 +316,12 @@
Gralloc::Gralloc() {
[this] {
- ASSERT_NO_FATAL_FAILURE(mGralloc4 = std::make_shared<Gralloc4>("default", "default",
- /*errOnFailure=*/false));
+ ASSERT_NO_FATAL_FAILURE(mGralloc4 = std::make_shared<Gralloc4>(
+ /*aidlAllocatorServiceName*/ IAllocator::descriptor +
+ std::string("/default"),
+ /*hidlAllocatorServiceName*/ "default",
+ /*mapperServiceName*/ "default",
+ /*errOnFailure=*/false));
if (!mGralloc4->hasAllocator() || mGralloc4->getMapper() == nullptr) {
mGralloc4 = nullptr;
ASSERT_NO_FATAL_FAILURE(mGralloc3 = std::make_shared<Gralloc3>("default", "default",
diff --git a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
index 2949823..f8ea661 100644
--- a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/ComposerVts.h
@@ -49,6 +49,7 @@
using Gralloc2 = android::hardware::graphics::mapper::V2_0::vts::Gralloc;
using Gralloc3 = android::hardware::graphics::mapper::V3_0::vts::Gralloc;
using Gralloc4 = android::hardware::graphics::mapper::V4_0::vts::Gralloc;
+using IAllocator = aidl::android::hardware::graphics::allocator::IAllocator;
class ComposerClient;
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index 7de4007..b706596 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -182,8 +182,12 @@
Gralloc::Gralloc() {
[this] {
ALOGD("Attempting to initialize gralloc4");
- ASSERT_NO_FATAL_FAILURE(mGralloc4 = std::make_shared<Gralloc4>("default", "default",
- /*errOnFailure=*/false));
+ ASSERT_NO_FATAL_FAILURE(mGralloc4 = std::make_shared<Gralloc4>(
+ /*aidlAllocatorServiceName*/ IAllocator::descriptor +
+ std::string("/default"),
+ /*hidlAllocatorServiceName*/ "default",
+ /*mapperServiceName*/ "default",
+ /*errOnFailure=*/false));
if (mGralloc4->getMapper() == nullptr || !mGralloc4->hasAllocator()) {
mGralloc4 = nullptr;
ALOGD("Failed to initialize gralloc4, initializing gralloc3");
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
index d3bba17..02d7bdb 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
@@ -48,6 +48,7 @@
using Gralloc2_1 = android::hardware::graphics::mapper::V2_1::vts::Gralloc;
using Gralloc3 = android::hardware::graphics::mapper::V3_0::vts::Gralloc;
using Gralloc4 = android::hardware::graphics::mapper::V4_0::vts::Gralloc;
+using IAllocator = aidl::android::hardware::graphics::allocator::IAllocator;
class ComposerClient;
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index ece1fd3..93b646f 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1719,10 +1719,10 @@
}
}
+ configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
+ display.getCrop());
mWriter.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
/*acquireFence*/ -1);
- mWriter.setLayerCompositionType(display.getDisplayId(), layer,
- Composition::DISPLAY_DECORATION);
mWriter.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp);
execute();
if (support) {
diff --git a/graphics/mapper/4.0/utils/vts/MapperVts.cpp b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
index e4a2535..c6c9834 100644
--- a/graphics/mapper/4.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
@@ -27,21 +27,24 @@
namespace V4_0 {
namespace vts {
-Gralloc::Gralloc(const std::string& allocatorServiceName, const std::string& mapperServiceName,
+Gralloc::Gralloc(const std::string& aidlAllocatorServiceName,
+ const std::string& hidlAllocatorServiceName, const std::string& mapperServiceName,
bool errOnFailure) {
if (errOnFailure) {
- init(allocatorServiceName, mapperServiceName);
+ init(aidlAllocatorServiceName, hidlAllocatorServiceName, mapperServiceName);
} else {
- initNoErr(allocatorServiceName, mapperServiceName);
+ initNoErr(aidlAllocatorServiceName, hidlAllocatorServiceName, mapperServiceName);
}
}
-void Gralloc::init(const std::string& allocatorServiceName, const std::string& mapperServiceName) {
+void Gralloc::init(const std::string& aidlAllocatorServiceName,
+ const std::string& hidlAllocatorServiceName,
+ const std::string& mapperServiceName) {
mAidlAllocator = aidl::android::hardware::graphics::allocator::IAllocator::fromBinder(
- ndk::SpAIBinder(AServiceManager_checkService(allocatorServiceName.c_str())));
+ ndk::SpAIBinder(AServiceManager_checkService(aidlAllocatorServiceName.c_str())));
if (mAidlAllocator == nullptr) {
- mHidlAllocator = IAllocator::getService(allocatorServiceName);
+ mHidlAllocator = IAllocator::getService(hidlAllocatorServiceName);
}
ASSERT_TRUE(nullptr != mAidlAllocator || mHidlAllocator != nullptr)
<< "failed to get allocator service";
@@ -51,13 +54,14 @@
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
-void Gralloc::initNoErr(const std::string& allocatorServiceName,
+void Gralloc::initNoErr(const std::string& aidlAllocatorServiceName,
+ const std::string& hidlAllocatorServiceName,
const std::string& mapperServiceName) {
mAidlAllocator = aidl::android::hardware::graphics::allocator::IAllocator::fromBinder(
- ndk::SpAIBinder(AServiceManager_checkService(allocatorServiceName.c_str())));
+ ndk::SpAIBinder(AServiceManager_checkService(aidlAllocatorServiceName.c_str())));
if (mAidlAllocator == nullptr) {
- mHidlAllocator = IAllocator::getService(allocatorServiceName);
+ mHidlAllocator = IAllocator::getService(hidlAllocatorServiceName);
}
mMapper = IMapper::getService(mapperServiceName);
diff --git a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
index b956e49..ecbbc58 100644
--- a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
+++ b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
@@ -49,7 +49,9 @@
kToleranceAllErrors = ~0x0U,
};
- Gralloc(const std::string& allocatorServiceName = "default",
+ Gralloc(const std::string& aidlAllocatorServiceName =
+ "android.hardware.graphics.allocator.IAllocator/default",
+ const std::string& hidlAllocatorServiceName = "default",
const std::string& mapperServiceName = "default", bool errOnFailure = true);
~Gralloc();
@@ -164,10 +166,13 @@
0x1U << std::underlying_type_t<Error>(error)) != 0;
}
- void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
+ void init(const std::string& aidlAllocatorServiceName,
+ const std::string& hidlAllocatorServiceName, const std::string& mapperServiceName);
// initialize without checking for failure to get service
- void initNoErr(const std::string& allocatorServiceName, const std::string& mapperServiceName);
+ void initNoErr(const std::string& aidlAllocatorServiceName,
+ const std::string& hidlAllocatorServiceName,
+ const std::string& mapperServiceName);
const native_handle_t* cloneBuffer(const hidl_handle& rawHandle, enum Tolerance tolerance);
const native_handle_t* cloneBuffer(const hidl_handle& rawHandle) {
return cloneBuffer(rawHandle, Tolerance::kToleranceStrict);
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index bf56860..bdaaf96 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -27,6 +27,7 @@
#include <openssl/mem.h>
#include <openssl/x509.h>
+#include <android-base/properties.h>
#include <cutils/properties.h>
#include <keymasterV4_0/attestation_record.h>
@@ -386,6 +387,28 @@
return property_get("ro.boot.vbmeta.device_state", value, "") != 0;
}
+int get_vsr_api_level() {
+ int api_level = ::android::base::GetIntProperty("ro.board.api_level", -1);
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.board.first_api_level", -1);
+ }
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.vndk.version", -1);
+ }
+ // We really should have a VSR API level by now. But on cuttlefish, and perhaps other weird
+ // devices, we may not. So, we use the SDK first or current API level if needed. If this goes
+ // wrong, it should go wrong in the direction of being too strict rather than too lenient, which
+ // should provoke someone to examine why we don't have proper VSR API level properties.
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.product.first_api_level", -1);
+ }
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.build.version.sdk", -1);
+ }
+ EXPECT_NE(api_level, -1) << "Could not find a VSR level, or equivalent.";
+ return api_level;
+}
+
bool is_gsi() {
char property_value[PROPERTY_VALUE_MAX] = {};
EXPECT_NE(property_get("ro.product.system.name", property_value, ""), 0);
@@ -4833,6 +4856,18 @@
INSTANTIATE_KEYMASTER_HIDL_TEST(TransportLimitTest);
+using VsrRequirementTest = KeymasterHidlTest;
+
+TEST_P(VsrRequirementTest, Vsr13Test) {
+ int vsr_api_level = get_vsr_api_level();
+ if (vsr_api_level < 33) {
+ GTEST_SKIP() << "Applies only to VSR API level 33, this device is: " << vsr_api_level;
+ }
+ FAIL() << "VSR 13+ requires KeyMint version 2";
+}
+
+INSTANTIATE_KEYMASTER_HIDL_TEST(VsrRequirementTest);
+
} // namespace test
} // namespace V4_0
} // namespace keymaster
diff --git a/security/keymint/RKP_README.md b/security/keymint/RKP_README.md
new file mode 100644
index 0000000..89a2598
--- /dev/null
+++ b/security/keymint/RKP_README.md
@@ -0,0 +1,374 @@
+# Remote Provisioning HAL
+
+## Objective
+
+Design a HAL to support over-the-air provisioning of certificates for asymmetric
+keys. The HAL must interact effectively with Keystore (and other daemons) and
+protect device privacy and security.
+
+Note that this API is designed for KeyMint, but with the intention that it
+should be usable for other HALs that require certificate provisioning.
+Throughout this document we'll refer to the Keystore and KeyMint (formerly
+called Keymaster) components, but only for concreteness and convenience; those
+labels could be replaced with the names of any system and secure area
+components, respectively, that need certificates provisioned.
+
+## Key design decisions
+
+### General approach
+
+To more securely and reliably get keys and certificates to Android devices, we
+need to create a system where no party outside of the device's secure components
+is responsible for managing private keys. The strategy we've chosen is to
+deliver certificates over the air, using an asymmetric key pair created
+on-device in the factory as a root of trust to create an authenticated, secure
+channel. In this document we refer to this device-unique asymmetric key pair as
+Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device
+Key Certificate containing DK\_pub is denoted DKC.
+
+In order for the provisioning service to use DK (or a key authenticated by DK),
+it must know whether a given DK\_pub is known and trusted. To prove trust, we
+ask device OEMs to use one of two mechanisms:
+
+1. (Preferred, recommended) The device OEM extracts DK\_pub from each device it
+ manufactures and uploads the public keys to a backend server.
+
+1. The device OEM signs the DK\_pub to produce DKC and stores it on the device.
+ This has the advantage that they don't need to upload a DK\_pub for every
+ device immediately, but the disadvantage that they have to manage their
+ private signing keys, which means they have to have HSMs, configure and
+ secure them correctly, etc. Some backend providers may also require that the
+ OEM passes a factory security audit, and additionally promises to upload the
+ keys eventually as well.
+
+Note that in the full elaboration of this plan, DK\_pub is not the key used to
+establish a secure channel. Instead, DK\_pub is just the first public key in a
+chain of public keys which ends with the KeyMint public key, KM\_pub. All keys
+in the chain are device-unique and are joined in a certificate chain called the
+_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote
+provisioning project it is a chain of certificates corresponding to boot phases.
+We speak of the BCC even for phase 1, though in phase 1 it contains only a
+single self-signed DKC. This is described in more depth in the Phases section
+below.
+
+The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have
+additional DKCs, from the SoC vendor, the device OEM, or both. Those are not
+part of the BCC but included as optional fields in the certificate request
+structure.
+
+The format of the the DK and BCC is specified within [Open Profile for DICE]
+(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md). To
+map phrases within this document to their equivalent terminology in the DICE
+specification, read the terms as follows: the DK corresponds to the UDS-derived
+key pair, DKC corresponds to the UDS certificate, and the BCC entries between
+DK\_pub and KM\_pub correspond to a chain of CDI certificates.
+
+Note: In addition to allowing 32 byte hash values for fields in the BCC payload,
+this spec additionally constrains some of the choices allowed in open-DICE.
+Specifically, these include which entries are required and which are optional in
+the BCC payload, and which algorithms are acceptable for use.
+
+### Phases
+
+RKP will be deployed in three phases, in terms of managing the root of trust
+binding between the device and the backend. To briefly describe them:
+
+* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are
+ the same key and the certificate is self-signed.
+* Phase 2: This is identical to phase 1, except it leverages the hardware root
+ of trust process described by DICE. Instead of trust being rooted in the TEE,
+ it is now rooted in the ROM by key material blown into fuses which are only
+ accessible to the ROM code.
+* Phase 3: This is identical to Phase 2, except the SoC vendor also does the
+ public key extraction or certification in their facilities, along with the OEM
+ doing it in the factory. This tightens up the "supply chain" and aims to make
+ key upload management more secure.
+
+### Privacy considerations
+
+Because DK and the DKCs are unique, immutable, unspoofable hardware-bound
+identifiers for the device, we must limit access to them to the absolute minimum
+possible. We do this in two ways:
+
+1. We require KeyMint (which knows the BCC and either knows or at least has the
+ability to use KM\_priv) to refuse to ever divulge the BCC or additional
+signatures in plaintext. Instead, KeyMint requires the caller to provide an
+_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before
+returning it. When provisioning production keys, the EEK must be signed by an
+approved authority whose public key is embedded in KeyMint. When certifying test
+keys, KeyMint will accept any EEK without checking the signature, but will
+encrypt and return a test BCC, rather than the real one. The result is that
+only an entity in possession of an Trusted EEK (TEEK) private key can discover
+the plaintext of the production BCC.
+1. Having thus limited access to the public keys to the trusted party only, we
+need to prevent the entity from abusing this unique device identifier. The
+approach and mechanisms for doing that are beyond the scope of this document
+(they must be addressed in the server design), but generally involve taking care
+to ensure that we do not create any links between user IDs, IP addresses or
+issued certificates and the device pubkey.
+
+Although the details of the mechanisms for preventing the entity from abusing
+the BCC are, as stated, beyond the scope of this document, there is a subtle
+design decision here made specifically to enable abuse prevention. Specifically
+the `CertificateRequest` message sent to the server is (in
+[CDDL](https://tools.ietf.org/html/rfc8610)):
+
+```
+cddl
+CertificateRequest = [
+ DeviceInfo,
+ challenge : bstr,
+ ProtectedData,
+ MacedKeysToSign
+]
+```
+
+The public keys to be attested by the server are in `MacedKeysToSign`, which is
+a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The
+MAC key is signed by DK\_pub.
+
+This structure allows the backend component that has access to EEK\_priv to
+decrypt `ProtectedData`, validate that the request is from an authorized device,
+check that the request is fresh and verify and extract the MAC key. That backend
+component never sees any data related to the keys to be signed, but can provide
+the MAC key to another backend component that can verify `MacedKeysToSign` and
+proceed to generate the certificates.
+
+In this way, we can partition the provisioning server into one component that
+knows the device identity, as represented by DK\_pub, but never sees the keys to
+be certified or certificates generated, and another component that sees the keys
+to be certified and certificates generated but does not know the device
+identity.
+
+### Key and cryptographic message formatting
+
+For simplicity of generation and parsing, compactness of wire representation,
+and flexibility and standardization, we've settled on using the CBOR Object
+Signing and Encryption (COSE) standard, defined in [RFC
+8152](https://tools.ietf.org/html/rfc8152). COSE provides compact and reasonably
+simple, yet easily-extensible, wire formats for:
+
+* Keys,
+* MACed messages,
+* Signed messages, and
+* Encrypted messages
+
+COSE enables easy layering of these message formats, such as using a COSE\_Sign
+structure to contain a COSE\_Key with a public key in it. We call this a
+"certificate".
+
+Due to the complexity of the standard, we'll spell out the COSE structures
+completely in this document and in the HAL and other documentation, so that
+although implementors will need to understand CBOR and the CBOR Data Definition
+Language ([CDDL, defined in RFC 8610](https://tools.ietf.org/html/rfc8610)),
+they shouldn't need to understand COSE.
+
+Note, however, that the certificate chains returned from the provisioning server
+are standard X.509 certificates.
+
+### Algorithm choices
+
+This document uses:
+
+* ECDSA P-256 for attestation signing keys;
+* Remote provisioning protocol signing keys:
+ * Ed25519 / P-256
+* ECDH keys:
+ * X25519 / P-256
+* AES-GCM for all encryption;
+* SHA-256 for all message digesting;
+* HMAC-SHA-256 for all MACing; and
+* HKDF-SHA-256 for all key derivation.
+
+We believe that Curve25519 offers the best tradeoff in terms of security,
+efficiency and global trustworthiness, and that it is now sufficiently
+widely-used and widely-implemented to make it a practical choice.
+
+However, since Secure Elements (SE) do not currently offer support for curve
+25519, we are allowing implementations to instead make use of EC P-256 for
+signing and ECDH. To put it simply, the device unique key pair will be a P-256
+key pair for ECDSA instead of Ed25519, and the ProtectedData COSE\_Encrypt
+message will have its payload encrypted with P-256 ECDH key exchange instead of
+X25519.
+
+The CDDL in the rest of the document will use the '/' operator to show areas
+where either curve 25519 or P-256 may be used. Since there is no easy way to
+bind choices across different CDDL groups, it is important that the implementor
+stays consistent in which type is chosen. E.g. taking ES256 as the choice for
+algorithm implies the implementor should also choose the P256 public key group
+further down in the COSE structure.
+
+### Testability
+
+It's critical that the remote provisioning implementation be testable, to
+minimize the probability that broken devices are sold to end users. To support
+testing, the remote provisioning HAL methods take a `testMode` argument. Keys
+created in test mode are tagged to indicate this. The provisioning server will
+check for the test mode tag and issue test certificates that do not chain back
+to a trusted public key. In test mode, any EEK will be accepted, enabling
+testing tools to use EEKs for which they have the private key so they can
+validate the content of certificate requests. The BCC included in the
+`CertificateRequest` must contain freshly-generated keys, not the real BCC keys.
+
+Keystore (or similar) will need to be able to handle both testMode keys and
+production keys and keep them distinct, generating test certificate requests
+when asked with a test EEK and production certificate requests when asked with a
+production EEK. Likewise, the interface used to instruct Keystore to create keys
+will need to be able to specify whether test or production keys are desired.
+
+## Design
+
+### Certificate provisioning flow
+
+TODO(jbires): Replace this with a `.png` containing a sequence diagram. The
+provisioning flow looks something like this:
+
+Provisioner -> Keystore: Prepare N keys
+Keystore -> KeyMint: generateKeyPair
+KeyMint -> KeyMint: Generate key pair
+KeyMint --> Keystore: key\_blob,pubkey
+Keystore -> Keystore: Store key\_blob,pubkey
+Provisioner -> Server: Get TEEK
+Server --> Provisioner: TEEK
+Provisioner -> Keystore: genCertReq(N, TEEK)
+Keystore -> KeyMint: genCertReq(pubkeys, TEEK)
+KeyMint -> KeyMint: Sign pubkeys & encrypt BCC
+KeyMint --> Keystore: signature, encrypted BCC
+Keystore -> Keystore: Construct cert\_request
+Keystore --> Provisioner: cert\_request
+Provisioner --> Server: cert\_request
+Server -> Server: Validate cert\_request
+Server -> Server: Generate certificates
+Server --> Provisioner: certificates
+Provisioner -> Keystore: certificates
+Keystore -> Keystore: Store certificates
+
+The actors in the above diagram are:
+
+* **Server** is the backend certificate provisioning server. It has access to
+ the uploaded device public keys and is responsible for providing encryption
+ keys, decrypting and validating requests, and generating certificates in
+ response to requests.
+* **Provisioner** is an application that is responsible for communicating with
+ the server and all of the system components that require key certificates
+ from the server. It also implements the policy that defines how many key
+ pairs each client should keep in their pool.
+* **Keystore** is the [Android keystore
+ daemon](https://developer.android.com/training/articles/keystore) (or, more
+ generally, whatever system component manages communications with a
+ particular secure aread component).
+* **KeyMint** is the secure area component that manages cryptographic keys and
+ performs attestations (or perhaps some other secure area component).
+
+### `BCC`
+
+The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains
+DK\_pub as well as other often device-unique certificates. The BCC is
+represented as a COSE\_Key containing DK\_pub followed by an array of
+COSE\_Sign1 "certificates" containing public keys and optional additional
+information, ordered from root to leaf, with each certificate signing the next.
+The first certificate in the array is signed by DK\_pub, the last certificate
+has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1
+there is only one entry; DK\_pub and KM\_pub are the same key and the
+certificate is self-signed.
+
+Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC
+8392](https://tools.ietf.org/html/rfc8392) with additional fields as described
+in the Open Profile for DICE. Of these additional fields, only the
+_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the
+KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the
+Open Profile for DICE are expected for other entries (each of which corresponds
+to a particular firmware component or boot stage). The CWT fields _iss_ and
+_sub_ identify the issuer and subject of the certificate and are consistent
+along the BCC entries; the issuer of a given entry matches the subject of the
+previous entry.
+
+The BCC is designed to be constructed using the Open Profile for DICE. In this
+case the DK key pair is derived from the UDS as described by that profile and
+all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub.
+The KM key pair is not part of the derived DICE chain. It is generated (not
+derived) by the KeyMint module, certified by the last key in the DICE chain, and
+added as the leaf BCC entry. The key usage field in this leaf certificate must
+indicate the key is not used to sign certificates. If a UDS certificate is
+available on the device it should appear in the certificate request as the leaf
+of a DKCertChain in AdditionalDKSignatures (see
+[CertificateRequest](#certificaterequest)).
+
+The Open Profile for DICE allows for an arbitrary configuration descriptor. For
+BCC entries, this configuration descriptor is a CBOR map with the following
+optional fields. If no fields are relevant, an empty map should be encoded.
+Additional implementation-specific fields may be added using key values not in
+the range \[-70000, -70999\] (these are reserved for future additions here).
+
+```
+| Name | Key | Value type | Meaning |
+| ----------------- | ------ | ---------- | ----------------------------------|
+| Component name | -70002 | tstr | Name of firmware component / boot |
+: : : : stage :
+| Component version | -70003 | int | Version of firmware component / |
+: : : : boot stage :
+| Resettable | -70004 | null | If present, key changes on factory|
+: : : : reset :
+```
+
+Please see
+[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+for a full CDDL definition of the BCC.
+
+### `CertificateRequest`
+
+The full CBOR message that will be sent to the server to request certificates
+is:
+
+```cddl
+CertificateRequest = [
+ DeviceInfo,
+ challenge : bstr, // Provided by the server
+ ProtectedData, // See ProtectedData.aidl
+ MacedKeysToSign // See IRemotelyProvisionedComponent.aidl
+]
+
+DeviceInfo = [
+ VerifiedDeviceInfo, // See DeviceInfo.aidl
+ UnverifiedDeviceInfo
+]
+
+// Unverified info is anything provided by the HLOS. Subject to change out of
+// step with the HAL.
+UnverifiedDeviceInfo = {
+ ? "fingerprint" : tstr,
+}
+
+```
+
+It will be the responsibility of Keystore and the Provisioner to construct the
+`CertificateRequest`. The HAL provides a method to generate the elements that
+need to be constructed on the secure side, which are the tag field of
+`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of
+`ProtectedData`.
+
+### HAL
+
+The remote provisioning HAL provides a simple interface that can be implemented
+by multiple secure components that require remote provisioning. It would be
+slightly simpler to extend the KeyMint API, but that approach would only serve
+the needs of KeyMint, this is more general.
+
+NOTE the data structures defined in this HAL may look a little bloated and
+complex. This is because the COSE data structures are fully spelled-out; we
+could make it much more compact by not re-specifying the standardized elements
+and instead just referencing the standard, but it seems better to fully specify
+them. If the apparent complexity seems daunting, consider what the same would
+look like if traditional ASN.1 DER-based structures from X.509 and related
+standards were used and also fully elaborated.
+
+Please see the related HAL documentation directly in the source code at the
+following links:
+
+* [IRemotelyProvisionedComponent
+ HAL](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl)
+* [ProtectedData](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+* [MacedPublicKey](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl)
+* [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl)
+* [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl)
+
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 70b89c3..33945fd 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1460,6 +1460,28 @@
OPENSSL_free(cert_issuer);
}
+int get_vsr_api_level() {
+ int api_level = ::android::base::GetIntProperty("ro.board.api_level", -1);
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.board.first_api_level", -1);
+ }
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.vndk.version", -1);
+ }
+ // We really should have a VSR API level by now. But on cuttlefish, and perhaps other weird
+ // devices, we may not. So, we use the SDK first or current API level if needed. If this goes
+ // wrong, it should go wrong in the direction of being too strict rather than too lenient, which
+ // should provoke someone to examine why we don't have proper VSR API level properties.
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.product.first_api_level", -1);
+ }
+ if (api_level == -1) {
+ api_level = ::android::base::GetIntProperty("ro.build.version.sdk", -1);
+ }
+ EXPECT_NE(api_level, -1) << "Could not find a VSR level, or equivalent.";
+ return api_level;
+}
+
bool is_gsi_image() {
std::ifstream ifs("/system/system_ext/etc/init/init.gsi.rc");
return ifs.good();
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 043d8b5..8f9df24 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -355,6 +355,9 @@
}
}
+// Return the VSR API level for this device.
+int get_vsr_api_level();
+
// Indicate whether the test is running on a GSI image.
bool is_gsi_image();
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 38f5b1c..371b589 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1102,9 +1102,9 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ ASSERT_GT(cert_chain_.size(), 0);
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
- ASSERT_GT(cert_chain_.size(), 0);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -1178,6 +1178,7 @@
EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_));
// The signature over the attested key should correspond to the P256 public key.
+ ASSERT_GT(cert_chain_.size(), 0);
X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
ASSERT_TRUE(key_cert.get());
EVP_PKEY_Ptr signing_pubkey;
@@ -1265,9 +1266,9 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ ASSERT_GT(cert_chain_.size(), 0);
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
- ASSERT_GT(cert_chain_.size(), 0);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -1317,9 +1318,9 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ ASSERT_EQ(cert_chain_.size(), 1);
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
- ASSERT_EQ(cert_chain_.size(), 1);
CheckedDeleteKey(&key_blob);
}
@@ -1398,6 +1399,7 @@
<< "Key size " << key_size << "missing";
EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+ ASSERT_GT(cert_chain_.size(), 0);
verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
ASSERT_EQ(cert_chain_.size(), 1);
@@ -2228,8 +2230,8 @@
EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
- verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
ASSERT_EQ(cert_chain_.size(), 1);
+ verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -8014,6 +8016,18 @@
INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
+using VsrRequirementTest = KeyMintAidlTestBase;
+
+TEST_P(VsrRequirementTest, Vsr13Test) {
+ int vsr_api_level = get_vsr_api_level();
+ if (vsr_api_level < 33) {
+ GTEST_SKIP() << "Applies only to VSR API level 33, this device is: " << vsr_api_level;
+ }
+ EXPECT_GE(AidlVersion(), 2) << "VSR 13+ requires KeyMint version 2";
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(VsrRequirementTest);
+
} // namespace aidl::android::hardware::security::keymint::test
int main(int argc, char** argv) {
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp
index 274cfa7..d53179a 100644
--- a/sensors/1.0/vts/functional/Android.bp
+++ b/sensors/1.0/vts/functional/Android.bp
@@ -26,7 +26,10 @@
cc_test {
name: "VtsHalSensorsV1_0TargetTest",
cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: [
+ "VtsHalSensorsDefaults",
+ "VtsHalTargetTestDefaults",
+ ],
tidy_timeout_srcs: [
"VtsHalSensorsV1_0TargetTest.cpp",
],
@@ -34,9 +37,12 @@
"SensorsHidlEnvironmentV1_0.cpp",
"VtsHalSensorsV1_0TargetTest.cpp",
],
+ shared_libs: [
+ "libbinder_ndk",
+ "libvndksupport",
+ ],
static_libs: [
"android.hardware.sensors@1.0",
- "VtsHalSensorsTargetTestUtils",
],
test_suites: [
"general-tests",
diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp
index c4ec866..62eaf6b 100644
--- a/sensors/2.0/vts/functional/Android.bp
+++ b/sensors/2.0/vts/functional/Android.bp
@@ -26,7 +26,10 @@
cc_test {
name: "VtsHalSensorsV2_0TargetTest",
cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: [
+ "VtsHalSensorsDefaults",
+ "VtsHalTargetTestDefaults",
+ ],
tidy_timeout_srcs: [
"VtsHalSensorsV2_0TargetTest.cpp",
],
@@ -36,13 +39,15 @@
header_libs: [
"android.hardware.sensors@2.X-shared-utils",
],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
static_libs: [
"android.hardware.sensors@1.0",
"android.hardware.sensors@1.0-convert",
"android.hardware.sensors@2.0",
"android.hardware.sensors@2.1",
"libfmq",
- "VtsHalSensorsTargetTestUtils",
"VtsHalSensorsV2_0TargetTest-lib",
],
test_suites: [
diff --git a/sensors/2.1/vts/functional/Android.bp b/sensors/2.1/vts/functional/Android.bp
index 3659e11..61cfd14 100644
--- a/sensors/2.1/vts/functional/Android.bp
+++ b/sensors/2.1/vts/functional/Android.bp
@@ -28,7 +28,10 @@
cflags: [
"-DLOG_TAG=\"sensors_hidl_hal_test\"",
],
- defaults: ["VtsHalTargetTestDefaults"],
+ defaults: [
+ "VtsHalSensorsDefaults",
+ "VtsHalTargetTestDefaults",
+ ],
srcs: [
"VtsHalSensorsV2_1TargetTest.cpp",
],
@@ -41,7 +44,6 @@
"android.hardware.sensors@2.0",
"android.hardware.sensors@2.1",
"libfmq",
- "VtsHalSensorsTargetTestUtils",
"VtsHalSensorsV2_1TargetTest-lib",
],
test_suites: [
diff --git a/sensors/aidl/default/multihal/ConvertUtils.cpp b/sensors/aidl/default/multihal/ConvertUtils.cpp
index 9b2d8fe..bf56ed5 100644
--- a/sensors/aidl/default/multihal/ConvertUtils.cpp
+++ b/sensors/aidl/default/multihal/ConvertUtils.cpp
@@ -77,6 +77,8 @@
hidlEvent->u.vec3.x = aidlEvent.payload.get<Event::EventPayload::vec3>().x;
hidlEvent->u.vec3.y = aidlEvent.payload.get<Event::EventPayload::vec3>().y;
hidlEvent->u.vec3.z = aidlEvent.payload.get<Event::EventPayload::vec3>().z;
+ hidlEvent->u.vec3.status =
+ (V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::vec3>().status;
break;
case AidlSensorType::GAME_ROTATION_VECTOR:
hidlEvent->u.vec4.x = aidlEvent.payload.get<Event::EventPayload::vec4>().x;
@@ -225,6 +227,7 @@
vec3.x = hidlEvent.u.vec3.x;
vec3.y = hidlEvent.u.vec3.y;
vec3.z = hidlEvent.u.vec3.z;
+ vec3.status = (SensorStatus)hidlEvent.u.vec3.status;
aidlEvent->payload.set<Event::EventPayload::vec3>(vec3);
break;
}
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
index b5a5f15..f3972ec 100644
--- a/sensors/aidl/vts/Android.bp
+++ b/sensors/aidl/vts/Android.bp
@@ -24,8 +24,9 @@
cc_test {
name: "VtsAidlHalSensorsTargetTest",
defaults: [
- "VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
+ "VtsHalSensorsDefaults",
+ "VtsHalTargetTestDefaults",
],
srcs: [
"VtsAidlHalSensorsTargetTest.cpp",
diff --git a/sensors/common/vts/utils/Android.bp b/sensors/common/vts/utils/Android.bp
index 44bed6e..08b6afa 100644
--- a/sensors/common/vts/utils/Android.bp
+++ b/sensors/common/vts/utils/Android.bp
@@ -23,6 +23,23 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+// Prefer to use these defaults to pull in VtsHalSensorsTargetTestUtils + its
+// dependencies
+cc_defaults {
+ name: "VtsHalSensorsDefaults",
+ shared_libs: [
+ "android.hardware.graphics.allocator-V1-ndk",
+ "android.hardware.graphics.common-V3-ndk",
+ "libbinder_ndk",
+ "libutils",
+ "libvndksupport",
+ ],
+ static_libs: [
+ "libaidlcommonsupport",
+ "VtsHalSensorsTargetTestUtils",
+ ],
+}
+
cc_library_static {
name: "VtsHalSensorsTargetTestUtils",
defaults: ["VtsHalTargetTestDefaults"],
@@ -36,13 +53,19 @@
local_include_dirs: [
"include/sensors-vts-utils",
],
+ // Targets that depend on us need to also include these
shared_libs: [
+ "android.hardware.graphics.allocator-V1-ndk",
+ "android.hardware.graphics.common-V3-ndk",
+ "libbinder_ndk",
"libutils",
+ "libvndksupport",
],
static_libs: [
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
"android.hardware.sensors@2.1",
+ "libaidlcommonsupport",
],
whole_static_libs: [
"android.hardware.graphics.allocator@2.0",
diff --git a/sensors/common/vts/utils/GrallocWrapper.cpp b/sensors/common/vts/utils/GrallocWrapper.cpp
index 47d1f42..e6e0888 100644
--- a/sensors/common/vts/utils/GrallocWrapper.cpp
+++ b/sensors/common/vts/utils/GrallocWrapper.cpp
@@ -16,6 +16,9 @@
#include "GrallocWrapper.h"
+#include <aidl/android/hardware/graphics/allocator/IAllocator.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android/binder_manager.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
@@ -27,8 +30,10 @@
#include <utils/Log.h>
#include <cinttypes>
+#include <memory>
#include <type_traits>
+using IAllocatorAidl = ::aidl::android::hardware::graphics::allocator::IAllocator;
using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
using IAllocator4 = ::android::hardware::graphics::allocator::V4_0::IAllocator;
@@ -41,6 +46,9 @@
using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
using Error4 = ::android::hardware::graphics::mapper::V4_0::Error;
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::graphics::allocator::AllocationResult;
+
using ::android::hardware::graphics::common::V1_0::BufferUsage;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
@@ -97,10 +105,11 @@
// Since all the type and function names are the same for the things we use across the major HAL
// versions, we use template magic to avoid repeating ourselves.
-template <typename AllocatorT, typename MapperT>
+template <typename AllocatorT, typename MapperT,
+ template <typename> typename AllocatorWrapperT = sp>
class GrallocHalWrapper : public IGrallocHalWrapper {
public:
- GrallocHalWrapper(const sp<AllocatorT>& allocator, const sp<MapperT>& mapper)
+ GrallocHalWrapper(const AllocatorWrapperT<AllocatorT>& allocator, const sp<MapperT>& mapper)
: mAllocator(allocator), mMapper(mapper) {
if (mapper->isRemote()) {
ALOGE("Mapper is in passthrough mode");
@@ -116,7 +125,7 @@
private:
static constexpr uint64_t kBufferUsage =
static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::CPU_READ_OFTEN);
- sp<AllocatorT> mAllocator;
+ AllocatorWrapperT<AllocatorT> mAllocator;
sp<MapperT> mMapper;
// v2.0 and v3.0 use vec<uint32_t> for BufferDescriptor, but v4.0 uses vec<uint8_t>, so use
@@ -128,8 +137,34 @@
native_handle_t* importBuffer(const hidl_handle& rawHandle);
};
-template <typename AllocatorT, typename MapperT>
-native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::allocate(uint32_t size) {
+template <>
+native_handle_t* GrallocHalWrapper<IAllocatorAidl, IMapper4, std::shared_ptr>::allocate(
+ uint32_t size) {
+ constexpr uint32_t kBufferCount = 1;
+ BufferDescriptorT descriptor = getDescriptor(size);
+ native_handle_t* bufferHandle = nullptr;
+
+ AllocationResult result;
+ auto status = mAllocator->allocate(descriptor, kBufferCount, &result);
+ if (!status.isOk()) {
+ status_t error = status.getExceptionCode();
+ ALOGE("Failed to allocate buffer: %" PRId32, static_cast<int32_t>(error));
+ } else if (result.buffers.size() != kBufferCount) {
+ ALOGE("Invalid buffer array size (got %zu, expected %" PRIu32 ")", result.buffers.size(),
+ kBufferCount);
+ } else {
+ // Convert from AIDL NativeHandle to native_handle_t to hidl_handle
+ hidl_handle hidlHandle;
+ hidlHandle.setTo(dupFromAidl(result.buffers[0]), /*shouldOwn*/ true);
+ bufferHandle = importBuffer(hidlHandle);
+ }
+
+ return bufferHandle;
+}
+
+template <typename AllocatorT, typename MapperT, template <typename> typename AllocatorWrapperT>
+native_handle_t* GrallocHalWrapper<AllocatorT, MapperT, AllocatorWrapperT>::allocate(
+ uint32_t size) {
constexpr uint32_t kBufferCount = 1;
BufferDescriptorT descriptor = getDescriptor(size);
native_handle_t* bufferHandle = nullptr;
@@ -149,17 +184,18 @@
return bufferHandle;
}
-template <typename AllocatorT, typename MapperT>
-void GrallocHalWrapper<AllocatorT, MapperT>::freeBuffer(native_handle_t* bufferHandle) {
+template <typename AllocatorT, typename MapperT, template <typename> typename AllocatorWrapperT>
+void GrallocHalWrapper<AllocatorT, MapperT, AllocatorWrapperT>::freeBuffer(
+ native_handle_t* bufferHandle) {
auto error = mMapper->freeBuffer(bufferHandle);
if (!error.isOk() || failed(error)) {
ALOGE("Failed to free buffer %p", bufferHandle);
}
}
-template <typename AllocatorT, typename MapperT>
-typename GrallocHalWrapper<AllocatorT, MapperT>::BufferDescriptorT
-GrallocHalWrapper<AllocatorT, MapperT>::getDescriptor(uint32_t size) {
+template <typename AllocatorT, typename MapperT, template <typename> typename AllocatorWrapperT>
+typename GrallocHalWrapper<AllocatorT, MapperT, AllocatorWrapperT>::BufferDescriptorT
+GrallocHalWrapper<AllocatorT, MapperT, AllocatorWrapperT>::getDescriptor(uint32_t size) {
typename MapperT::BufferDescriptorInfo descriptorInfo = {
.width = size,
.height = 1,
@@ -181,8 +217,8 @@
return descriptor;
}
-template <typename AllocatorT, typename MapperT>
-native_handle_t* GrallocHalWrapper<AllocatorT, MapperT>::importBuffer(
+template <typename AllocatorT, typename MapperT, template <typename> typename AllocatorWrapperT>
+native_handle_t* GrallocHalWrapper<AllocatorT, MapperT, AllocatorWrapperT>::importBuffer(
const hidl_handle& rawHandle) {
native_handle_t* bufferHandle = nullptr;
@@ -198,8 +234,9 @@
return bufferHandle;
}
-template <typename AllocatorT, typename MapperT>
-void* GrallocHalWrapper<AllocatorT, MapperT>::lock(native_handle_t* bufferHandle) {
+template <typename AllocatorT, typename MapperT, template <typename> typename AllocatorWrapperT>
+void* GrallocHalWrapper<AllocatorT, MapperT, AllocatorWrapperT>::lock(
+ native_handle_t* bufferHandle) {
// Per the HAL, all-zeros Rect means the entire buffer
typename MapperT::Rect accessRegion = {};
hidl_handle acquireFenceHandle; // No fence needed, already safe to lock
@@ -218,8 +255,9 @@
return data;
}
-template <typename AllocatorT, typename MapperT>
-void GrallocHalWrapper<AllocatorT, MapperT>::unlock(native_handle_t* bufferHandle) {
+template <typename AllocatorT, typename MapperT, template <typename> typename AllocatorWrapperT>
+void GrallocHalWrapper<AllocatorT, MapperT, AllocatorWrapperT>::unlock(
+ native_handle_t* bufferHandle) {
mMapper->unlock(bufferHandle, [&](auto error, const hidl_handle& /*releaseFence*/) {
if (failed(error)) {
ALOGE("Failed to unlock buffer %p: %" PRId32, bufferHandle,
@@ -234,8 +272,22 @@
sp<IAllocator4> allocator4 = IAllocator4::getService();
sp<IMapper4> mapper4 = IMapper4::getService();
- if (allocator4 != nullptr && mapper4 != nullptr) {
- ALOGD("Using IAllocator/IMapper v4.0");
+ const auto kAllocatorSvc = std::string(IAllocatorAidl::descriptor) + "/default";
+ std::shared_ptr<IAllocatorAidl> allocatorAidl;
+ if (AServiceManager_isDeclared(kAllocatorSvc.c_str())) {
+ allocatorAidl = IAllocatorAidl::fromBinder(
+ ndk::SpAIBinder(AServiceManager_checkService(kAllocatorSvc.c_str())));
+ }
+
+ // As of T, AIDL Allocator is supported only with HIDL Mapper4
+ // (ref: VtsHalGraphicsAllocatorAidl_TargetTest.cpp)
+ if (allocatorAidl != nullptr && mapper4 != nullptr) {
+ ALOGD("Using AIDL IAllocator + HIDL IMapper v4.0");
+ mGrallocHal = std::unique_ptr<IGrallocHalWrapper>(
+ new GrallocHalWrapper<IAllocatorAidl, IMapper4, std::shared_ptr>(allocatorAidl,
+ mapper4));
+ } else if (allocator4 != nullptr && mapper4 != nullptr) {
+ ALOGD("AIDL IAllocator not found, using HIDL IAllocator/IMapper v4.0");
mGrallocHal = std::unique_ptr<IGrallocHalWrapper>(
new GrallocHalWrapper<IAllocator4, IMapper4>(allocator4, mapper4));
} else {
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index a1f51df..2ff0c3d 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#include <aidl/android/hardware/tv/tuner/Result.h>
-
#include "FrontendTests.h"
+#include <aidl/android/hardware/tv/tuner/Result.h>
+
ndk::ScopedAStatus FrontendCallback::onEvent(FrontendEventType frontendEventType) {
android::Mutex::Autolock autoLock(mMsgLock);
ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
@@ -323,7 +323,10 @@
FrontendStatusType type = statusTypes[i];
switch (type) {
case FrontendStatusType::MODULATIONS: {
- // TODO: verify modulations
+ ASSERT_TRUE(std::equal(
+ realStatuses[i].get<FrontendStatus::Tag::modulations>().begin(),
+ realStatuses[i].get<FrontendStatus::Tag::modulations>().end(),
+ expectStatuses[i].get<FrontendStatus::Tag::modulations>().begin()));
break;
}
case FrontendStatusType::BERS: {
@@ -340,11 +343,13 @@
break;
}
case FrontendStatusType::GUARD_INTERVAL: {
- // TODO: verify interval
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::interval>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::interval>());
break;
}
case FrontendStatusType::TRANSMISSION_MODE: {
- // TODO: verify tranmission mode
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::transmissionMode>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::transmissionMode>());
break;
}
case FrontendStatusType::UEC: {
@@ -379,7 +384,8 @@
break;
}
case FrontendStatusType::ROLL_OFF: {
- // TODO: verify roll off
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::rollOff>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::rollOff>());
break;
}
case FrontendStatusType::IS_MISO: {
@@ -599,9 +605,10 @@
ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
// TODO: find a better way to push all frontend status types
- for (int32_t i = 0; i < static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
+ for (int32_t i = 0; i <= static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
allTypes.push_back(static_cast<FrontendStatusType>(i));
}
+
ndk::ScopedAStatus status = mFrontend->getFrontendStatusReadiness(allTypes, &readiness);
ASSERT_TRUE(status.isOk());
ASSERT_TRUE(readiness.size() == allTypes.size());
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index edd8dd6..81d26ba 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -68,6 +68,11 @@
iuwb_ = IUwb::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
ASSERT_NE(iuwb_, nullptr);
}
+ virtual void TearDown() override {
+ // Trigger HAL close at end of each test.
+ const auto iuwb_chip = getAnyChip();
+ iuwb_chip->close();
+ }
std::shared_ptr<IUwb> iuwb_;
// TODO (b/197638976): We pick the first chip here. Need to fix this
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index ddc6ee0..01602ab 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -59,7 +59,10 @@
const std::shared_ptr<IVibratorCallback>& callback) {
LOG(VERBOSE) << "Vibrator on for timeoutMs: " << timeoutMs;
if (callback != nullptr) {
- std::thread([=] {
+ // Note that thread lambdas aren't using implicit capture [=], to avoid capturing "this",
+ // which may be asynchronously destructed.
+ // If "this" is needed, use [sharedThis = this->ref<Vibrator>()].
+ std::thread([timeoutMs, callback] {
LOG(VERBOSE) << "Starting on on another thread";
usleep(timeoutMs * 1000);
LOG(VERBOSE) << "Notifying on complete";
@@ -87,7 +90,7 @@
constexpr size_t kEffectMillis = 100;
if (callback != nullptr) {
- std::thread([=] {
+ std::thread([callback] {
LOG(VERBOSE) << "Starting perform on another thread";
usleep(kEffectMillis * 1000);
LOG(VERBOSE) << "Notifying perform complete";
@@ -174,7 +177,8 @@
}
}
- std::thread([=] {
+ // The thread may theoretically outlive the vibrator, so take a proper reference to it.
+ std::thread([sharedThis = this->ref<Vibrator>(), composite, callback] {
LOG(VERBOSE) << "Starting compose on another thread";
for (auto& e : composite) {
@@ -185,7 +189,7 @@
<< e.scale;
int32_t durationMs;
- getPrimitiveDuration(e.primitive, &durationMs);
+ sharedThis->getPrimitiveDuration(e.primitive, &durationMs);
usleep(durationMs * 1000);
}
@@ -396,7 +400,7 @@
}
}
- std::thread([=] {
+ std::thread([totalDuration, callback] {
LOG(VERBOSE) << "Starting composePwle on another thread";
usleep(totalDuration * 1000);
if (callback != nullptr) {
diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp
index 7cf9e6a..26edf5a 100644
--- a/vibrator/aidl/default/VibratorManager.cpp
+++ b/vibrator/aidl/default/VibratorManager.cpp
@@ -66,7 +66,7 @@
ndk::ScopedAStatus VibratorManager::triggerSynced(
const std::shared_ptr<IVibratorCallback>& callback) {
LOG(INFO) << "Vibrator Manager trigger synced";
- std::thread([=] {
+ std::thread([callback] {
if (callback != nullptr) {
LOG(INFO) << "Notifying perform complete";
callback->onComplete();
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 3841715..791d7e8 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -332,6 +332,7 @@
sleep(1);
EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
sleep(1);
+ EXPECT_TRUE(vibrator->off().isOk());
}
}