Merge changes from topic "IFace-enrollment-API"
* changes:
Update the VTS test
Update the default implementation
Update the enrollment API
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/authsecret/aidl/vts/OWNERS b/authsecret/aidl/vts/OWNERS
new file mode 100644
index 0000000..40d95e4
--- /dev/null
+++ b/authsecret/aidl/vts/OWNERS
@@ -0,0 +1,2 @@
+chengyouho@google.com
+frankwoo@google.com
diff --git a/bluetooth/1.0/default/test/bluetooth_address_test.cc b/bluetooth/1.0/default/test/bluetooth_address_test.cc
index ee52d33..422d6a3 100644
--- a/bluetooth/1.0/default/test/bluetooth_address_test.cc
+++ b/bluetooth/1.0/default/test/bluetooth_address_test.cc
@@ -14,7 +14,6 @@
// limitations under the License.
//
-#include <cutils/properties.h>
#include <errno.h>
#include <fcntl.h>
#include <gtest/gtest.h>
@@ -39,12 +38,6 @@
"00:00:00:00:00:00";
constexpr uint8_t kZeros_bytes[BluetoothAddress::kBytes] = {0x00, 0x00, 0x00,
0x00, 0x00, 0x00};
-constexpr char kTestAddrBad1[BluetoothAddress::kStringLength + 1] =
- "bb:aa:dd:00:00:01";
-constexpr uint8_t kTestAddrBad1_bytes[BluetoothAddress::kBytes] = {
- 0xbb, 0xaa, 0xdd, 0x00, 0x00, 0x01};
-
-constexpr char kAddrPath[] = "/tmp/my_address_in_a_file.txt";
class BluetoothAddressTest : public ::testing::Test {
public:
@@ -120,45 +113,6 @@
EXPECT_FALSE(memcmp(addrA, addrB, BluetoothAddress::kStringLength) == 0);
}
-TEST_F(BluetoothAddressTest, get_local_address) {
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, "") == 0);
- EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, "") == 0);
- uint8_t address[BluetoothAddress::kBytes];
-
- // File contains a non-zero Address.
- FileWriteString(kAddrPath, kTestAddr1);
- EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, kAddrPath) == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
-
- // File contains a zero address. A random address will be generated.
- FileWriteString(kAddrPath, kZeros);
- EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, kAddrPath) == 0);
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddrBad1) == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kZeros_bytes, BluetoothAddress::kBytes) != 0);
- char prop[PROP_VALUE_MAX] = "Before reading";
- EXPECT_TRUE(property_get(PERSIST_BDADDR_PROPERTY, prop, NULL) ==
- BluetoothAddress::kStringLength);
- char address_str[BluetoothAddress::kStringLength + 1];
- BluetoothAddress::bytes_to_string(address, address_str);
- EXPECT_TRUE(memcmp(address_str, prop, BluetoothAddress::kStringLength) == 0);
-
- // Factory property contains an address.
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddrBad1) == 0);
- EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, kTestAddr1) == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
-
- // Persistent property contains an address.
- memcpy(address, kTestAddrBad1_bytes, BluetoothAddress::kBytes);
- EXPECT_TRUE(property_set(PERSIST_BDADDR_PROPERTY, kTestAddr1) == 0);
- EXPECT_TRUE(property_set(FACTORY_BDADDR_PROPERTY, "") == 0);
- EXPECT_TRUE(property_set(PROPERTY_BT_BDADDR_PATH, "") == 0);
- EXPECT_TRUE(BluetoothAddress::get_local_address(address));
- EXPECT_TRUE(memcmp(address, kTestAddr1_bytes, BluetoothAddress::kBytes) == 0);
-}
-
} // namespace implementation
} // namespace V1_0
} // namespace bluetooth
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index b8676b0..cdf72ae 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -198,7 +198,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.drm</name>
- <version>1.3</version>
+ <version>1.3-4</version>
<interface>
<name>ICryptoFactory</name>
<regex-instance>.*</regex-instance>
@@ -287,6 +287,14 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.health.storage</name>
+ <version>1</version>
+ <interface>
+ <name>IStorage</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.identity</name>
<version>1-2</version>
<interface>
diff --git a/drm/1.4/Android.bp b/drm/1.4/Android.bp
new file mode 100644
index 0000000..8e1dc93
--- /dev/null
+++ b/drm/1.4/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.drm@1.4",
+ root: "android.hardware",
+ srcs: [
+ "ICryptoFactory.hal",
+ "ICryptoPlugin.hal",
+ "IDrmFactory.hal",
+ "IDrmPlugin.hal",
+ ],
+ interfaces: [
+ "android.hardware.drm@1.0",
+ "android.hardware.drm@1.1",
+ "android.hardware.drm@1.2",
+ "android.hardware.drm@1.3",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/drm/1.4/ICryptoFactory.hal b/drm/1.4/ICryptoFactory.hal
new file mode 100644
index 0000000..6cbf9e3
--- /dev/null
+++ b/drm/1.4/ICryptoFactory.hal
@@ -0,0 +1,32 @@
+/*
+ * 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.drm@1.4;
+
+import @1.3::ICryptoFactory;
+
+/**
+ * ICryptoFactory is the main entry point for interacting with a vendor's
+ * crypto HAL to create crypto plugins. Crypto plugins create crypto sessions
+ * which are used by a codec to decrypt protected video content.
+ *
+ * The 1.4 factory must always create 1.4 ICryptoPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ *
+ * To use 1.4 features the caller must cast the returned interface to a
+ * 1.4 HAL, using V1_4::ICryptoPlugin::castFrom().
+ */
+interface ICryptoFactory extends @1.3::ICryptoFactory {
+};
diff --git a/drm/1.4/ICryptoPlugin.hal b/drm/1.4/ICryptoPlugin.hal
new file mode 100644
index 0000000..874ef4c
--- /dev/null
+++ b/drm/1.4/ICryptoPlugin.hal
@@ -0,0 +1,26 @@
+/**
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.drm@1.4;
+
+import @1.2::ICryptoPlugin;
+
+/**
+ * ICryptoPlugin is the HAL for vendor-provided crypto plugins.
+ * It allows crypto sessions to be opened and operated on, to
+ * load crypto keys for a codec to decrypt protected video content.
+ */
+interface ICryptoPlugin extends @1.2::ICryptoPlugin {
+};
diff --git a/drm/1.4/IDrmFactory.hal b/drm/1.4/IDrmFactory.hal
new file mode 100644
index 0000000..035a298
--- /dev/null
+++ b/drm/1.4/IDrmFactory.hal
@@ -0,0 +1,34 @@
+/*
+ * 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.drm@1.4;
+
+import @1.3::IDrmFactory;
+
+/**
+ * IDrmFactory is the main entry point for interacting with a vendor's
+ * drm HAL to create drm plugin instances. A drm plugin instance
+ * creates drm sessions which are used to obtain keys for a crypto
+ * session so it can decrypt protected video content.
+ *
+ * The 1.4 factory must always create 1.4 IDrmPlugin interfaces, which are
+ * returned via the 1.0 createPlugin method.
+ *
+ * To use 1.4 features the caller must cast the returned interface to a
+ * 1.4 HAL, using V1_4::IDrmPlugin::castFrom().
+ */
+
+interface IDrmFactory extends @1.3::IDrmFactory {
+};
diff --git a/drm/1.4/IDrmPlugin.hal b/drm/1.4/IDrmPlugin.hal
new file mode 100644
index 0000000..e8af230
--- /dev/null
+++ b/drm/1.4/IDrmPlugin.hal
@@ -0,0 +1,64 @@
+/**
+ * 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.drm@1.4;
+
+import @1.0::Status;
+import @1.0::SessionId;
+import @1.1::SecurityLevel;
+import @1.2::IDrmPlugin;
+
+/**
+ * IDrmPlugin is used to interact with a specific drm plugin that was
+ * created by IDrmFactory::createPlugin. A drm plugin provides methods for
+ * obtaining drm keys to be used by a codec to decrypt protected video
+ * content.
+ */
+interface IDrmPlugin extends @1.2::IDrmPlugin {
+
+ /**
+ * Check if the specified mime-type & security level require a secure decoder
+ * component.
+ *
+ * @param mime The content mime-type
+ * @param level the requested security level
+ * @return secureRequired must be true if and only if a secure decoder is required
+ * for the specified mime-type & security level
+ */
+ requiresSecureDecoder(string mime, @1.1::SecurityLevel level) generates (bool secureRequired);
+
+ /**
+ * Check if the specified mime-type requires a secure decoder component
+ * at the highest security level supported on the device.
+ *
+ * @param mime The content mime-type
+ * @return secureRequired must be true if and only if a secure decoder is required
+ * for the specified mime-type
+ */
+ 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/default/Android.bp b/health/1.0/default/Android.bp
index aab9cc7..ff4b875 100644
--- a/health/1.0/default/Android.bp
+++ b/health/1.0/default/Android.bp
@@ -17,62 +17,3 @@
],
}
-
-cc_library_static {
- name: "android.hardware.health@1.0-impl-helper",
- vendor: true,
- srcs: ["Health.cpp"],
-
- header_libs: [
- "libbase_headers",
- "libhealthd_headers",
- ],
-
- shared_libs: [
- "libcutils",
- "libhidlbase",
- "liblog",
- "libutils",
- "android.hardware.health@1.0",
- ],
-
- static_libs: [
- "android.hardware.health@1.0-convert",
- ],
-}
-
-cc_library_shared {
- name: "android.hardware.health@1.0-impl",
- vendor: true,
- relative_install_path: "hw",
-
- static_libs: [
- "android.hardware.health@1.0-impl-helper",
- "android.hardware.health@1.0-convert",
- "libhealthd.default",
- ],
-
- shared_libs: [
- "libhidlbase",
- "libutils",
- "android.hardware.health@1.0",
- ],
-}
-
-cc_binary {
- name: "android.hardware.health@1.0-service",
- vendor: true,
- relative_install_path: "hw",
- init_rc: ["android.hardware.health@1.0-service.rc"],
- srcs: ["HealthService.cpp"],
-
- shared_libs: [
- "liblog",
- "libcutils",
- "libdl",
- "libbase",
- "libutils",
- "libhidlbase",
- "android.hardware.health@1.0",
- ],
-}
diff --git a/health/1.0/default/Health.cpp b/health/1.0/default/Health.cpp
deleted file mode 100644
index 1a02956..0000000
--- a/health/1.0/default/Health.cpp
+++ /dev/null
@@ -1,93 +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.
- */
-
-#define LOG_TAG "health-hal"
-
-#include <Health.h>
-#include <include/hal_conversion.h>
-
-namespace android {
-namespace hardware {
-namespace health {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::health::V1_0::hal_conversion::convertToHealthConfig;
-using ::android::hardware::health::V1_0::hal_conversion::convertFromHealthConfig;
-using ::android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
-using ::android::hardware::health::V1_0::hal_conversion::convertFromHealthInfo;
-
-// Methods from ::android::hardware::health::V1_0::IHealth follow.
-Return<void> Health::init(const HealthConfig& config, init_cb _hidl_cb) {
- struct healthd_config healthd_config = {};
- HealthConfig configOut;
-
- // To keep working with existing healthd static HALs,
- // convert the new HealthConfig to the old healthd_config
- // and back.
-
- convertFromHealthConfig(config, &healthd_config);
- healthd_board_init(&healthd_config);
- mGetEnergyCounter = healthd_config.energyCounter;
- convertToHealthConfig(&healthd_config, configOut);
-
- _hidl_cb(configOut);
-
- return Void();
-}
-
-Return<void> Health::update(const HealthInfo& info, update_cb _hidl_cb) {
- struct android::BatteryProperties p = {};
- HealthInfo infoOut;
-
- // To keep working with existing healthd static HALs,
- // convert the new HealthInfo to android::Batteryproperties
- // and back.
-
- convertFromHealthInfo(info, &p);
- int skipLogging = healthd_board_battery_update(&p);
- convertToHealthInfo(&p, infoOut);
-
- _hidl_cb(!!skipLogging, infoOut);
-
- return Void();
-}
-
-Return<void> Health::energyCounter(energyCounter_cb _hidl_cb) {
- int64_t energy = 0;
- Result result = Result::NOT_SUPPORTED;
-
- if (mGetEnergyCounter) {
- int status = mGetEnergyCounter(&energy);
- if (status == 0) {
- result = Result::SUCCESS;
- }
- }
-
- _hidl_cb(result, energy);
-
- return Void();
-}
-
-IHealth* HIDL_FETCH_IHealth(const char* /* name */) {
- return new Health();
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace health
-} // namespace hardware
-} // namespace android
diff --git a/health/1.0/default/Health.h b/health/1.0/default/Health.h
deleted file mode 100644
index ed364c1..0000000
--- a/health/1.0/default/Health.h
+++ /dev/null
@@ -1,57 +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.
- */
-#ifndef ANDROID_HARDWARE_HEALTH_V1_0_HEALTH_H
-#define ANDROID_HARDWARE_HEALTH_V1_0_HEALTH_H
-
-#include <android/hardware/health/1.0/IHealth.h>
-#include <hidl/Status.h>
-#include <hidl/MQDescriptor.h>
-#include <healthd/healthd.h>
-#include <utils/String8.h>
-
-namespace android {
-namespace hardware {
-namespace health {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::health::V1_0::HealthInfo;
-using ::android::hardware::health::V1_0::HealthConfig;
-using ::android::hardware::health::V1_0::IHealth;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-struct Health : public IHealth {
- // Methods from ::android::hardware::health::V1_0::IHealth follow.
- Return<void> init(const HealthConfig& config, init_cb _hidl_cb) override;
- Return<void> update(const HealthInfo& info, update_cb _hidl_cb) override;
- Return<void> energyCounter(energyCounter_cb _hidl_cb) override;
-private:
- std::function<int(int64_t *)> mGetEnergyCounter;
-};
-
-extern "C" IHealth* HIDL_FETCH_IHealth(const char* name);
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace health
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_HEALTH_V1_0_HEALTH_H
diff --git a/health/1.0/default/HealthService.cpp b/health/1.0/default/HealthService.cpp
deleted file mode 100644
index 55848d2..0000000
--- a/health/1.0/default/HealthService.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#define LOG_TAG "android.hardware.health@1.0-service"
-
-#include <android/hardware/health/1.0/IHealth.h>
-#include <hidl/LegacySupport.h>
-
-using android::hardware::health::V1_0::IHealth;
-using android::hardware::defaultPassthroughServiceImplementation;
-
-int main() {
- return defaultPassthroughServiceImplementation<IHealth>();
-}
diff --git a/health/1.0/default/README.md b/health/1.0/default/README.md
deleted file mode 100644
index 1ded7de..0000000
--- a/health/1.0/default/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-# Implement the 2.1 HAL instead!
-
-It is strongly recommended that you implement the 2.1 HAL directly. See
-`hardware/interfaces/health/2.1/README.md` for more details.
-
-# Implement Health 1.0 HAL
-
-1. Install common binderized service. The binderized service `dlopen()`s
- passthrough implementations on the device, so there is no need to write
- your own.
-
- ```mk
- # Install default binderized implementation to vendor.
- PRODUCT_PACKAGES += android.hardware.health@1.0-service
- ```
-
-1. Add proper VINTF manifest entry to your device manifest. Example:
-
- ```xml
- <hal format="hidl">
- <name>android.hardware.health</name>
- <transport>hwbinder</transport>
- <version>1.0</version>
- <interface>
- <name>IHealth</name>
- <instance>default</instance>
- </interface>
- </hal>
- ```
-
-1. Install the proper passthrough implemetation.
-
- 1. If you want to use the default implementation (with default `libhealthd`),
- add the following to `device.mk`:
-
- ```mk
- PRODUCT_PACKAGES += \
- android.hardware.health@1.0-impl
- ```
-
- 1. Otherwise, if you have a customized `libhealthd.<board>`:
-
- 1. Define your passthrough implementation. Example (replace `<device>`
- and `<board>` accordingly):
-
- ```bp
- cc_library_shared {
- name: "android.hardware.health@1.0-impl-<device>",
- vendor: true,
- relative_install_path: "hw",
-
- static_libs: [
- "android.hardware.health@1.0-impl-helper",
- "android.hardware.health@1.0-convert",
- "libhealthd.<board>",
- ],
- }
- ```
-
- 1. Add to `device.mk`.
-
- ```
- PRODUCT_PACKAGES += android.hardware.health@1.0-impl-<device>
- ```
-
- 1. Define appropriate SELinux permissions.
diff --git a/health/1.0/default/android.hardware.health@1.0-service.rc b/health/1.0/default/android.hardware.health@1.0-service.rc
deleted file mode 100644
index 569dc88..0000000
--- a/health/1.0/default/android.hardware.health@1.0-service.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.health-hal-1-0 /vendor/bin/hw/android.hardware.health@1.0-service
- class hal
- user system
- group system
- capabilities WAKE_ALARM BLOCK_SUSPEND
diff --git a/health/1.0/default/libhealthd/Android.bp b/health/1.0/default/libhealthd/Android.bp
deleted file mode 100644
index 43463eb..0000000
--- a/health/1.0/default/libhealthd/Android.bp
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2016 The Android Open Source Project
-
-cc_library_static {
- srcs: ["healthd_board_default.cpp"],
- name: "libhealthd.default",
- vendor_available: true,
- recovery_available: true,
- cflags: ["-Werror"],
- include_dirs: ["system/libbase/include"],
- header_libs: ["libhealthd_headers"],
-}
diff --git a/health/1.0/vts/functional/Android.bp b/health/1.0/vts/functional/Android.bp
deleted file mode 100644
index f4a04a7..0000000
--- a/health/1.0/vts/functional/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (C) 2017 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: "VtsHalHealthV1_0TargetTest",
- defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["VtsHalHealthV1_0TargetTest.cpp"],
- static_libs: ["android.hardware.health@1.0"],
- test_suites: ["general-tests", "vts"],
-}
diff --git a/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp b/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp
deleted file mode 100644
index 8b3dcc1..0000000
--- a/health/1.0/vts/functional/VtsHalHealthV1_0TargetTest.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "health_hidl_hal_test"
-
-#include <android/hardware/health/1.0/IHealth.h>
-#include <android/hardware/health/1.0/types.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-#include <log/log.h>
-
-using HealthConfig = ::android::hardware::health::V1_0::HealthConfig;
-using HealthInfo = ::android::hardware::health::V1_0::HealthInfo;
-using IHealth = ::android::hardware::health::V1_0::IHealth;
-using Result = ::android::hardware::health::V1_0::Result;
-
-using ::android::sp;
-
-class HealthHidlTest : public ::testing::TestWithParam<std::string> {
- public:
- virtual void SetUp() override {
- health = IHealth::getService(GetParam());
- ASSERT_NE(health, nullptr);
- health->init(config,
- [&](const auto& halConfigOut) { config = halConfigOut; });
- }
-
- sp<IHealth> health;
- HealthConfig config;
-};
-
-/**
- * Ensure EnergyCounter call returns positive energy counter or NOT_SUPPORTED
- */
-TEST_P(HealthHidlTest, TestEnergyCounter) {
- Result result;
- int64_t energy = 0;
- health->energyCounter([&](Result ret, int64_t energyOut) {
- result = ret;
- energy = energyOut;
- });
-
- ASSERT_TRUE(result == Result::SUCCESS || result == Result::NOT_SUPPORTED);
- ASSERT_TRUE(result != Result::SUCCESS || energy > 0);
-}
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HealthHidlTest);
-INSTANTIATE_TEST_SUITE_P(
- PerInstance, HealthHidlTest,
- testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHealth::descriptor)),
- android::hardware::PrintInstanceNameToString);
diff --git a/health/storage/1.0/default/Android.bp b/health/storage/1.0/default/Android.bp
index 3156dfe..3834244 100644
--- a/health/storage/1.0/default/Android.bp
+++ b/health/storage/1.0/default/Android.bp
@@ -38,6 +38,7 @@
],
static_libs: [
+ "libhealth_storage_impl_common",
"libfstab",
],
diff --git a/health/storage/1.0/default/Storage.cpp b/health/storage/1.0/default/Storage.cpp
index 561deaa..02b6a3d 100644
--- a/health/storage/1.0/default/Storage.cpp
+++ b/health/storage/1.0/default/Storage.cpp
@@ -18,11 +18,8 @@
#include <sstream>
-#include <android-base/chrono_utils.h>
-#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <fstab/fstab.h>
+#include <health-storage-impl/common.h>
namespace android {
namespace hardware {
@@ -31,69 +28,9 @@
namespace V1_0 {
namespace implementation {
-using base::ReadFileToString;
-using base::Timer;
-using base::Trim;
-using base::WriteStringToFd;
-using base::WriteStringToFile;
-using fs_mgr::Fstab;
-using fs_mgr::ReadDefaultFstab;
-
-std::string getGarbageCollectPath() {
- Fstab fstab;
- ReadDefaultFstab(&fstab);
-
- for (const auto& entry : fstab) {
- if (!entry.sysfs_path.empty()) {
- return entry.sysfs_path + "/manual_gc";
- }
- }
-
- return "";
-}
-
Return<void> Storage::garbageCollect(uint64_t timeoutSeconds,
const sp<IGarbageCollectCallback>& cb) {
- Result result = Result::SUCCESS;
- std::string path = getGarbageCollectPath();
-
- if (path.empty()) {
- LOG(WARNING) << "Cannot find Dev GC path";
- result = Result::UNKNOWN_ERROR;
- } else {
- Timer timer;
- LOG(INFO) << "Start Dev GC on " << path;
- while (1) {
- std::string require;
- if (!ReadFileToString(path, &require)) {
- PLOG(WARNING) << "Reading manual_gc failed in " << path;
- result = Result::IO_ERROR;
- break;
- }
- require = Trim(require);
- if (require == "" || require == "off" || require == "disabled") {
- LOG(DEBUG) << "No more to do Dev GC";
- break;
- }
- LOG(DEBUG) << "Trigger Dev GC on " << path;
- if (!WriteStringToFile("1", path)) {
- PLOG(WARNING) << "Start Dev GC failed on " << path;
- result = Result::IO_ERROR;
- break;
- }
- if (timer.duration() >= std::chrono::seconds(timeoutSeconds)) {
- LOG(WARNING) << "Dev GC timeout";
- // Timeout is not treated as an error. Try next time.
- break;
- }
- sleep(2);
- }
- LOG(INFO) << "Stop Dev GC on " << path;
- if (!WriteStringToFile("0", path)) {
- PLOG(WARNING) << "Stop Dev GC failed on " << path;
- result = Result::IO_ERROR;
- }
- }
+ Result result = GarbageCollect(timeoutSeconds);
if (cb != nullptr) {
auto ret = cb->onFinish(result);
@@ -110,28 +47,7 @@
}
int fd = handle->data[0];
- std::stringstream output;
-
- std::string path = getGarbageCollectPath();
- if (path.empty()) {
- output << "Cannot find Dev GC path";
- } else {
- std::string require;
-
- if (ReadFileToString(path, &require)) {
- output << path << ":" << require << std::endl;
- }
-
- if (WriteStringToFile("0", path)) {
- output << "stop success" << std::endl;
- }
- }
-
- if (!WriteStringToFd(output.str(), fd)) {
- PLOG(WARNING) << "debug: cannot write to fd";
- }
-
- fsync(fd);
+ DebugDump(fd);
return Void();
}
diff --git a/health/storage/1.0/vts/functional/Android.bp b/health/storage/1.0/vts/functional/Android.bp
index 2201031..731ad62 100644
--- a/health/storage/1.0/vts/functional/Android.bp
+++ b/health/storage/1.0/vts/functional/Android.bp
@@ -19,6 +19,9 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalHealthStorageV1_0TargetTest.cpp"],
static_libs: ["android.hardware.health.storage@1.0"],
+ header_libs: [
+ "libhealth_storage_test_common_headers",
+ ],
shared_libs: [
"libhidlbase",
],
diff --git a/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp b/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
index 24ddc5d..ddb6b5a 100644
--- a/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
+++ b/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
@@ -14,14 +14,17 @@
* limitations under the License.
*/
+#include <unistd.h>
+
+#include <thread>
+
#include <android-base/logging.h>
#include <android/hardware/health/storage/1.0/IStorage.h>
#include <gtest/gtest.h>
+#include <health-storage-test/common.h>
#include <hidl/GtestPrinter.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/ServiceManagement.h>
-#include <unistd.h>
-#include <thread>
namespace android {
namespace hardware {
@@ -29,61 +32,17 @@
namespace storage {
namespace V1_0 {
+using namespace ::android::hardware::health::storage::test;
using ::std::literals::chrono_literals::operator""ms;
#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) << ret.description()
-// Dev GC timeout. This is the timeout used by vold.
-const uint64_t kDevGcTimeoutSec = 120;
-const std::chrono::seconds kDevGcTimeout{kDevGcTimeoutSec};
-// Dev GC timeout tolerance. The HAL may not immediately return after the
-// timeout, so include an acceptable tolerance.
-const std::chrono::seconds kDevGcTolerance{3};
-// Time accounted for RPC calls.
-const std::chrono::milliseconds kRpcTime{1000};
-
-template <typename R>
-std::string toString(std::chrono::duration<R, std::milli> time) {
- return std::to_string(time.count()) + "ms";
-}
-
-/** An atomic boolean flag that indicates whether a task has finished. */
-class Flag {
- public:
- void onFinish() {
- std::unique_lock<std::mutex> lock(mMutex);
- onFinishLocked(&lock);
- }
- template <typename R, typename P>
- bool wait(std::chrono::duration<R, P> duration) {
- std::unique_lock<std::mutex> lock(mMutex);
- return waitLocked(&lock, duration);
- }
-
- protected:
- /** Will unlock. */
- void onFinishLocked(std::unique_lock<std::mutex>* lock) {
- mFinished = true;
- lock->unlock();
- mCv.notify_all();
- }
- template <typename R, typename P>
- bool waitLocked(std::unique_lock<std::mutex>* lock, std::chrono::duration<R, P> duration) {
- mCv.wait_for(*lock, duration, [this] { return mFinished; });
- return mFinished;
- }
-
- bool mFinished{false};
- std::mutex mMutex;
- std::condition_variable mCv;
-};
-
class GcCallback : public IGarbageCollectCallback, public Flag {
- public:
+ public:
Return<void> onFinish(Result result) override {
- std::unique_lock<std::mutex> lock(mMutex);
- mResult = result;
- Flag::onFinishLocked(&lock);
+ std::unique_lock<std::mutex> lock(mutex_);
+ result_ = result;
+ Flag::OnFinishLocked(&lock);
return Void();
}
@@ -93,13 +52,13 @@
*/
template <typename R, typename P>
void waitForResult(std::chrono::duration<R, P> timeout, Result expected) {
- std::unique_lock<std::mutex> lock(mMutex);
- ASSERT_TRUE(waitLocked(&lock, timeout)) << "timeout after " << toString(timeout);
- EXPECT_EQ(expected, mResult);
+ std::unique_lock<std::mutex> lock(mutex_);
+ ASSERT_TRUE(WaitLocked(&lock, timeout)) << "timeout after " << to_string(timeout);
+ EXPECT_EQ(expected, result_);
}
- private:
- Result mResult{Result::UNKNOWN_ERROR};
+ private:
+ Result result_{Result::UNKNOWN_ERROR};
};
class HealthStorageHidlTest : public ::testing::TestWithParam<std::string> {
@@ -127,10 +86,10 @@
auto pingFlag = std::make_shared<Flag>();
std::thread([service, pingFlag] {
service->ping();
- pingFlag->onFinish();
+ pingFlag->OnFinish();
})
.detach();
- return pingFlag->wait(timeout);
+ return pingFlag->Wait(timeout);
}
sp<IStorage> fs;
@@ -147,7 +106,7 @@
// Hold test process because HAL can be single-threaded and doing GC.
ASSERT_TRUE(ping(kDevGcTimeout + kDevGcTolerance + kRpcTime))
<< "Service must be available after "
- << toString(kDevGcTimeout + kDevGcTolerance + kRpcTime);
+ << to_string(kDevGcTimeout + kDevGcTolerance + kRpcTime);
}
/**
diff --git a/health/storage/aidl/Android.bp b/health/storage/aidl/Android.bp
new file mode 100644
index 0000000..c39a46d
--- /dev/null
+++ b/health/storage/aidl/Android.bp
@@ -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.
+
+aidl_interface {
+ name: "android.hardware.health.storage",
+ vendor_available: true,
+ srcs: ["android/hardware/health/storage/*.aidl"],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ enabled: false,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl b/health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/IGarbageCollectCallback.aidl
similarity index 87%
copy from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
copy to health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/IGarbageCollectCallback.aidl
index 963e66e..0f382d7 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
+++ b/health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/IGarbageCollectCallback.aidl
@@ -16,8 +16,8 @@
// 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.security.keymint;
+package android.hardware.health.storage;
@VintfStability
-parcelable Timestamp {
- long milliSeconds;
+interface IGarbageCollectCallback {
+ oneway void onFinish(in android.hardware.health.storage.Result result);
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl b/health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/IStorage.aidl
similarity index 84%
copy from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
copy to health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/IStorage.aidl
index 963e66e..61f838a 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
+++ b/health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/IStorage.aidl
@@ -16,8 +16,8 @@
// 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.security.keymint;
+package android.hardware.health.storage;
@VintfStability
-parcelable Timestamp {
- long milliSeconds;
+interface IStorage {
+ oneway void garbageCollect(in long timeoutSeconds, in android.hardware.health.storage.IGarbageCollectCallback callback);
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl b/health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/Result.aidl
similarity index 87%
copy from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
copy to health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/Result.aidl
index 963e66e..a345808 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
+++ b/health/storage/aidl/aidl_api/android.hardware.health.storage/current/android/hardware/health/storage/Result.aidl
@@ -16,8 +16,10 @@
// 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.security.keymint;
-@VintfStability
-parcelable Timestamp {
- long milliSeconds;
+package android.hardware.health.storage;
+@Backing(type="int") @VintfStability
+enum Result {
+ SUCCESS = 0,
+ IO_ERROR = 1,
+ UNKNOWN_ERROR = 2,
}
diff --git a/health/storage/aidl/android/hardware/health/storage/IGarbageCollectCallback.aidl b/health/storage/aidl/android/hardware/health/storage/IGarbageCollectCallback.aidl
new file mode 100644
index 0000000..ccd1b44
--- /dev/null
+++ b/health/storage/aidl/android/hardware/health/storage/IGarbageCollectCallback.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.health.storage;
+
+import android.hardware.health.storage.Result;
+
+/**
+ * Callback interface to IStorage.garbageCollect.
+ */
+@VintfStability
+interface IGarbageCollectCallback {
+ /**
+ * When garbage collection has finished, the implementation must
+ * invoke this function to indicate the result of the garbage collection.
+ *
+ * @param out result Execution result. See documentation for Result for
+ * details.
+ */
+ oneway void onFinish(in Result result);
+}
diff --git a/health/storage/aidl/android/hardware/health/storage/IStorage.aidl b/health/storage/aidl/android/hardware/health/storage/IStorage.aidl
new file mode 100644
index 0000000..78992a2
--- /dev/null
+++ b/health/storage/aidl/android/hardware/health/storage/IStorage.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.health.storage;
+
+import android.hardware.health.storage.IGarbageCollectCallback;
+
+/**
+ * IStorage is an interface that provides operations on underlying storage
+ * devices, including flash memory.
+ */
+@VintfStability
+interface IStorage {
+ /**
+ * Start garbage collection on the driver of storage devices.
+ *
+ * Garbage collection must be started at regular intervals when it is a good
+ * time for a longer-running cleanup tasks, roughly daily.
+ *
+ * When garbage collection finishes or encounters an error before the
+ * specified timeout, the implementation must call IGarbageCollect.finish
+ * immediately with appropriate result.
+ *
+ * If garbage collection does not finish within the specified timeout,
+ * the implementation must stop garbage collection, and must not call
+ * IGarbageCollect.finish.
+ *
+ * @param timeoutSeconds timeout in seconds. The implementation must
+ * return after the timeout is reached.
+ *
+ * @param callback callback interface. Callback must be null if the client
+ * does not need to receive any callbacks.
+ *
+ */
+ oneway void garbageCollect(in long timeoutSeconds, in IGarbageCollectCallback callback);
+}
diff --git a/health/storage/aidl/android/hardware/health/storage/Result.aidl b/health/storage/aidl/android/hardware/health/storage/Result.aidl
new file mode 100644
index 0000000..73bb779
--- /dev/null
+++ b/health/storage/aidl/android/hardware/health/storage/Result.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.health.storage;
+
+/**
+ * Status values for HAL methods.
+ */
+@VintfStability
+@Backing(type="int")
+enum Result {
+ /**
+ * Execution of the method is successful.
+ */
+ SUCCESS = 0,
+ /**
+ * An IO error is encountered when the HAL communicates with the device.
+ */
+ IO_ERROR,
+ /**
+ * An unknown error is encountered.
+ */
+ UNKNOWN_ERROR,
+}
diff --git a/health/storage/aidl/default/Android.bp b/health/storage/aidl/default/Android.bp
new file mode 100644
index 0000000..68a8ee2
--- /dev/null
+++ b/health/storage/aidl/default/Android.bp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+cc_defaults {
+ name: "libhealth_storage_impl_defaults",
+ vendor: true,
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "android.hardware.health.storage-unstable-ndk_platform",
+ ],
+ static_libs: [
+ "libfstab",
+ "libhealth_storage_impl_common",
+ ],
+}
+
+cc_library_static {
+ name: "libhealth_storage_default_impl",
+ defaults: ["libhealth_storage_impl_defaults"],
+ srcs: [
+ "Storage.cpp",
+ ],
+ visibility: [
+ ":__subpackages__",
+ "//hardware/interfaces/tests/extension/health/storage:__subpackages__",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.health.storage-service.default",
+ defaults: ["libhealth_storage_impl_defaults"],
+ relative_install_path: "hw",
+ init_rc: ["health-storage-default.rc"],
+ vintf_fragments: ["health-storage-default.xml"],
+ srcs: ["main.cpp"],
+ static_libs: [
+ "libhealth_storage_default_impl",
+ ],
+}
diff --git a/health/storage/aidl/default/Storage.cpp b/health/storage/aidl/default/Storage.cpp
new file mode 100644
index 0000000..faa4ff6
--- /dev/null
+++ b/health/storage/aidl/default/Storage.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Storage.h"
+
+#include <sstream>
+
+#include <android-base/logging.h>
+#include <health-storage-impl/common.h>
+
+using ::android::hardware::health::storage::DebugDump;
+using ::android::hardware::health::storage::GarbageCollect;
+
+using HResult = android::hardware::health::storage::V1_0::Result;
+using AResult = aidl::android::hardware::health::storage::Result;
+// Ensure static_cast<AResult>(any HResult) works
+static_assert(static_cast<AResult>(HResult::SUCCESS) == AResult::SUCCESS);
+static_assert(static_cast<AResult>(HResult::IO_ERROR) == AResult::IO_ERROR);
+static_assert(static_cast<AResult>(HResult::UNKNOWN_ERROR) == AResult::UNKNOWN_ERROR);
+
+namespace aidl::android::hardware::health::storage {
+
+ndk::ScopedAStatus Storage::garbageCollect(
+ int64_t timeout_seconds, const std::shared_ptr<IGarbageCollectCallback>& callback) {
+ AResult result = static_cast<AResult>(GarbageCollect(static_cast<uint64_t>(timeout_seconds)));
+ if (callback != nullptr) {
+ auto status = callback->onFinish(result);
+ if (!status.isOk()) {
+ LOG(WARNING) << "Cannot return result " << toString(result)
+ << " to callback: " << status.getDescription();
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+binder_status_t Storage::dump(int fd, const char**, uint32_t) {
+ DebugDump(fd);
+ return STATUS_OK;
+}
+
+} // namespace aidl::android::hardware::health::storage
diff --git a/health/storage/aidl/default/Storage.h b/health/storage/aidl/default/Storage.h
new file mode 100644
index 0000000..049991b
--- /dev/null
+++ b/health/storage/aidl/default/Storage.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/health/storage/BnStorage.h>
+
+namespace aidl::android::hardware::health::storage {
+
+class Storage : public BnStorage {
+ ndk::ScopedAStatus garbageCollect(
+ int64_t timeout_seconds,
+ const std::shared_ptr<IGarbageCollectCallback>& callback) override;
+ binder_status_t dump(int fd, const char** args, uint32_t num_args) override;
+};
+
+} // namespace aidl::android::hardware::health::storage
diff --git a/health/storage/aidl/default/health-storage-default.rc b/health/storage/aidl/default/health-storage-default.rc
new file mode 100644
index 0000000..fc1cc8b
--- /dev/null
+++ b/health/storage/aidl/default/health-storage-default.rc
@@ -0,0 +1,7 @@
+service vendor.health-storage-default /vendor/bin/hw/android.hardware.health.storage-service.default
+ interface aidl android.hardware.health.storage.IStorage/default
+ oneshot
+ disabled
+ class hal
+ user system
+ group system
diff --git a/health/storage/aidl/default/health-storage-default.xml b/health/storage/aidl/default/health-storage-default.xml
new file mode 100644
index 0000000..14d4901
--- /dev/null
+++ b/health/storage/aidl/default/health-storage-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.health.storage</name>
+ <version>1</version>
+ <fqname>IStorage/default</fqname>
+ </hal>
+</manifest>
diff --git a/health/storage/aidl/default/main.cpp b/health/storage/aidl/default/main.cpp
new file mode 100644
index 0000000..186b64c
--- /dev/null
+++ b/health/storage/aidl/default/main.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "Storage.h"
+
+using aidl::android::hardware::health::storage::Storage;
+using std::string_literals::operator""s;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ // make a default storage service
+ auto storage = ndk::SharedRefBase::make<Storage>();
+ const std::string name = Storage::descriptor + "/default"s;
+ CHECK_EQ(STATUS_OK,
+ AServiceManager_registerLazyService(storage->asBinder().get(), name.c_str()));
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/health/storage/aidl/vts/functional/Android.bp b/health/storage/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..86b72a7
--- /dev/null
+++ b/health/storage/aidl/vts/functional/Android.bp
@@ -0,0 +1,37 @@
+// 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.
+
+cc_test {
+ name: "VtsHalHealthStorageTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: [
+ "VtsHalHealthStorageTargetTest.cpp",
+ ],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.health.storage-ndk_platform",
+ ],
+ header_libs: [
+ "libhealth_storage_test_common_headers",
+ ],
+ test_suites: [
+ "vts",
+ ],
+ test_config: "VtsHalHealthStorageTargetTest.xml",
+}
diff --git a/health/storage/aidl/vts/functional/VtsHalHealthStorageTargetTest.cpp b/health/storage/aidl/vts/functional/VtsHalHealthStorageTargetTest.cpp
new file mode 100644
index 0000000..3b6b6b4
--- /dev/null
+++ b/health/storage/aidl/vts/functional/VtsHalHealthStorageTargetTest.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+
+#include <chrono>
+#include <set>
+#include <string>
+#include <thread>
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/health/storage/BnGarbageCollectCallback.h>
+#include <aidl/android/hardware/health/storage/IStorage.h>
+#include <android-base/logging.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <health-storage-test/common.h>
+
+namespace aidl::android::hardware::health::storage {
+
+using namespace ::android::hardware::health::storage::test;
+using std::chrono_literals::operator""ms;
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk()) << ret.getDescription()
+#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk()) << ret.getDescription()
+
+class GcCallback : public BnGarbageCollectCallback, public Flag {
+ public:
+ ndk::ScopedAStatus onFinish(Result result) override {
+ std::unique_lock<std::mutex> lock(mutex_);
+ result_ = result;
+ OnFinishLocked(&lock);
+ return ndk::ScopedAStatus::ok();
+ }
+
+ /**
+ * Wait for a specific "timeout". If GC has finished, test that the result
+ * is equal to the "expected" value.
+ */
+ template <typename R, typename P>
+ void WaitForResult(std::chrono::duration<R, P> timeout, Result expected) {
+ std::unique_lock<std::mutex> lock(mutex_);
+ ASSERT_TRUE(WaitLocked(&lock, timeout)) << "timeout after " << to_string(timeout);
+ EXPECT_EQ(expected, result_);
+ }
+
+ private:
+ Result result_{Result::UNKNOWN_ERROR};
+};
+
+class HealthStorageAidl : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ std::string name = GetParam();
+ ASSERT_TRUE(AServiceManager_isDeclared(name.c_str())) << name;
+ ndk::SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
+ ASSERT_NE(binder, nullptr);
+ storage_ = IStorage::fromBinder(binder);
+ ASSERT_NE(storage_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ EXPECT_TRUE(ping(kRpcTime))
+ << "Service is not responsive; expect subsequent tests to fail.";
+ }
+
+ /**
+ * Ping the service and expect it to return after "timeout". Return true
+ * iff the service is responsive within "timeout".
+ */
+ template <typename R, typename P>
+ bool ping(std::chrono::duration<R, P> timeout) {
+ // Ensure the service is responsive after the test.
+ std::shared_ptr<IStorage> service = storage_;
+ auto ping_flag = std::make_shared<Flag>();
+ std::thread([service, ping_flag] {
+ EXPECT_EQ(STATUS_OK, AIBinder_ping(service->asBinder().get()));
+ ping_flag->OnFinish();
+ }).detach();
+ return ping_flag->Wait(timeout);
+ }
+
+ std::shared_ptr<IStorage> storage_;
+};
+
+/**
+ * Ensure garbage collection works on null callback.
+ */
+TEST_P(HealthStorageAidl, GcNullCallback) {
+ ASSERT_OK(storage_->garbageCollect(kDevGcTimeoutSec, nullptr));
+
+ // Hold test process because HAL can be single-threaded and doing GC.
+ ASSERT_TRUE(ping(kDevGcTimeout + kDevGcTolerance + kRpcTime))
+ << "Service must be available after "
+ << to_string(kDevGcTimeout + kDevGcTolerance + kRpcTime);
+}
+
+/**
+ * Ensure garbage collection works on non-null callback.
+ */
+TEST_P(HealthStorageAidl, GcNonNullCallback) {
+ std::shared_ptr<GcCallback> cb = ndk::SharedRefBase::make<GcCallback>();
+ ASSERT_OK(storage_->garbageCollect(kDevGcTimeoutSec, cb));
+ cb->WaitForResult(kDevGcTimeout + kDevGcTolerance + kRpcTime, Result::SUCCESS);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HealthStorageAidl);
+INSTANTIATE_TEST_SUITE_P(
+ HealthStorage, HealthStorageAidl,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IStorage::descriptor)),
+ ::android::PrintInstanceNameToString);
+
+} // namespace aidl::android::hardware::health::storage
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/health/storage/aidl/vts/functional/VtsHalHealthStorageTargetTest.xml b/health/storage/aidl/vts/functional/VtsHalHealthStorageTargetTest.xml
new file mode 100644
index 0000000..f8a1c87
--- /dev/null
+++ b/health/storage/aidl/vts/functional/VtsHalHealthStorageTargetTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalHealthStorageTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalHealthStorageTargetTest->/data/local/tmp/VtsHalHealthStorageTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalHealthStorageTargetTest" />
+ <option name="native-test-timeout" value="3m" />
+ </test>
+</configuration>
diff --git a/health/storage/impl_common/Android.bp b/health/storage/impl_common/Android.bp
new file mode 100644
index 0000000..e1149c0
--- /dev/null
+++ b/health/storage/impl_common/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Common implementation between HIDL and AIDL HAL.
+cc_library_static {
+ name: "libhealth_storage_impl_common",
+ vendor: true,
+ srcs: [
+ "impl_common.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libhidlbase",
+ "liblog",
+ "android.hardware.health.storage@1.0",
+ ],
+
+ static_libs: [
+ "libfstab",
+ ],
+
+ export_shared_lib_headers: [
+ "android.hardware.health.storage@1.0",
+ ],
+}
diff --git a/health/storage/impl_common/impl_common.cpp b/health/storage/impl_common/impl_common.cpp
new file mode 100644
index 0000000..6e753d4
--- /dev/null
+++ b/health/storage/impl_common/impl_common.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <health-storage-impl/common.h>
+
+#include <android-base/chrono_utils.h>
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <fstab/fstab.h>
+
+using ::android::base::ReadFileToString;
+using ::android::base::Timer;
+using ::android::base::Trim;
+using ::android::base::WriteStringToFd;
+using ::android::base::WriteStringToFile;
+using ::android::fs_mgr::Fstab;
+using ::android::fs_mgr::ReadDefaultFstab;
+using ::android::hardware::health::storage::V1_0::Result;
+
+namespace android::hardware::health::storage {
+
+static std::string GetGarbageCollectPath() {
+ Fstab fstab;
+ ReadDefaultFstab(&fstab);
+
+ for (const auto& entry : fstab) {
+ if (!entry.sysfs_path.empty()) {
+ return entry.sysfs_path + "/manual_gc";
+ }
+ }
+
+ return "";
+}
+
+Result GarbageCollect(uint64_t timeout_seconds) {
+ std::string path = GetGarbageCollectPath();
+
+ if (path.empty()) {
+ LOG(WARNING) << "Cannot find Dev GC path";
+ return Result::UNKNOWN_ERROR;
+ }
+
+ Result result = Result::SUCCESS;
+ Timer timer;
+ LOG(INFO) << "Start Dev GC on " << path;
+ while (1) {
+ std::string require;
+ if (!ReadFileToString(path, &require)) {
+ PLOG(WARNING) << "Reading manual_gc failed in " << path;
+ result = Result::IO_ERROR;
+ break;
+ }
+ require = Trim(require);
+ if (require == "" || require == "off" || require == "disabled") {
+ LOG(DEBUG) << "No more to do Dev GC";
+ break;
+ }
+ LOG(DEBUG) << "Trigger Dev GC on " << path;
+ if (!WriteStringToFile("1", path)) {
+ PLOG(WARNING) << "Start Dev GC failed on " << path;
+ result = Result::IO_ERROR;
+ break;
+ }
+ if (timer.duration() >= std::chrono::seconds(timeout_seconds)) {
+ LOG(WARNING) << "Dev GC timeout";
+ // Timeout is not treated as an error. Try next time.
+ break;
+ }
+ sleep(2);
+ }
+ LOG(INFO) << "Stop Dev GC on " << path;
+ if (!WriteStringToFile("0", path)) {
+ PLOG(WARNING) << "Stop Dev GC failed on " << path;
+ result = Result::IO_ERROR;
+ }
+
+ return result;
+}
+
+void DebugDump(int fd) {
+ std::stringstream output;
+
+ std::string path = GetGarbageCollectPath();
+ if (path.empty()) {
+ output << "Cannot find Dev GC path";
+ } else {
+ std::string require;
+
+ if (ReadFileToString(path, &require)) {
+ output << path << ":" << require << std::endl;
+ }
+
+ if (WriteStringToFile("0", path)) {
+ output << "stop success" << std::endl;
+ }
+ }
+
+ if (!WriteStringToFd(output.str(), fd)) {
+ PLOG(WARNING) << "debug: cannot write to fd";
+ }
+
+ fsync(fd);
+}
+
+} // namespace android::hardware::health::storage
diff --git a/health/storage/impl_common/include/health-storage-impl/common.h b/health/storage/impl_common/include/health-storage-impl/common.h
new file mode 100644
index 0000000..c84a6a9
--- /dev/null
+++ b/health/storage/impl_common/include/health-storage-impl/common.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/health/storage/1.0/types.h>
+#include <string>
+
+namespace android::hardware::health::storage {
+
+// Run debug on fd
+void DebugDump(int fd);
+
+// Run garbage collection on GetGarbageCollectPath(). Blocks until garbage
+// collect finishes or |timeout_seconds| has reached.
+V1_0::Result GarbageCollect(uint64_t timeout_seconds);
+
+} // namespace android::hardware::health::storage
diff --git a/health/1.0/default/libhealthd/healthd_board_default.cpp b/health/storage/test_common/Android.bp
similarity index 64%
rename from health/1.0/default/libhealthd/healthd_board_default.cpp
rename to health/storage/test_common/Android.bp
index 127f98e..7c6bef4 100644
--- a/health/1.0/default/libhealthd/healthd_board_default.cpp
+++ b/health/storage/test_common/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 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.
@@ -14,15 +14,7 @@
* limitations under the License.
*/
-#include <healthd/healthd.h>
-
-void healthd_board_init(struct healthd_config*)
-{
- // use defaults
-}
-
-int healthd_board_battery_update(struct android::BatteryProperties*)
-{
- // return 0 to log periodic polled battery status to kernel log
- return 0;
+cc_library_headers {
+ name: "libhealth_storage_test_common_headers",
+ export_include_dirs: ["include"],
}
diff --git a/health/storage/test_common/include/health-storage-test/common.h b/health/storage/test_common/include/health-storage-test/common.h
new file mode 100644
index 0000000..dfda830
--- /dev/null
+++ b/health/storage/test_common/include/health-storage-test/common.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <chrono>
+#include <string>
+
+namespace android::hardware::health::storage::test {
+
+// Dev GC timeout. This is the timeout used by vold.
+const uint64_t kDevGcTimeoutSec = 120;
+const std::chrono::seconds kDevGcTimeout{kDevGcTimeoutSec};
+// Dev GC timeout tolerance. The HAL may not immediately return after the
+// timeout, so include an acceptable tolerance.
+const std::chrono::seconds kDevGcTolerance{3};
+// Time accounted for RPC calls.
+const std::chrono::milliseconds kRpcTime{1000};
+
+template <typename R>
+std::string to_string(std::chrono::duration<R, std::milli> time) {
+ return std::to_string(time.count()) + "ms";
+}
+
+/** An atomic boolean flag that indicates whether a task has finished. */
+class Flag {
+ public:
+ void OnFinish() {
+ std::unique_lock<std::mutex> lock(mutex_);
+ OnFinishLocked(&lock);
+ }
+ template <typename R, typename P>
+ bool Wait(std::chrono::duration<R, P> duration) {
+ std::unique_lock<std::mutex> lock(mutex_);
+ return WaitLocked(&lock, duration);
+ }
+
+ protected:
+ /** Will unlock. */
+ void OnFinishLocked(std::unique_lock<std::mutex>* lock) {
+ finished_ = true;
+ lock->unlock();
+ cv_.notify_all();
+ }
+ template <typename R, typename P>
+ bool WaitLocked(std::unique_lock<std::mutex>* lock, std::chrono::duration<R, P> duration) {
+ cv_.wait_for(*lock, duration, [this] { return finished_; });
+ return finished_;
+ }
+
+ bool finished_{false};
+ std::mutex mutex_;
+ std::condition_variable cv_;
+};
+
+} // namespace android::hardware::health::storage::test
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/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 7166654..0b49b36 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -236,7 +236,12 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRP, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria_1_5()
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
@@ -261,7 +266,12 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRQ, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria_1_5()
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
@@ -307,7 +317,12 @@
ALOGI("setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR, rspInfo.error = %s\n",
toString(radioRsp_v1_5->rspInfo.error).c_str());
- ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error, {RadioError::NONE}));
+
+ // Allow REQUEST_NOT_SUPPORTED because some non-5G device may not support NGRAN for
+ // setSignalStrengthReportingCriteria_1_5()
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
+ {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
}
/*
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index b5adac9..5652827 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -4,6 +4,9 @@
srcs: [
"android/hardware/security/keymint/*.aidl",
],
+ imports: [
+ "android.hardware.security.secureclock",
+ ],
stability: "vintf",
backend: {
java: {
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
index 0d43d8d..ad5bf39 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -23,6 +23,6 @@
long userId;
long authenticatorId;
android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType;
- android.hardware.security.keymint.Timestamp timestamp;
+ android.hardware.security.secureclock.Timestamp timestamp;
byte[] mac;
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
index 07c2844..c95145d 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -20,7 +20,6 @@
@VintfStability
interface IKeyMintDevice {
android.hardware.security.keymint.KeyMintHardwareInfo getHardwareInfo();
- android.hardware.security.keymint.VerificationToken verifyAuthorization(in long challenge, in android.hardware.security.keymint.HardwareAuthToken token);
void addRngEntropy(in byte[] data);
android.hardware.security.keymint.KeyCreationResult generateKey(in android.hardware.security.keymint.KeyParameter[] keyParams);
android.hardware.security.keymint.KeyCreationResult importKey(in android.hardware.security.keymint.KeyParameter[] keyParams, in android.hardware.security.keymint.KeyFormat keyFormat, in byte[] keyData);
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
index 08aa00a..e6ab4c8 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -19,7 +19,7 @@
package android.hardware.security.keymint;
@VintfStability
interface IKeyMintOperation {
- int update(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken inAuthToken, in @nullable android.hardware.security.keymint.VerificationToken inVerificationToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams, out @nullable android.hardware.security.keymint.ByteArray output);
- byte[] finish(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable byte[] inSignature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.keymint.VerificationToken inVerificationToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams);
+ int update(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken inAuthToken, in @nullable android.hardware.security.secureclock.TimeStampToken inTimeStampToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams, out @nullable android.hardware.security.keymint.ByteArray output);
+ byte[] finish(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable byte[] inSignature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken inTimeStampToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams);
void abort();
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/VerificationToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/VerificationToken.aidl
deleted file mode 100644
index 7dc556c..0000000
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/VerificationToken.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// 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.security.keymint;
-@VintfStability
-parcelable VerificationToken {
- long challenge;
- android.hardware.security.keymint.Timestamp timestamp;
- android.hardware.security.keymint.SecurityLevel securityLevel;
- byte[] mac;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
index 12d615f..1067540 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -16,7 +16,7 @@
package android.hardware.security.keymint;
-import android.hardware.security.keymint.Timestamp;
+import android.hardware.security.secureclock.Timestamp;
import android.hardware.security.keymint.HardwareAuthenticatorType;
/**
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 820e135..d5f7a1f 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -26,7 +26,7 @@
import android.hardware.security.keymint.KeyMintHardwareInfo;
import android.hardware.security.keymint.KeyPurpose;
import android.hardware.security.keymint.SecurityLevel;
-import android.hardware.security.keymint.VerificationToken;
+import android.hardware.security.secureclock.TimeStampToken;
/**
* KeyMint device definition.
@@ -223,34 +223,6 @@
KeyMintHardwareInfo getHardwareInfo();
/**
- * Verify authorizations for another IKeyMintDevice instance.
- *
- * On systems with both a StrongBox and a TEE IKeyMintDevice instance it is sometimes useful
- * to ask the TEE KeyMintDevice to verify authorizations for a key hosted in StrongBox.
- *
- * For every StrongBox operation, Keystore is required to call this method on the TEE KeyMint,
- * passing in the StrongBox key's hardwareEnforced authorization list and the challenge
- * returned by StrongBox begin(). Keystore must then pass the VerificationToken to the
- * subsequent invocations of StrongBox update() and finish().
- *
- * StrongBox implementations must return ErrorCode::UNIMPLEMENTED.
- *
- * @param the challenge returned by StrongBox's keyMint's begin().
- *
- * @param authToken A HardwareAuthToken if needed to authorize key usage.
- *
- * @return error ErrorCode::OK on success or ErrorCode::UNIMPLEMENTED if the KeyMintDevice is
- * a StrongBox. If the IKeyMintDevice cannot verify one or more elements of
- * parametersToVerify it must not return an error code, but just omit the unverified
- * parameter from the VerificationToken.
- *
- * @return token the verification token. See VerificationToken in VerificationToken.aidl for
- * details.
- */
- VerificationToken verifyAuthorization(in long challenge,
- in HardwareAuthToken token);
-
- /**
* Adds entropy to the RNG used by KeyMint. Entropy added through this method must not be the
* only source of entropy used, and a secure mixing function must be used to mix the entropy
* provided by this method with internally-generated entropy. The mixing function must be
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index 24960cc..8c49602 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -20,7 +20,7 @@
import android.hardware.security.keymint.HardwareAuthToken;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyParameterArray;
-import android.hardware.security.keymint.VerificationToken;
+import android.hardware.security.secureclock.TimeStampToken;
@VintfStability
interface IKeyMintOperation {
@@ -119,10 +119,9 @@
* @param input Data to be processed. Note that update() may or may not consume all of the data
* provided. See return value.
*
- * @param verificationToken Verification token, used to prove that another IKeymasterDevice HAL
- * has verified some parameters, and to deliver the other HAL's current timestamp, if
- * needed. If not provided, all fields must be initialized to zero and vectors must be
- * empty.
+ * @param inTimeStampToken timestamp token, certifies the freshness of an auth token in case
+ * the security domain of this KeyMint instance has a different clock than the
+ * authenticator issuing the auth token.
*
* @return error Returns ErrorCode encountered in keymint as service specific errors. See the
* ErrorCode enum in ErrorCode.aidl.
@@ -141,7 +140,7 @@
int update(in @nullable KeyParameterArray inParams,
in @nullable byte[] input,
in @nullable HardwareAuthToken inAuthToken,
- in @nullable VerificationToken inVerificationToken,
+ in @nullable TimeStampToken inTimeStampToken,
out @nullable KeyParameterArray outParams,
out @nullable ByteArray output);
@@ -241,9 +240,9 @@
*
* @param authToken Authentication token. Can be nullable if not provided.
*
- * @param verificationToken Verification token, used to prove that another IKeyMintDevice HAL
- * has verified some parameters, and to deliver the other HAL's current timestamp, if
- * needed. Can be nullable if not needed.
+ * @param inTimeStampToken timestamp token, certifies the freshness of an auth token in case
+ * the security domain of this KeyMint instance has a different clock than the
+ * authenticator issuing the auth token.
*
* @return outParams Any output parameters generated by finish().
*
@@ -252,7 +251,7 @@
byte[] finish(in @nullable KeyParameterArray inParams, in @nullable byte[] input,
in @nullable byte[] inSignature,
in @nullable HardwareAuthToken authToken,
- in @nullable VerificationToken inVerificationToken,
+ in @nullable TimeStampToken inTimeStampToken,
out @nullable KeyParameterArray outParams);
/**
diff --git a/security/keymint/aidl/android/hardware/security/keymint/VerificationToken.aidl b/security/keymint/aidl/android/hardware/security/keymint/VerificationToken.aidl
deleted file mode 100644
index f76e6a8..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/VerificationToken.aidl
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.
- */
-
-package android.hardware.security.keymint;
-
-import android.hardware.security.keymint.SecurityLevel;
-import android.hardware.security.keymint.Timestamp;
-
-/**
- * VerificationToken instances are used for secure environments to authenticate one another.
- *
- * This version of the parcelable currently don't use the parametersVerified field since it's not
- * needed for time-based verification. This can be added in a later version, if needed.
- */
-@VintfStability
-parcelable VerificationToken {
- /**
- * The operation handle, used to ensure freshness.
- */
- long challenge;
-
- /**
- * The current time of the secure environment that generates the VerificationToken. This can be
- * checked against auth tokens generated by the same secure environment, which avoids needing to
- * synchronize clocks.
- */
- Timestamp timestamp;
-
- /**
- * SecurityLevel of the secure environment that generated the token.
- */
- SecurityLevel securityLevel;
-
- /**
- * 32-byte HMAC-SHA256 of the above values, computed as:
- *
- * HMAC(H,
- * "Auth Verification" || challenge || timestamp || securityLevel)
- *
- * where:
- *
- * ``HMAC'' is the shared HMAC key (see computeSharedHmac() in IKeyMint).
- *
- * ``||'' represents concatenation
- *
- * The representation of challenge and timestamp is as 64-bit unsigned integers in big-endian
- * order. securityLevel is represented as a 32-bit unsigned integer in big-endian order.
- */
- byte[] mac;
-}
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index c7cc380..17a4613 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -22,7 +22,6 @@
],
srcs: [
"KeyMintTest.cpp",
- "VerificationTokenTest.cpp",
],
shared_libs: [
"libbinder_ndk",
@@ -32,6 +31,7 @@
],
static_libs: [
"android.hardware.security.keymint-unstable-ndk_platform",
+ "android.hardware.security.secureclock-unstable-ndk_platform",
"libcppbor_external",
"libkeymint_vts_test_utils",
],
@@ -61,6 +61,7 @@
],
static_libs: [
"android.hardware.security.keymint-unstable-ndk_platform",
+ "android.hardware.security.secureclock-unstable-ndk_platform",
"libcppbor",
],
}
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/aidl/vts/functional/VerificationTokenTest.cpp b/security/keymint/aidl/vts/functional/VerificationTokenTest.cpp
deleted file mode 100644
index 0b1eccd..0000000
--- a/security/keymint/aidl/vts/functional/VerificationTokenTest.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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 "KeyMintAidlTestBase.h"
-
-namespace aidl::android::hardware::security::keymint::test {
-
-class VerificationTokenTest : public KeyMintAidlTestBase {
- protected:
- struct VerifyAuthorizationResult {
- ErrorCode error;
- VerificationToken token;
- };
-
- VerifyAuthorizationResult verifyAuthorization(uint64_t operationHandle,
- const HardwareAuthToken& authToken) {
- VerifyAuthorizationResult result;
-
- Status err;
- err = keyMint().verifyAuthorization(operationHandle, //
- authToken, //
- &result.token);
-
- result.error = GetReturnErrorCode(err);
- return result;
- }
-
- uint64_t getTime() {
- struct timespec timespec;
- EXPECT_EQ(0, clock_gettime(CLOCK_BOOTTIME, ×pec));
- return timespec.tv_sec * 1000 + timespec.tv_nsec / 1000000;
- }
-
- int sleep_ms(uint32_t milliseconds) {
- struct timespec sleep_time = {static_cast<time_t>(milliseconds / 1000),
- static_cast<long>(milliseconds % 1000) * 1000000};
- while (sleep_time.tv_sec || sleep_time.tv_nsec) {
- if (nanosleep(&sleep_time /* to wait */,
- &sleep_time /* remaining (on interrruption) */) == 0) {
- sleep_time = {};
- } else {
- if (errno != EINTR) return errno;
- }
- }
- return 0;
- }
-};
-
-/*
- * VerificationTokens exist to facilitate cross-KeyMint verification of requirements. As
- * such, the precise capabilities required will vary depending on the specific vendor
- * implementations. Essentially, VerificationTokens are a "hook" to enable vendor
- * implementations to communicate, so the precise usage is defined by those vendors. The only
- * thing we really can test is that tokens can be created by TEE keyMints, and that the
- * timestamps increase as expected.
- */
-TEST_P(VerificationTokenTest, TestCreation) {
- auto result1 = verifyAuthorization(1 /* operation handle */, HardwareAuthToken());
- auto result1_time = getTime();
-
- if (SecLevel() == SecurityLevel::STRONGBOX) {
- // StrongBox should not implement verifyAuthorization.
- EXPECT_EQ(ErrorCode::UNIMPLEMENTED, result1.error);
- return;
- }
-
- ASSERT_EQ(ErrorCode::OK, result1.error);
- EXPECT_EQ(1U, result1.token.challenge);
- EXPECT_EQ(SecLevel(), result1.token.securityLevel);
- EXPECT_GT(result1.token.timestamp.milliSeconds, 0U);
-
- constexpr uint32_t time_to_sleep = 200;
- sleep_ms(time_to_sleep);
-
- auto result2 = verifyAuthorization(2 /* operation handle */, HardwareAuthToken());
-
- auto result2_time = getTime();
- ASSERT_EQ(ErrorCode::OK, result2.error);
- EXPECT_EQ(2U, result2.token.challenge);
- EXPECT_EQ(SecLevel(), result2.token.securityLevel);
-
- auto host_time_delta = result2_time - result1_time;
-
- EXPECT_GE(host_time_delta, time_to_sleep)
- << "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much";
- EXPECT_LE(host_time_delta, time_to_sleep + 20)
- << "The verifyAuthorization call took " << (host_time_delta - time_to_sleep)
- << " ms? That's awful!";
-
- auto km_time_delta =
- result2.token.timestamp.milliSeconds - result1.token.timestamp.milliSeconds;
-
- // If not too much else is going on on the system, the time delta should be quite close. Allow
- // 2 ms of slop just to avoid test flakiness.
- //
- // TODO(swillden): see if we can output values so they can be gathered across many runs and
- // report if times aren't nearly always <1ms apart.
- EXPECT_LE(host_time_delta, km_time_delta + 2);
- EXPECT_LE(km_time_delta, host_time_delta + 2);
- ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size());
- ASSERT_NE(0,
- memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size()));
-}
-
-/*
- * Test that the mac changes when the time stamp changes. This is does not guarantee that the time
- * stamp is included in the mac but on failure we know that it is not. Other than in the test
- * case above we call verifyAuthorization with the exact same set of parameters.
- */
-TEST_P(VerificationTokenTest, MacChangesOnChangingTimestamp) {
- auto result1 = verifyAuthorization(0 /* operation handle */, HardwareAuthToken());
- auto result1_time = getTime();
-
- if (SecLevel() == SecurityLevel::STRONGBOX) {
- // StrongBox should not implement verifyAuthorization.
- EXPECT_EQ(ErrorCode::UNIMPLEMENTED, result1.error);
- return;
- }
-
- EXPECT_EQ(ErrorCode::OK, result1.error);
- EXPECT_EQ(0U, result1.token.challenge);
- EXPECT_EQ(SecLevel(), result1.token.securityLevel);
- EXPECT_GT(result1.token.timestamp.milliSeconds, 0U);
-
- constexpr uint32_t time_to_sleep = 200;
- sleep_ms(time_to_sleep);
-
- auto result2 = verifyAuthorization(0 /* operation handle */, HardwareAuthToken());
- // ASSERT_TRUE(result2.callSuccessful);
- auto result2_time = getTime();
- EXPECT_EQ(ErrorCode::OK, result2.error);
- EXPECT_EQ(0U, result2.token.challenge);
- EXPECT_EQ(SecLevel(), result2.token.securityLevel);
-
- auto host_time_delta = result2_time - result1_time;
-
- EXPECT_GE(host_time_delta, time_to_sleep)
- << "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much";
- EXPECT_LE(host_time_delta, time_to_sleep + 20)
- << "The verifyAuthorization call took " << (host_time_delta - time_to_sleep)
- << " ms? That's awful!";
-
- auto km_time_delta =
- result2.token.timestamp.milliSeconds - result1.token.timestamp.milliSeconds;
-
- EXPECT_LE(host_time_delta, km_time_delta + 2);
- EXPECT_LE(km_time_delta, host_time_delta + 2);
- ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size());
- ASSERT_NE(0,
- memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size()));
-}
-
-INSTANTIATE_KEYMINT_AIDL_TEST(VerificationTokenTest);
-
-} // namespace aidl::android::hardware::security::keymint::test
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/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp
index 7d26a9b..5a6d7ae 100644
--- a/security/secureclock/aidl/Android.bp
+++ b/security/secureclock/aidl/Android.bp
@@ -5,9 +5,6 @@
"android/hardware/security/secureclock/*.aidl",
],
stability: "vintf",
- imports: [
- "android.hardware.security.keymint",
- ],
backend: {
java: {
sdk_version: "module_current",
diff --git a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl
index c23ddca..51b1824 100644
--- a/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl
+++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/TimeStampToken.aidl
@@ -20,7 +20,6 @@
@VintfStability
parcelable TimeStampToken {
long challenge;
- android.hardware.security.keymint.Timestamp timestamp;
- android.hardware.security.keymint.SecurityLevel securityLevel;
+ android.hardware.security.secureclock.Timestamp timestamp;
byte[] mac;
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl
similarity index 95%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
rename to security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl
index 963e66e..50b8b9f 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Timestamp.aidl
+++ b/security/secureclock/aidl/aidl_api/android.hardware.security.secureclock/current/android/hardware/security/secureclock/Timestamp.aidl
@@ -16,7 +16,7 @@
// 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.security.keymint;
+package android.hardware.security.secureclock;
@VintfStability
parcelable Timestamp {
long milliSeconds;
diff --git a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
index 76a2d28..b24d335 100644
--- a/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
+++ b/security/secureclock/aidl/android/hardware/security/secureclock/TimeStampToken.aidl
@@ -16,8 +16,7 @@
package android.hardware.security.secureclock;
-import android.hardware.security.keymint.SecurityLevel;
-import android.hardware.security.keymint.Timestamp;
+import android.hardware.security.secureclock.Timestamp;
/**
* TimeStampToken instances are used for secure environments that requires secure time information.
@@ -36,11 +35,6 @@
Timestamp timestamp;
/**
- * SecurityLevel of the secure environment that generated the token.
- */
- SecurityLevel securityLevel;
-
- /**
* 32-byte HMAC-SHA256 of the above values, computed as:
*
* HMAC(H,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Timestamp.aidl b/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl
similarity index 95%
rename from security/keymint/aidl/android/hardware/security/keymint/Timestamp.aidl
rename to security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl
index ebb3684..7bd1f9e 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Timestamp.aidl
+++ b/security/secureclock/aidl/android/hardware/security/secureclock/Timestamp.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.security.keymint;
+package android.hardware.security.secureclock;
/**
* Time in milliseconds since some arbitrary point in time. Time must be monotonically increasing,
diff --git a/tv/tuner/1.0/vts/functional/DvrTests.cpp b/tv/tuner/1.0/vts/functional/DvrTests.cpp
index 0dfc032..ba21189 100644
--- a/tv/tuner/1.0/vts/functional/DvrTests.cpp
+++ b/tv/tuner/1.0/vts/functional/DvrTests.cpp
@@ -55,6 +55,7 @@
uint8_t* buffer;
ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str());
if (fd < 0) {
+ EXPECT_TRUE(fd >= 0) << "Failed to open: " + mInputDataFile;
mPlaybackThreadRunning = false;
ALOGW("[vts] Error %s", strerror(errno));
}
@@ -178,7 +179,7 @@
// Our current implementation filter the data and write it into the filter FMQ
// immediately after the DATA_READY from the VTS/framework
if (!readRecordFMQ()) {
- ALOGD("[vts] record data failed to be filtered. Ending thread");
+ ALOGW("[vts] record data failed to be filtered. Ending thread");
mRecordThreadRunning = false;
break;
}
diff --git a/tv/tuner/1.0/vts/functional/FilterTests.cpp b/tv/tuner/1.0/vts/functional/FilterTests.cpp
index 5f5d108..240aa9f 100644
--- a/tv/tuner/1.0/vts/functional/FilterTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FilterTests.cpp
@@ -70,6 +70,10 @@
}
bool FilterCallback::readFilterEventData() {
+ if (mFilterMQ == NULL) {
+ ALOGW("[vts] FMQ is not configured and does not need to be tested.");
+ return true;
+ }
bool result = false;
DemuxFilterEvent filterEvent = mFilterEvent;
ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId);
@@ -223,7 +227,11 @@
return AssertionResult(status == Result::SUCCESS);
}
-AssertionResult FilterTests::getFilterMQDescriptor(uint32_t filterId) {
+AssertionResult FilterTests::getFilterMQDescriptor(uint32_t filterId, bool getMqDesc) {
+ if (!getMqDesc) {
+ ALOGE("[vts] Filter does not need FMQ.");
+ return success();
+ }
Result status;
EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
@@ -284,16 +292,14 @@
AssertionResult FilterTests::closeFilter(uint32_t filterId) {
EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
Result status = mFilters[filterId]->close();
- if (status == Result::SUCCESS) {
- for (int i = 0; i < mUsedFilterIds.size(); i++) {
- if (mUsedFilterIds[i] == filterId) {
- mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
- break;
- }
+ for (int i = 0; i < mUsedFilterIds.size(); i++) {
+ if (mUsedFilterIds[i] == filterId) {
+ mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
+ break;
}
- mFilterCallbacks.erase(filterId);
- mFilters.erase(filterId);
}
+ mFilterCallbacks.erase(filterId);
+ mFilters.erase(filterId);
return AssertionResult(status == Result::SUCCESS);
}
diff --git a/tv/tuner/1.0/vts/functional/FilterTests.h b/tv/tuner/1.0/vts/functional/FilterTests.h
index 8ac9c55..c61fa18 100644
--- a/tv/tuner/1.0/vts/functional/FilterTests.h
+++ b/tv/tuner/1.0/vts/functional/FilterTests.h
@@ -159,7 +159,7 @@
AssertionResult getTimeStamp();
AssertionResult getNewlyOpenedFilterId(uint32_t& filterId);
AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId);
- AssertionResult getFilterMQDescriptor(uint32_t filterId);
+ AssertionResult getFilterMQDescriptor(uint32_t filterId, bool getMqDesc);
AssertionResult setFilterDataSource(uint32_t sourceFilterId, uint32_t sinkFilterId);
AssertionResult setFilterDataSourceToDemux(uint32_t filterId);
AssertionResult startFilter(uint32_t filterId);
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 078f5df..891619a 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -48,7 +48,7 @@
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
@@ -75,6 +75,9 @@
void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
FrontendConfig frontendConf) {
+ if (!frontendConf.enable) {
+ return;
+ }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
@@ -99,7 +102,7 @@
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
// tune test
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
@@ -145,7 +148,7 @@
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback());
ASSERT_TRUE(mDvrTests.startDvrPlayback());
ASSERT_TRUE(mFilterTests.startFilter(filterId));
@@ -160,6 +163,9 @@
void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
FrontendConfig frontendConf, DvrConfig dvrConf) {
+ if (!frontendConf.enable) {
+ return;
+ }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
@@ -184,7 +190,7 @@
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
filter = mFilterTests.getFilterById(filterId);
ASSERT_TRUE(filter != nullptr);
mDvrTests.startRecordOutputThread(dvrConf.settings.record());
@@ -247,7 +253,7 @@
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
filter = mFilterTests.getFilterById(filterId);
ASSERT_TRUE(filter != nullptr);
ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
@@ -265,6 +271,9 @@
void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
FrontendConfig frontendConf,
DescramblerConfig descConfig) {
+ if (!frontendConf.enable) {
+ return;
+ }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
@@ -328,17 +337,17 @@
TEST_P(TunerFrontendHidlTest, TuneFrontend) {
description("Tune one Frontend with specific setting and check Lock event");
- mFrontendTests.tuneTest(frontendArray[DVBT]);
+ mFrontendTests.tuneTest(frontendArray[defaultFrontend]);
}
TEST_P(TunerFrontendHidlTest, AutoScanFrontend) {
description("Run an auto frontend scan with specific setting and check lock scanMessage");
- mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_AUTO);
+ mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_AUTO);
}
TEST_P(TunerFrontendHidlTest, BlindScanFrontend) {
description("Run an blind frontend scan with specific setting and check lock scanMessage");
- mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
+ mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND);
}
TEST_P(TunerLnbHidlTest, OpenLnbByName) {
@@ -374,7 +383,7 @@
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
- mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
+ mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -394,7 +403,7 @@
uint32_t avSyncHwId;
sp<IFilter> mediaFilter;
- mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
+ mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -422,7 +431,7 @@
TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
description("Open and start a filter in Demux.");
// TODO use paramterized tests
- configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
+ configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
}
TEST_P(TunerFilterHidlTest, SetFilterLinkage) {
@@ -463,22 +472,22 @@
TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) {
description("Test Video Filter functionality in Broadcast use case.");
- broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[DVBT]);
+ broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[defaultFrontend]);
}
TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) {
description("Test Audio Filter functionality in Broadcast use case.");
- broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[DVBT]);
+ broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[defaultFrontend]);
}
TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) {
description("Test Section Filter functionality in Broadcast use case.");
- broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[DVBT]);
+ broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[defaultFrontend]);
}
TEST_P(TunerBroadcastHidlTest, IonBufferTest) {
description("Test the av filter data bufferring.");
- broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
+ broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
}
TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) {
@@ -493,11 +502,11 @@
sp<IDemux> demux;
uint32_t filterId;
- mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
+ mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
if (feId == INVALID_ID) {
// TODO broadcast test on Cuttlefish needs licensed ts input,
// these tests are runnable on vendor device with real frontend module
- // or with manual ts installing and use DVBT frontend.
+ // or with manual ts installing and use defaultFrontend frontend.
return;
}
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
@@ -510,13 +519,13 @@
filterArray[TS_AUDIO1].bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_AUDIO1].settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_AUDIO1].getMqDesc));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type,
filterArray[TS_VIDEO1].bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_VIDEO1].getMqDesc));
ASSERT_TRUE(mFilterTests.startFilter(filterId));
// tune test
PlaybackSettings playbackSettings{
@@ -533,7 +542,8 @@
};
dvrConfig.settings.playback(playbackSettings);
mFrontendTests.setSoftwareFrontendDvrConfig(dvrConfig);
- ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendArray[DVBT], true /*testWithDemux*/));
+ ASSERT_TRUE(
+ mFrontendTests.tuneFrontend(frontendArray[defaultFrontend], true /*testWithDemux*/));
ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
@@ -550,13 +560,14 @@
TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) {
description("Attach a single filter to the record dvr test.");
// TODO use paramterized tests
- attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[DVBT],
+ attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend],
dvrArray[DVR_RECORD0]);
}
TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) {
description("Feed ts data from frontend to recording and test with ts record filter");
- recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]);
+ recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend],
+ dvrArray[DVR_RECORD0]);
}
TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
@@ -569,7 +580,7 @@
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
- mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
+ mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -586,7 +597,7 @@
set<FilterConfig> filterConfs;
filterConfs.insert(filterArray[TS_AUDIO0]);
filterConfs.insert(filterArray[TS_VIDEO1]);
- scrambledBroadcastTest(filterConfs, frontendArray[DVBT], descramblerArray[DESC_0]);
+ scrambledBroadcastTest(filterConfs, frontendArray[defaultFrontend], descramblerArray[DESC_0]);
}
INSTANTIATE_TEST_SUITE_P(
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
index 27c6593..b0a9c03 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -55,6 +55,7 @@
using namespace std;
+const uint32_t FMQ_SIZE_512K = 0x80000;
const uint32_t FMQ_SIZE_1M = 0x100000;
const uint32_t FMQ_SIZE_4M = 0x400000;
const uint32_t FMQ_SIZE_16M = 0x1000000;
@@ -134,6 +135,7 @@
uint32_t bufferSize;
DemuxFilterType type;
DemuxFilterSettings settings;
+ bool getMqDesc;
bool operator<(const FilterConfig& /*c*/) const { return false; }
};
@@ -144,6 +146,7 @@
};
struct FrontendConfig {
+ bool enable;
bool isSoftwareFe;
FrontendType type;
FrontendSettings settings;
@@ -191,6 +194,8 @@
static DvrConfig dvrArray[DVR_MAX];
static DescramblerConfig descramblerArray[DESC_MAX];
static vector<string> goldenOutputFiles;
+static int defaultFrontend = DVBT;
+static int defaultScanFrontend = SCAN_DVBT;
/** Configuration array for the frontend tune test */
inline void initFrontendConfig() {
@@ -216,7 +221,9 @@
frontendArray[DVBT].tuneStatusTypes = types;
frontendArray[DVBT].expectTuneStatuses = statuses;
frontendArray[DVBT].isSoftwareFe = true;
+ frontendArray[DVBS].enable = true;
frontendArray[DVBS].type = FrontendType::DVBS;
+ frontendArray[DVBS].enable = true;
frontendArray[DVBS].isSoftwareFe = true;
};
@@ -288,6 +295,7 @@
.isRaw = false,
.streamId = 0xbd,
});
+ filterArray[TS_PES0].getMqDesc = true;
// TS PCR filter setting
filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS;
filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR);
@@ -308,6 +316,7 @@
filterArray[TS_SECTION0].settings.ts().filterSettings.section({
.isRaw = false,
});
+ filterArray[TS_SECTION0].getMqDesc = true;
// TS RECORD filter setting
filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS;
filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD);