Merge "Return new authenticatorId when invalidation finishes"
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 94fa92a..0f0cdcf 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -116,75 +116,33 @@
}
#endif // MAJOR_VERSION <= 6
-class SingleOutputConfigTest : public AudioHidlTestWithDeviceConfigParameter {};
-TEST_P(SingleOutputConfigTest, CloseDeviceWithOpenedOutputStreams) {
+class SingleConfigOutputStreamTest : public OutputStreamTest {};
+TEST_P(SingleConfigOutputStreamTest, CloseDeviceWithOpenedOutputStreams) {
doc::test("Verify that a device can't be closed if there are output streams opened");
-#if MAJOR_VERSION <= 6
- DeviceAddress address{.device = AudioDevice::OUT_DEFAULT};
- SourceMetadata initMetadata = {{{AudioUsage::MEDIA, AudioContentType::MUSIC, 1 /* gain */}}};
-#elif MAJOR_VERSION >= 7
- DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT)};
- SourceMetadata initMetadata = {{{toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
- toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
- {} /* tags */,
- toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
- 1 /* gain */}}};
-#endif
- const AudioConfig& config = getConfig();
- auto flags = getOutputFlags();
- sp<IStreamOut> stream;
- StreamHelper<IStreamOut> helper(stream);
- AudioConfig suggestedConfig{};
- ASSERT_NO_FATAL_FAILURE(helper.open(
- [&](AudioIoHandle handle, AudioConfig config, auto cb) {
- return getDevice()->openOutputStream(handle, address, config, flags, initMetadata,
- cb);
- },
- config, &res, &suggestedConfig));
+ // Opening of the stream is done in SetUp.
ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
- ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
+ ASSERT_OK(closeStream(true /*clear*/));
ASSERT_OK(getDevice()->close());
ASSERT_TRUE(resetDevice());
}
-INSTANTIATE_TEST_CASE_P(SingleOutputConfig, SingleOutputConfigTest,
+INSTANTIATE_TEST_CASE_P(SingleConfigOutputStream, SingleConfigOutputStreamTest,
::testing::ValuesIn(getOutputDeviceSingleConfigParameters()),
&DeviceConfigParameterToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleOutputConfig);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigOutputStream);
-class SingleInputConfigTest : public AudioHidlTestWithDeviceConfigParameter {};
-TEST_P(SingleInputConfigTest, CloseDeviceWithOpenedInputStreams) {
+class SingleConfigInputStreamTest : public InputStreamTest {};
+TEST_P(SingleConfigInputStreamTest, CloseDeviceWithOpenedInputStreams) {
doc::test("Verify that a device can't be closed if there are input streams opened");
-#if MAJOR_VERSION <= 6
- DeviceAddress address{.device = AudioDevice::IN_DEFAULT};
- SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
-#elif MAJOR_VERSION >= 7
- DeviceAddress address{.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT)};
- SinkMetadata initMetadata = {
- {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC),
- .gain = 1,
- .tags = {},
- .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
-#endif
- const AudioConfig& config = getConfig();
- auto flags = getInputFlags();
- sp<IStreamIn> stream;
- StreamHelper<IStreamIn> helper(stream);
- AudioConfig suggestedConfig{};
- ASSERT_NO_FATAL_FAILURE(helper.open(
- [&](AudioIoHandle handle, AudioConfig config, auto cb) {
- return getDevice()->openInputStream(handle, address, config, flags, initMetadata,
- cb);
- },
- config, &res, &suggestedConfig));
+ // Opening of the stream is done in SetUp.
ASSERT_RESULT(Result::INVALID_STATE, getDevice()->close());
- ASSERT_NO_FATAL_FAILURE(helper.close(true /*clear*/, &res));
+ ASSERT_OK(closeStream(true /*clear*/));
ASSERT_OK(getDevice()->close());
ASSERT_TRUE(resetDevice());
}
-INSTANTIATE_TEST_CASE_P(SingleInputConfig, SingleInputConfigTest,
+INSTANTIATE_TEST_CASE_P(SingleConfigInputStream, SingleConfigInputStreamTest,
::testing::ValuesIn(getInputDeviceSingleConfigParameters()),
&DeviceConfigParameterToString);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleInputConfig);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleConfigInputStream);
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 3b6d5f2..0f52a90 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -298,6 +298,19 @@
&DeviceConfigParameterToString);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InputBufferSizeInvalidConfig);
+static const DeviceAddress& getInvalidDeviceAddress() {
+ static const DeviceAddress valid = {.deviceType = "random_string"};
+ return valid;
+}
+
+TEST_P(AudioHidlDeviceTest, SetConnectedStateInvalidDeviceAddress) {
+ doc::test("Check that invalid device address is rejected by IDevice::setConnectedState");
+ EXPECT_RESULT(Result::INVALID_ARGUMENTS,
+ getDevice()->setConnectedState(getInvalidDeviceAddress(), true));
+ EXPECT_RESULT(Result::INVALID_ARGUMENTS,
+ getDevice()->setConnectedState(getInvalidDeviceAddress(), false));
+}
+
enum { PARAM_DEVICE_CONFIG, PARAM_ADDRESS, PARAM_METADATA };
enum { INDEX_SINK, INDEX_SOURCE };
using SinkOrSourceMetadata = std::variant<SinkMetadata, SourceMetadata>;
@@ -361,11 +374,6 @@
return valid;
}
-static const DeviceAddress& getInvalidDeviceAddress() {
- static const DeviceAddress valid = {.deviceType = "random_string"};
- return valid;
-}
-
static const RecordTrackMetadata& getValidRecordTrackMetadata() {
static const RecordTrackMetadata valid = {
.source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT), .gain = 1};
@@ -567,7 +575,40 @@
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamInvalidAddress);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(OutputStreamInvalidMetadata);
-TEST_P(OutputStreamTest, UpdateInvalidSourceMetadata) {
+#define TEST_SINGLE_CONFIG_IO_STREAM(test_name, documentation, code) \
+ TEST_P(SingleConfigInputStreamTest, test_name) { \
+ doc::test(documentation); \
+ code; \
+ } \
+ TEST_P(SingleConfigOutputStreamTest, test_name) { \
+ doc::test(documentation); \
+ code; \
+ }
+
+static void testSetDevicesInvalidDeviceAddress(IStream* stream) {
+ ASSERT_RESULT(Result::INVALID_ARGUMENTS, stream->setDevices({getInvalidDeviceAddress()}));
+}
+TEST_SINGLE_CONFIG_IO_STREAM(
+ SetDevicesInvalidDeviceAddress,
+ "Verify that invalid device address is rejected by IStream::setDevices",
+ areAudioPatchesSupported() ? doc::partialTest("Audio patches are supported")
+ : testSetDevicesInvalidDeviceAddress(stream.get()));
+
+static void testSetAudioPropertiesInvalidArguments(IStream* stream, const AudioConfigBase& base) {
+ AudioConfigBase invalidFormat = base;
+ invalidFormat.format = "random_string";
+ ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidFormat));
+
+ AudioConfigBase invalidChannelMask = base;
+ invalidChannelMask.channelMask = "random_string";
+ ASSERT_RESULT(invalidArgsOrNotSupported, stream->setAudioProperties(invalidChannelMask));
+}
+TEST_SINGLE_CONFIG_IO_STREAM(
+ SetAudioPropertiesInvalidArguments,
+ "Verify that invalid arguments are rejected by IStream::setAudioProperties",
+ testSetAudioPropertiesInvalidArguments(stream.get(), audioConfig.base));
+
+TEST_P(SingleConfigOutputStreamTest, UpdateInvalidSourceMetadata) {
doc::test("Verify that invalid metadata is rejected by IStreamOut::updateSourceMetadata");
for (const auto& metadata : getInvalidSourceMetadatas()) {
ASSERT_RESULT(invalidArgsOrNotSupported, stream->updateSourceMetadata(metadata))
@@ -575,7 +616,7 @@
}
}
-TEST_P(InputStreamTest, UpdateInvalidSinkMetadata) {
+TEST_P(SingleConfigInputStreamTest, UpdateInvalidSinkMetadata) {
doc::test("Verify that invalid metadata is rejected by IStreamIn::updateSinkMetadata");
for (const auto& metadata : getInvalidSinkMetadatas()) {
ASSERT_RESULT(invalidArgsOrNotSupported, stream->updateSinkMetadata(metadata))
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index d39fbcd..35ff869 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <vector>
+
#define LOG_TAG "AudioEffectHidlHalTest"
#include <android-base/logging.h>
#if MAJOR_VERSION <= 6
@@ -309,6 +311,47 @@
EXPECT_EQ(Result::OK, ret2);
}
+#if MAJOR_VERSION >= 7
+std::vector<EffectBufferConfig> generateInvalidConfigs(const EffectBufferConfig& src) {
+ std::vector<EffectBufferConfig> result;
+ EffectBufferConfig invalidFormat = src;
+ invalidFormat.base.format = "random_string";
+ result.push_back(std::move(invalidFormat));
+ EffectBufferConfig invalidChannelMask = src;
+ invalidChannelMask.base.channelMask = "random_string";
+ result.push_back(std::move(invalidChannelMask));
+ return result;
+}
+
+TEST_P(AudioEffectHidlTest, SetConfigInvalidArguments) {
+ description("Verify that invalid arguments are rejected by SetConfig");
+ Result retval = Result::NOT_INITIALIZED;
+ EffectConfig currentConfig;
+ Return<void> ret = effect->getConfig([&](Result r, const EffectConfig& conf) {
+ retval = r;
+ if (r == Result::OK) {
+ currentConfig = conf;
+ }
+ });
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::OK, retval);
+ for (const auto& invalidInputCfg : generateInvalidConfigs(currentConfig.inputCfg)) {
+ EffectConfig invalidConfig = currentConfig;
+ invalidConfig.inputCfg = invalidInputCfg;
+ Return<Result> ret = effect->setConfig(invalidConfig, nullptr, nullptr);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, ret);
+ }
+ for (const auto& invalidOutputCfg : generateInvalidConfigs(currentConfig.outputCfg)) {
+ EffectConfig invalidConfig = currentConfig;
+ invalidConfig.outputCfg = invalidOutputCfg;
+ Return<Result> ret = effect->setConfig(invalidConfig, nullptr, nullptr);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, ret);
+ }
+}
+#endif
+
TEST_P(AudioEffectHidlTest, GetConfigReverse) {
description("Verify that GetConfigReverse does not crash");
Return<void> ret = effect->getConfigReverse([&](Result, const EffectConfig&) {});
@@ -413,6 +456,16 @@
EXPECT_EQ(Result::OK, ret);
}
+#if MAJOR_VERSION >= 7
+TEST_P(AudioEffectHidlTest, SetDeviceInvalidDeviceAddress) {
+ description("Verify that invalid device address is rejected by SetDevice");
+ DeviceAddress device{.deviceType = "random_string"};
+ Return<Result> ret = effect->setDevice(device);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_EQ(Result::INVALID_ARGUMENTS, ret);
+}
+#endif
+
TEST_P(AudioEffectHidlTest, SetDevice) {
description("Verify that SetDevice works for an output chain effect");
#if MAJOR_VERSION <= 6
@@ -468,6 +521,17 @@
EXPECT_TRUE(ret.isOk());
}
+#if MAJOR_VERSION >= 7
+TEST_P(AudioEffectHidlTest, SetInputDeviceInvalidDeviceAddress) {
+ description("Verify that invalid device address is rejected by SetInputDevice");
+ DeviceAddress device{.deviceType = "random_string"};
+ Return<Result> ret = effect->setInputDevice(device);
+ EXPECT_TRUE(ret.isOk());
+ EXPECT_TRUE(ret == Result::INVALID_ARGUMENTS || ret == Result::NOT_SUPPORTED)
+ << ::testing::PrintToString(ret);
+}
+#endif
+
TEST_P(AudioEffectHidlTest, SetInputDevice) {
description("Verify that SetInputDevice does not crash");
#if MAJOR_VERSION <= 6
@@ -479,6 +543,16 @@
EXPECT_TRUE(ret.isOk());
}
+#if MAJOR_VERSION >= 7
+TEST_P(AudioEffectHidlTest, SetInvalidAudioSource) {
+ description("Verify that an invalid audio source is rejected by SetAudioSource");
+ Return<Result> ret = effect->setAudioSource("random_string");
+ ASSERT_TRUE(ret.isOk());
+ EXPECT_TRUE(ret == Result::INVALID_ARGUMENTS || ret == Result::NOT_SUPPORTED)
+ << ::testing::PrintToString(ret);
+}
+#endif
+
TEST_P(AudioEffectHidlTest, SetAudioSource) {
description("Verify that SetAudioSource does not crash");
#if MAJOR_VERSION <= 6
diff --git a/authsecret/aidl/Android.bp b/authsecret/aidl/Android.bp
new file mode 100644
index 0000000..0a05034
--- /dev/null
+++ b/authsecret/aidl/Android.bp
@@ -0,0 +1,16 @@
+aidl_interface {
+ name: "android.hardware.authsecret",
+ vendor_available: true,
+ srcs: ["android/hardware/authsecret/*.aidl"],
+ stability: "vintf",
+ backend: {
+ java: {
+ platform_apis: true,
+ },
+ ndk: {
+ vndk: {
+ enabled: true,
+ },
+ },
+ },
+}
diff --git a/authsecret/aidl/aidl_api/android.hardware.authsecret/current/android/hardware/authsecret/IAuthSecret.aidl b/authsecret/aidl/aidl_api/android.hardware.authsecret/current/android/hardware/authsecret/IAuthSecret.aidl
new file mode 100644
index 0000000..14e8325
--- /dev/null
+++ b/authsecret/aidl/aidl_api/android.hardware.authsecret/current/android/hardware/authsecret/IAuthSecret.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.authsecret;
+@VintfStability
+interface IAuthSecret {
+ oneway void setPrimaryUserCredential(in byte[] secret);
+}
diff --git a/authsecret/aidl/android/hardware/authsecret/IAuthSecret.aidl b/authsecret/aidl/android/hardware/authsecret/IAuthSecret.aidl
new file mode 100644
index 0000000..3849ec0
--- /dev/null
+++ b/authsecret/aidl/android/hardware/authsecret/IAuthSecret.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.authsecret;
+
+/**
+ * This security HAL allows vendor components to be cryptographically tied to
+ * the primary user's credential. For example, security hardware can require
+ * proof that the credential is known before applying updates.
+ *
+ */
+@VintfStability
+interface IAuthSecret {
+ /**
+ * When the primary user is unlocked, this method is passed a secret to
+ * prove that is has been successfully unlocked. The primary user can either
+ * be unlocked by a person entering their credential or by another party
+ * using an escrow token e.g. a device administrator.
+ *
+ * The first time this is called, the secret must be used to provision state
+ * that depends on the primary user's secret. The same secret must be passed
+ * on each call until the next factory reset.
+ *
+ * Upon factory reset, any dependence on the secret must be removed as that
+ * secret is now lost and must never be derived again. A new secret must be
+ * created for the new primary user which must be used to newly provision
+ * state the first time this method is called after factory reset.
+ *
+ * The secret must be at least 16 bytes, or the secret must be dropped.
+ *
+ * @param secret blob derived from the primary user's credential.
+ */
+ oneway void setPrimaryUserCredential(in byte[] secret);
+}
diff --git a/authsecret/aidl/default/Android.bp b/authsecret/aidl/default/Android.bp
new file mode 100644
index 0000000..d598344
--- /dev/null
+++ b/authsecret/aidl/default/Android.bp
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_binary {
+ name: "android.hardware.authsecret-service.example",
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.authsecret-service.example.rc"],
+ vintf_fragments: ["android.hardware.authsecret-service.example.xml"],
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "AuthSecret.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.authsecret-ndk_platform",
+ "libbase",
+ "libbinder_ndk",
+ ],
+}
diff --git a/authsecret/aidl/default/AuthSecret.cpp b/authsecret/aidl/default/AuthSecret.cpp
new file mode 100644
index 0000000..9645e4d
--- /dev/null
+++ b/authsecret/aidl/default/AuthSecret.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 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 "AuthSecret.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace authsecret {
+
+// Methods from ::android::hardware::authsecret::IAuthSecret follow.
+::ndk::ScopedAStatus AuthSecret::setPrimaryUserCredential(const std::vector<uint8_t>& in_secret) {
+ (void)in_secret;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace authsecret
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/authsecret/aidl/default/AuthSecret.h b/authsecret/aidl/default/AuthSecret.h
new file mode 100644
index 0000000..b40fc48
--- /dev/null
+++ b/authsecret/aidl/default/AuthSecret.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/authsecret/BnAuthSecret.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace authsecret {
+
+struct AuthSecret : public BnAuthSecret {
+ AuthSecret() = default;
+
+ // Methods from ::android::hardware::authsecret::IAuthSecret follow.
+ ::ndk::ScopedAStatus setPrimaryUserCredential(const std::vector<uint8_t>& in_secret) override;
+
+};
+
+} // namespace authsecret
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/authsecret/aidl/default/android.hardware.authsecret-service.example.rc b/authsecret/aidl/default/android.hardware.authsecret-service.example.rc
new file mode 100644
index 0000000..fef6e24
--- /dev/null
+++ b/authsecret/aidl/default/android.hardware.authsecret-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.authsecret_default /vendor/bin/hw/android.hardware.authsecret-service.example
+ class hal
+ user hsm
+ group hsm
diff --git a/authsecret/aidl/default/android.hardware.authsecret-service.example.xml b/authsecret/aidl/default/android.hardware.authsecret-service.example.xml
new file mode 100644
index 0000000..9d4e162
--- /dev/null
+++ b/authsecret/aidl/default/android.hardware.authsecret-service.example.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.authsecret</name>
+ <version>1</version>
+ <interface>
+ <name>IAuthSecret</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/authsecret/aidl/default/service.cpp b/authsecret/aidl/default/service.cpp
new file mode 100644
index 0000000..efecf10
--- /dev/null
+++ b/authsecret/aidl/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "AuthSecret.h"
+
+using ::aidl::android::hardware::authsecret::AuthSecret;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ std::shared_ptr<AuthSecret> authsecret = ndk::SharedRefBase::make<AuthSecret>();
+
+ const std::string instance = std::string() + AuthSecret::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(authsecret->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return -1; // Should never be reached
+}
diff --git a/authsecret/aidl/vts/Android.bp b/authsecret/aidl/vts/Android.bp
new file mode 100644
index 0000000..83a85b2
--- /dev/null
+++ b/authsecret/aidl/vts/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2018 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: "VtsHalAuthSecretTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalAuthSecretTargetTest.cpp"],
+ static_libs: ["android.hardware.authsecret-ndk_platform"],
+ shared_libs: ["libbinder_ndk"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ require_root: true,
+}
diff --git a/authsecret/aidl/vts/VtsHalAuthSecretTargetTest.cpp b/authsecret/aidl/vts/VtsHalAuthSecretTargetTest.cpp
new file mode 100644
index 0000000..31c2834
--- /dev/null
+++ b/authsecret/aidl/vts/VtsHalAuthSecretTargetTest.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/authsecret/IAuthSecret.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::aidl::android::hardware::authsecret::IAuthSecret;
+
+using ::ndk::SpAIBinder;
+
+/**
+ * There is no expected behaviour that can be tested so these tests check the
+ * HAL doesn't crash with different execution orders.
+ */
+class AuthSecretAidlTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ authsecret = IAuthSecret::fromBinder(
+ SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(authsecret, nullptr);
+
+ // Notify LSS to generate PIN code '1234' and corresponding secret.
+ (void)system("cmd lock_settings set-pin 1234");
+
+ // All tests must enroll the correct secret first as this cannot be changed
+ // without a factory reset and the order of tests could change.
+ authsecret->setPrimaryUserCredential(CORRECT_SECRET);
+ }
+
+ static void TearDownTestSuite() {
+ // clean up PIN code after testing
+ (void)system("cmd lock_settings clear --old 1234");
+ }
+
+ std::shared_ptr<IAuthSecret> authsecret;
+ std::vector<uint8_t> CORRECT_SECRET{61, 93, 124, 240, 5, 0, 7, 201, 9, 129, 11, 12, 0, 14, 0, 16};
+ std::vector<uint8_t> WRONG_SECRET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+};
+
+/* Provision the primary user with a secret. */
+TEST_P(AuthSecretAidlTest, provisionPrimaryUserCredential) {
+ // Secret provisioned by SetUp()
+}
+
+/* Provision the primary user with a secret and pass the secret again. */
+TEST_P(AuthSecretAidlTest, provisionPrimaryUserCredentialAndPassAgain) {
+ // Secret provisioned by SetUp()
+ authsecret->setPrimaryUserCredential(CORRECT_SECRET);
+}
+
+/* Provision the primary user with a secret and pass the secret again repeatedly. */
+TEST_P(AuthSecretAidlTest, provisionPrimaryUserCredentialAndPassAgainMultipleTimes) {
+ // Secret provisioned by SetUp()
+ constexpr int N = 5;
+ for (int i = 0; i < N; ++i) {
+ authsecret->setPrimaryUserCredential(CORRECT_SECRET);
+ }
+}
+
+/* Provision the primary user with a secret and then pass the wrong secret. This
+ * should never happen and is an framework bug if it does. As the secret is
+ * wrong, the HAL implementation may not be able to function correctly but it
+ * should fail gracefully. */
+TEST_P(AuthSecretAidlTest, provisionPrimaryUserCredentialAndWrongSecret) {
+ // Secret provisioned by SetUp()
+ authsecret->setPrimaryUserCredential(WRONG_SECRET);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AuthSecretAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, AuthSecretAidlTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IAuthSecret::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index faf7ad2..427709a 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -22,15 +22,18 @@
generated_sources: ["audio_policy_configuration_V7_0"],
header_libs: ["libxsdc-utils"],
shared_libs: [
+ "android.frameworks.automotive.powerpolicy-ndk_platform",
"android.hardware.automotive.audiocontrol-ndk_platform",
"libbase",
"libbinder_ndk",
- "liblog",
"libcutils",
+ "liblog",
+ "libpowerpolicyclient",
"libxml2",
],
srcs: [
"AudioControl.cpp",
"main.cpp",
+ "PowerPolicyClient.cpp",
],
}
diff --git a/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp b/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp
new file mode 100644
index 0000000..7657337
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 "PowerPolicyClient.h"
+#include "AudioControl.h"
+
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+
+namespace aafap = aidl::android::frameworks::automotive::powerpolicy;
+
+using aafap::CarPowerPolicy;
+using aafap::CarPowerPolicyFilter;
+using aafap::PowerComponent;
+using ::android::frameworks::automotive::powerpolicy::hasComponent;
+using ::ndk::ScopedAStatus;
+
+namespace {
+
+constexpr PowerComponent kAudioComponent = PowerComponent::AUDIO;
+
+} // namespace
+
+PowerPolicyClient::PowerPolicyClient(std::shared_ptr<AudioControl> audioControl)
+ : mAudioControl(audioControl) {}
+
+void PowerPolicyClient::onInitFailed() {
+ LOG(ERROR) << "Initializing power policy client failed";
+}
+
+std::vector<PowerComponent> PowerPolicyClient::getComponentsOfInterest() {
+ std::vector<PowerComponent> components{kAudioComponent};
+ return components;
+}
+
+ScopedAStatus PowerPolicyClient::onPolicyChanged(const CarPowerPolicy& powerPolicy) {
+ if (hasComponent(powerPolicy.enabledComponents, kAudioComponent)) {
+ LOG(DEBUG) << "Power policy: Audio component is enabled";
+ // TODO(b/173719953): Do something when AUDIO is enabled.
+ } else if (hasComponent(powerPolicy.disabledComponents, kAudioComponent)) {
+ LOG(DEBUG) << "Power policy: Audio component is disabled";
+ // TODO(b/173719953): Do something when AUDIO is disabled.
+ }
+ return ScopedAStatus::ok();
+}
+
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/automotive/audiocontrol/aidl/default/PowerPolicyClient.h b/automotive/audiocontrol/aidl/default/PowerPolicyClient.h
new file mode 100644
index 0000000..0b4d5b6
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/PowerPolicyClient.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
+#define AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
+
+#include "PowerPolicyClientBase.h"
+
+#include <memory>
+
+namespace aidl::android::hardware::automotive::audiocontrol {
+
+class AudioControl;
+
+class PowerPolicyClient
+ : public ::android::frameworks::automotive::powerpolicy::PowerPolicyClientBase {
+ public:
+ explicit PowerPolicyClient(std::shared_ptr<AudioControl> audioControl);
+
+ void onInitFailed();
+ std::vector<::aidl::android::frameworks::automotive::powerpolicy::PowerComponent>
+ getComponentsOfInterest() override;
+ ::ndk::ScopedAStatus onPolicyChanged(
+ const ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy&) override;
+
+ private:
+ std::shared_ptr<AudioControl> mAudioControl;
+};
+
+} // namespace aidl::android::hardware::automotive::audiocontrol
+
+#endif // AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
diff --git a/automotive/audiocontrol/aidl/default/main.cpp b/automotive/audiocontrol/aidl/default/main.cpp
index 996665f..9b259fc 100644
--- a/automotive/audiocontrol/aidl/default/main.cpp
+++ b/automotive/audiocontrol/aidl/default/main.cpp
@@ -15,22 +15,28 @@
*/
#include "AudioControl.h"
+#include "PowerPolicyClient.h"
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
using aidl::android::hardware::automotive::audiocontrol::AudioControl;
+using aidl::android::hardware::automotive::audiocontrol::PowerPolicyClient;
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
- std::shared_ptr<AudioControl> audioControl = ndk::SharedRefBase::make<AudioControl>();
+ std::shared_ptr<AudioControl> audioControl = ::ndk::SharedRefBase::make<AudioControl>();
const std::string instance = std::string() + AudioControl::descriptor + "/default";
binder_status_t status =
AServiceManager_addService(audioControl->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
+ std::shared_ptr<PowerPolicyClient> powerPolicyClient =
+ ::ndk::SharedRefBase::make<PowerPolicyClient>(audioControl);
+ powerPolicyClient->init();
+
ABinderProcess_joinThreadPool();
return EXIT_FAILURE; // should not reach
}
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 0488b57..f7e885d 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -3691,7 +3691,10 @@
* events.
*/
struct VehiclePropValue {
- /** Time is elapsed nanoseconds since boot */
+ /**
+ * Time is elapsed nanoseconds since boot. It's equivalent to
+ * {@code SystemClock.elapsedRealtimeNano()}.
+ */
int64_t timestamp;
/**
diff --git a/cas/1.0/vts/functional/Android.bp b/cas/1.0/vts/functional/Android.bp
index 82dc568..a065b85 100644
--- a/cas/1.0/vts/functional/Android.bp
+++ b/cas/1.0/vts/functional/Android.bp
@@ -20,6 +20,8 @@
srcs: ["VtsHalCasV1_0TargetTest.cpp"],
static_libs: [
"android.hardware.cas@1.0",
+ "android.hardware.cas@1.1",
+ "android.hardware.cas@1.2",
"android.hardware.cas.native@1.0",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
diff --git a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
index 7f5d988..df0c859 100644
--- a/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
+++ b/cas/1.0/vts/functional/VtsHalCasV1_0TargetTest.cpp
@@ -22,6 +22,7 @@
#include <android/hardware/cas/1.0/IDescramblerBase.h>
#include <android/hardware/cas/1.0/IMediaCasService.h>
#include <android/hardware/cas/1.0/types.h>
+#include <android/hardware/cas/1.2/IMediaCasService.h>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/cas/native/1.0/types.h>
#include <binder/MemoryDealer.h>
@@ -212,6 +213,10 @@
class MediaCasHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
+ if (android::hardware::cas::V1_2::IMediaCasService::getService(GetParam()) == nullptr) {
+ ALOGI("Descrambler is need to be tested before cas@1.2.");
+ mIsTestDescrambler = true;
+ }
mService = IMediaCasService::getService(GetParam());
ASSERT_NE(mService, nullptr);
}
@@ -226,6 +231,7 @@
sp<ICas> mMediaCas;
sp<IDescramblerBase> mDescramblerBase;
sp<MediaCasListener> mCasListener;
+ bool mIsTestDescrambler = false;
typedef struct _OobInputTestParams {
const SubSample* subSamples;
uint32_t numSubSamples;
@@ -270,8 +276,14 @@
auto descramblerStatus = mService->createDescrambler(caSystemId);
if (!descramblerStatus.isOk()) {
- return ::testing::AssertionFailure();
+ if (mIsTestDescrambler) {
+ return ::testing::AssertionFailure();
+ } else {
+ ALOGI("Skip Descrambler test since it's not required in cas@1.2.");
+ return ::testing::AssertionSuccess();
+ }
}
+ mIsTestDescrambler = true;
mDescramblerBase = descramblerStatus;
return ::testing::AssertionResult(mDescramblerBase != nullptr);
}
@@ -494,14 +506,15 @@
returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
+ if (mIsTestDescrambler) {
+ returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
- returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
-
- returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
hidl_vec<uint8_t> hidlNullPtr;
hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
@@ -543,29 +556,32 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
- EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
+ if (mIsTestDescrambler) {
+ EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
- sp<IDescrambler> descrambler;
- descrambler = IDescrambler::castFrom(mDescramblerBase);
- ASSERT_NE(descrambler, nullptr);
+ sp<IDescrambler> descrambler;
+ descrambler = IDescrambler::castFrom(mDescramblerBase);
+ ASSERT_NE(descrambler, nullptr);
- Status descrambleStatus = Status::OK;
- sp<IMemory> dataMemory;
+ Status descrambleStatus = Status::OK;
+ sp<IMemory> dataMemory;
- ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
- EXPECT_EQ(Status::OK, descrambleStatus);
+ ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
+ EXPECT_EQ(Status::OK, descrambleStatus);
- ASSERT_NE(nullptr, dataMemory.get());
- uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
+ ASSERT_NE(nullptr, dataMemory.get());
+ uint8_t* opBuffer =
+ static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
- int compareResult =
- memcmp(static_cast<const void*>(opBuffer), static_cast<const void*>(kOutRefBinaryBuffer),
- sizeof(kOutRefBinaryBuffer));
- EXPECT_EQ(0, compareResult);
+ int compareResult =
+ memcmp(static_cast<const void*>(opBuffer),
+ static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
+ EXPECT_EQ(0, compareResult);
- returnStatus = mDescramblerBase->release();
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ returnStatus = mDescramblerBase->release();
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
returnStatus = mMediaCas->release();
EXPECT_TRUE(returnStatus.isOk());
@@ -590,13 +606,15 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
- returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
+ if (mIsTestDescrambler) {
+ returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
- returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
+ returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
+ }
}
TEST_P(MediaCasHidlTest, TestClearKeyErrors) {
@@ -654,38 +672,40 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus);
- /*
- * Test MediaDescrambler error codes
- */
- // setMediaCasSession should fail with an invalid session id
- returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
+ if (mIsTestDescrambler) {
+ /*
+ * Test MediaDescrambler error codes
+ */
+ // setMediaCasSession should fail with an invalid session id
+ returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
- // descramble should fail without a valid session
- sp<IDescrambler> descrambler;
- descrambler = IDescrambler::castFrom(mDescramblerBase);
- ASSERT_NE(descrambler, nullptr);
+ // descramble should fail without a valid session
+ sp<IDescrambler> descrambler;
+ descrambler = IDescrambler::castFrom(mDescramblerBase);
+ ASSERT_NE(descrambler, nullptr);
- Status descrambleStatus = Status::OK;
- sp<IMemory> dataMemory;
+ Status descrambleStatus = Status::OK;
+ sp<IMemory> dataMemory;
- ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
- EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus);
+ ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
+ EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus);
- // Now set a valid session, should still fail because no valid ecm is processed
- returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ // Now set a valid session, should still fail because no valid ecm is processed
+ returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
- ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
- EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus);
+ ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
+ EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus);
- // Verify that requiresSecureDecoderComponent handles empty mime
- EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent(""));
+ // Verify that requiresSecureDecoderComponent handles empty mime
+ EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent(""));
- // Verify that requiresSecureDecoderComponent handles invalid mime
- EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("bad"));
+ // Verify that requiresSecureDecoderComponent handles invalid mime
+ EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("bad"));
+ }
}
TEST_P(MediaCasHidlTest, TestClearKeyOobFails) {
@@ -700,9 +720,11 @@
std::vector<uint8_t> sessionId;
ASSERT_TRUE(openCasSession(&sessionId));
- returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ if (mIsTestDescrambler) {
+ returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
hidl_vec<uint8_t> hidlEcm;
hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
@@ -710,126 +732,104 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
- sp<IDescrambler> descrambler = IDescrambler::castFrom(mDescramblerBase);
- ASSERT_NE(nullptr, descrambler.get());
+ if (mIsTestDescrambler) {
+ sp<IDescrambler> descrambler = IDescrambler::castFrom(mDescramblerBase);
+ ASSERT_NE(nullptr, descrambler.get());
- Status descrambleStatus = Status::OK;
+ Status descrambleStatus = Status::OK;
- // test invalid src buffer offset
- ASSERT_TRUE(descrambleTestOobInput(
- descrambler,
- &descrambleStatus,
- {
- .subSamples = kSubSamples,
- .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample),
- .imemSizeActual = sizeof(kInBinaryBuffer),
- .imemOffset = 0xcccccc,
- .imemSize = sizeof(kInBinaryBuffer),
- .srcOffset = 0,
- .dstOffset = 0
- }));
- EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
+ // test invalid src buffer offset
+ ASSERT_TRUE(
+ descrambleTestOobInput(descrambler, &descrambleStatus,
+ {.subSamples = kSubSamples,
+ .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+ .imemSizeActual = sizeof(kInBinaryBuffer),
+ .imemOffset = 0xcccccc,
+ .imemSize = sizeof(kInBinaryBuffer),
+ .srcOffset = 0,
+ .dstOffset = 0}));
+ EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
- // test invalid src buffer size
- ASSERT_TRUE(descrambleTestOobInput(
- descrambler,
- &descrambleStatus,
- {
- .subSamples = kSubSamples,
- .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample),
- .imemSizeActual = sizeof(kInBinaryBuffer),
- .imemOffset = 0,
- .imemSize = 0xcccccc,
- .srcOffset = 0,
- .dstOffset = 0
- }));
- EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
+ // test invalid src buffer size
+ ASSERT_TRUE(
+ descrambleTestOobInput(descrambler, &descrambleStatus,
+ {.subSamples = kSubSamples,
+ .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+ .imemSizeActual = sizeof(kInBinaryBuffer),
+ .imemOffset = 0,
+ .imemSize = 0xcccccc,
+ .srcOffset = 0,
+ .dstOffset = 0}));
+ EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
- // test invalid src buffer size
- ASSERT_TRUE(descrambleTestOobInput(
- descrambler,
- &descrambleStatus,
- {
- .subSamples = kSubSamples,
- .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample),
- .imemSizeActual = sizeof(kInBinaryBuffer),
- .imemOffset = 1,
- .imemSize = (uint64_t)-1,
- .srcOffset = 0,
- .dstOffset = 0
- }));
- EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
+ // test invalid src buffer size
+ ASSERT_TRUE(
+ descrambleTestOobInput(descrambler, &descrambleStatus,
+ {.subSamples = kSubSamples,
+ .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+ .imemSizeActual = sizeof(kInBinaryBuffer),
+ .imemOffset = 1,
+ .imemSize = (uint64_t)-1,
+ .srcOffset = 0,
+ .dstOffset = 0}));
+ EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
- // test invalid srcOffset
- ASSERT_TRUE(descrambleTestOobInput(
- descrambler,
- &descrambleStatus,
- {
- .subSamples = kSubSamples,
- .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample),
- .imemSizeActual = sizeof(kInBinaryBuffer),
- .imemOffset = 0,
- .imemSize = sizeof(kInBinaryBuffer),
- .srcOffset = 0xcccccc,
- .dstOffset = 0
- }));
- EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
+ // test invalid srcOffset
+ ASSERT_TRUE(
+ descrambleTestOobInput(descrambler, &descrambleStatus,
+ {.subSamples = kSubSamples,
+ .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+ .imemSizeActual = sizeof(kInBinaryBuffer),
+ .imemOffset = 0,
+ .imemSize = sizeof(kInBinaryBuffer),
+ .srcOffset = 0xcccccc,
+ .dstOffset = 0}));
+ EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
- // test invalid dstOffset
- ASSERT_TRUE(descrambleTestOobInput(
- descrambler,
- &descrambleStatus,
- {
- .subSamples = kSubSamples,
- .numSubSamples = sizeof(kSubSamples)/sizeof(SubSample),
- .imemSizeActual = sizeof(kInBinaryBuffer),
- .imemOffset = 0,
- .imemSize = sizeof(kInBinaryBuffer),
- .srcOffset = 0,
- .dstOffset = 0xcccccc
- }));
- EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
+ // test invalid dstOffset
+ ASSERT_TRUE(
+ descrambleTestOobInput(descrambler, &descrambleStatus,
+ {.subSamples = kSubSamples,
+ .numSubSamples = sizeof(kSubSamples) / sizeof(SubSample),
+ .imemSizeActual = sizeof(kInBinaryBuffer),
+ .imemOffset = 0,
+ .imemSize = sizeof(kInBinaryBuffer),
+ .srcOffset = 0,
+ .dstOffset = 0xcccccc}));
+ EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
- // test detection of oob subsample sizes
- const SubSample invalidSubSamples1[] =
- {{162, 0}, {0, 184}, {0, 0xdddddd}};
+ // test detection of oob subsample sizes
+ const SubSample invalidSubSamples1[] = {{162, 0}, {0, 184}, {0, 0xdddddd}};
- ASSERT_TRUE(descrambleTestOobInput(
- descrambler,
- &descrambleStatus,
- {
- .subSamples = invalidSubSamples1,
- .numSubSamples = sizeof(invalidSubSamples1)/sizeof(SubSample),
- .imemSizeActual = sizeof(kInBinaryBuffer),
- .imemOffset = 0,
- .imemSize = sizeof(kInBinaryBuffer),
- .srcOffset = 0,
- .dstOffset = 0
- }));
- EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
+ ASSERT_TRUE(descrambleTestOobInput(
+ descrambler, &descrambleStatus,
+ {.subSamples = invalidSubSamples1,
+ .numSubSamples = sizeof(invalidSubSamples1) / sizeof(SubSample),
+ .imemSizeActual = sizeof(kInBinaryBuffer),
+ .imemOffset = 0,
+ .imemSize = sizeof(kInBinaryBuffer),
+ .srcOffset = 0,
+ .dstOffset = 0}));
+ EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
- // test detection of overflowing subsample sizes
- const SubSample invalidSubSamples2[] =
- {{162, 0}, {0, 184}, {2, (uint32_t)-1}};
+ // test detection of overflowing subsample sizes
+ const SubSample invalidSubSamples2[] = {{162, 0}, {0, 184}, {2, (uint32_t)-1}};
- ASSERT_TRUE(descrambleTestOobInput(
- descrambler,
- &descrambleStatus,
- {
- .subSamples = invalidSubSamples2,
- .numSubSamples = sizeof(invalidSubSamples2)/sizeof(SubSample),
- .imemSizeActual = sizeof(kInBinaryBuffer),
- .imemOffset = 0,
- .imemSize = sizeof(kInBinaryBuffer),
- .srcOffset = 0,
- .dstOffset = 0
- }));
- EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
+ ASSERT_TRUE(descrambleTestOobInput(
+ descrambler, &descrambleStatus,
+ {.subSamples = invalidSubSamples2,
+ .numSubSamples = sizeof(invalidSubSamples2) / sizeof(SubSample),
+ .imemSizeActual = sizeof(kInBinaryBuffer),
+ .imemOffset = 0,
+ .imemSize = sizeof(kInBinaryBuffer),
+ .srcOffset = 0,
+ .dstOffset = 0}));
+ EXPECT_EQ(Status::BAD_VALUE, descrambleStatus);
- returnStatus = mDescramblerBase->release();
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
-
+ returnStatus = mDescramblerBase->release();
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
returnStatus = mMediaCas->release();
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
diff --git a/cas/1.1/vts/functional/Android.bp b/cas/1.1/vts/functional/Android.bp
index de223c8..0647d12a 100644
--- a/cas/1.1/vts/functional/Android.bp
+++ b/cas/1.1/vts/functional/Android.bp
@@ -21,6 +21,7 @@
static_libs: [
"android.hardware.cas@1.0",
"android.hardware.cas@1.1",
+ "android.hardware.cas@1.2",
"android.hardware.cas.native@1.0",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
diff --git a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
index b657f07..6797506 100644
--- a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
+++ b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
@@ -22,6 +22,7 @@
#include <android/hardware/cas/1.1/ICas.h>
#include <android/hardware/cas/1.1/ICasListener.h>
#include <android/hardware/cas/1.1/IMediaCasService.h>
+#include <android/hardware/cas/1.2/IMediaCasService.h>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/cas/native/1.0/types.h>
#include <binder/MemoryDealer.h>
@@ -255,6 +256,10 @@
class MediaCasHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
+ if (android::hardware::cas::V1_2::IMediaCasService::getService(GetParam()) == nullptr) {
+ ALOGI("Descrambler is need to be tested before cas@1.2.");
+ mIsTestDescrambler = true;
+ }
mService = IMediaCasService::getService(GetParam());
ASSERT_NE(mService, nullptr);
}
@@ -269,6 +274,7 @@
sp<ICas> mMediaCas;
sp<IDescramblerBase> mDescramblerBase;
sp<MediaCasListener> mCasListener;
+ bool mIsTestDescrambler = false;
typedef struct _OobInputTestParams {
const SubSample* subSamples;
uint32_t numSubSamples;
@@ -311,8 +317,15 @@
auto descramblerStatus = mService->createDescrambler(caSystemId);
if (!descramblerStatus.isOk()) {
- return ::testing::AssertionFailure();
+ if (mIsTestDescrambler) {
+ return ::testing::AssertionFailure();
+ } else {
+ ALOGI("Skip Descrambler test since it's not required in cas@1.2.");
+ return ::testing::AssertionSuccess();
+ }
}
+ mIsTestDescrambler = true;
+
mDescramblerBase = descramblerStatus;
return ::testing::AssertionResult(mDescramblerBase != nullptr);
}
@@ -468,13 +481,15 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
- returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ if (mIsTestDescrambler) {
+ returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
- returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
hidl_vec<uint8_t> hidlNullPtr;
hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
@@ -518,29 +533,31 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
- EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
+ if (mIsTestDescrambler) {
+ EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
- sp<IDescrambler> descrambler;
- descrambler = IDescrambler::castFrom(mDescramblerBase);
- ASSERT_NE(descrambler, nullptr);
+ sp<IDescrambler> descrambler;
+ descrambler = IDescrambler::castFrom(mDescramblerBase);
+ ASSERT_NE(descrambler, nullptr);
- Status descrambleStatus = Status::OK;
- sp<IMemory> dataMemory;
+ Status descrambleStatus = Status::OK;
+ sp<IMemory> dataMemory;
- ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
- EXPECT_EQ(Status::OK, descrambleStatus);
+ ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
+ EXPECT_EQ(Status::OK, descrambleStatus);
- ASSERT_NE(nullptr, dataMemory.get());
- uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
+ ASSERT_NE(nullptr, dataMemory.get());
+ uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
- int compareResult =
- memcmp(static_cast<const void*>(opBuffer),
- static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
- EXPECT_EQ(0, compareResult);
+ int compareResult =
+ memcmp(static_cast<const void*>(opBuffer),
+ static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
+ EXPECT_EQ(0, compareResult);
- returnStatus = mDescramblerBase->release();
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ returnStatus = mDescramblerBase->release();
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
returnStatus = mMediaCas->release();
EXPECT_TRUE(returnStatus.isOk());
diff --git a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
index f436b8b..333dea6 100644
--- a/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
+++ b/cas/1.2/vts/functional/VtsHalCasV1_2TargetTest.cpp
@@ -311,6 +311,7 @@
sp<ICas> mMediaCas;
sp<IDescramblerBase> mDescramblerBase;
sp<MediaCasListener> mCasListener;
+ bool mIsTestDescrambler = false;
typedef struct _OobInputTestParams {
const SubSample* subSamples;
uint32_t numSubSamples;
@@ -355,8 +356,11 @@
auto descramblerStatus = mService->createDescrambler(caSystemId);
if (!descramblerStatus.isOk()) {
- return ::testing::AssertionFailure();
+ ALOGI("Skip Descrambler test since it's not required in cas@1.2.");
+ return ::testing::AssertionSuccess();
}
+ mIsTestDescrambler = true;
+
mDescramblerBase = descramblerStatus;
return ::testing::AssertionResult(mDescramblerBase != nullptr);
}
@@ -512,14 +516,15 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
- returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ if (mIsTestDescrambler) {
+ returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
- returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
-
+ returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
hidl_vec<uint8_t> hidlNullPtr;
hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
@@ -566,29 +571,31 @@
EXPECT_TRUE(returnStatus.isOk());
EXPECT_EQ(Status::OK, returnStatus);
- EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
+ if (mIsTestDescrambler) {
+ EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
- sp<IDescrambler> descrambler;
- descrambler = IDescrambler::castFrom(mDescramblerBase);
- ASSERT_NE(descrambler, nullptr);
+ sp<IDescrambler> descrambler;
+ descrambler = IDescrambler::castFrom(mDescramblerBase);
+ ASSERT_NE(descrambler, nullptr);
- Status descrambleStatus = Status::OK;
- sp<IMemory> dataMemory;
+ Status descrambleStatus = Status::OK;
+ sp<IMemory> dataMemory;
- ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
- EXPECT_EQ(Status::OK, descrambleStatus);
+ ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
+ EXPECT_EQ(Status::OK, descrambleStatus);
- ASSERT_NE(nullptr, dataMemory.get());
- uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
+ ASSERT_NE(nullptr, dataMemory.get());
+ uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
- int compareResult =
- memcmp(static_cast<const void*>(opBuffer),
- static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
- EXPECT_EQ(0, compareResult);
+ int compareResult =
+ memcmp(static_cast<const void*>(opBuffer),
+ static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
+ EXPECT_EQ(0, compareResult);
- returnStatus = mDescramblerBase->release();
- EXPECT_TRUE(returnStatus.isOk());
- EXPECT_EQ(Status::OK, returnStatus);
+ returnStatus = mDescramblerBase->release();
+ EXPECT_TRUE(returnStatus.isOk());
+ EXPECT_EQ(Status::OK, returnStatus);
+ }
returnStatus = mMediaCas->release();
EXPECT_TRUE(returnStatus.isOk());
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 6938030..7c41d1f 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -27,6 +27,14 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.authsecret</name>
+ <version>1</version>
+ <interface>
+ <name>IAuthSecret</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
<hal format="hidl" optional="true">
<name>android.hardware.authsecret</name>
<version>1.0</version>
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index 846148f..218e823 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -37,6 +37,10 @@
static constexpr const char* FEATURE_TELEPHONY = "android.hardware.telephony";
+static constexpr const char* FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
+
+static constexpr const char* FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
+
/*
* Generate random serial number for radio test
*/
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 4dcf1f3..b0b984c 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -34,8 +34,9 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
- } else if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
- ALOGI("Skipping emergencyDial because telephony radio is not supported in device");
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
@@ -89,8 +90,9 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
- } else if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
- ALOGI("Skipping emergencyDial because telephony radio is not supported in device");
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
@@ -144,8 +146,9 @@
if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
ALOGI("Skipping emergencyDial because voice call is not supported in device");
return;
- } else if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
- ALOGI("Skipping emergencyDial because telephony radio is not supported in device");
+ } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+ !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+ ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
return;
} else {
ALOGI("Running emergencyDial because voice call is supported in device");
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 550e079..594c208 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -281,7 +281,7 @@
* suggestion. 0 indicates retry should be performed immediately. 0x7fffffffffffffff indicates
* the device should not retry data setup anymore.
*/
- uint64_t suggestedRetryTime;
+ int64_t suggestedRetryTime;
/** Context ID, uniquely identifies this data connection. */
int32_t cid;
diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal
index bedb709..ba964bf 100644
--- a/radio/config/1.3/types.hal
+++ b/radio/config/1.3/types.hal
@@ -19,4 +19,10 @@
/**
* Contains the device capabilities with respect to the Radio HAL.
*/
-struct HalDeviceCapabilities {};
+struct HalDeviceCapabilities {
+ /**
+ * True indicates that the modem is missing features within the current
+ * version of the Radio HAL.
+ */
+ bool modemReducedFeatureSet1;
+};
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl
index 6ab7ac5..3071dce3 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePrimitive.aidl
@@ -26,4 +26,5 @@
SLOW_RISE = 5,
QUICK_FALL = 6,
LIGHT_TICK = 7,
+ LOW_TICK = 8,
}
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
index 8e82db0..5314898 100644
--- a/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/CompositePrimitive.aidl
@@ -70,4 +70,11 @@
* Support is required.
*/
LIGHT_TICK,
+ /**
+ * This very short low frequency effect should produce a light crisp sensation intended
+ * to be used repetitively for dynamic feedback.
+ *
+ * Support is required.
+ */
+ LOW_TICK,
}
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index c446afd..1021e62 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -119,6 +119,7 @@
CompositePrimitive::THUD, CompositePrimitive::SPIN,
CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
CompositePrimitive::QUICK_FALL, CompositePrimitive::LIGHT_TICK,
+ CompositePrimitive::LOW_TICK,
};
return ndk::ScopedAStatus::ok();
}
diff --git a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
index efcebda..c6f05fb 100644
--- a/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.hal
@@ -20,7 +20,9 @@
import @1.0::ISupplicantStaIfaceCallback.Hs20AnqpData;
import @1.3::ISupplicantStaIfaceCallback;
import @1.0::ISupplicantStaIfaceCallback.State;
+import @1.0::ISupplicantStaIfaceCallback.StatusCode;
import @1.0::Bssid;
+import @1.0::Ssid;
/**
* Callback Interface exposed by the supplicant service
@@ -32,6 +34,19 @@
*/
interface ISupplicantStaIfaceCallback extends @1.3::ISupplicantStaIfaceCallback {
/**
+ * MBO spec v1.2, 4.2.4 Table 14: MBO Association disallowed reason code attribute
+ * values.
+ */
+ enum MboAssocDisallowedReasonCode : uint8_t {
+ RESERVED = 0,
+ UNSPECIFIED = 1,
+ MAX_NUM_STA_ASSOCIATED = 2,
+ AIR_INTERFACE_OVERLOADED = 3,
+ AUTH_SERVER_OVERLOADED = 4,
+ INSUFFICIENT_RSSI = 5,
+ };
+
+ /**
* ANQP data for IEEE Std 802.11-2016.
* The format of the data within these elements follows the IEEE
* Std 802.11-2016 standard, section 9.4.5.
@@ -49,6 +64,83 @@
};
/**
+ * OceRssiBasedAssocRejectAttr is extracted from (Re-)Association response
+ * frame from an OCE AP to indicate that the AP has rejected the
+ * (Re-)Association request on the basis of insufficient RSSI.
+ * Refer OCE spec v1.0 section 4.2.2 Table 7.
+ */
+ struct OceRssiBasedAssocRejectAttr {
+ /*
+ * Delta RSSI - The difference in dB between the minimum RSSI at which
+ * the AP would accept a (Re-)Association request from the STA before
+ * Retry Delay expires and the AP's measurement of the RSSI at which the
+ * (Re-)Association request was received.
+ */
+ uint32_t deltaRssi;
+
+ /*
+ * Retry Delay - The time period in seconds for which the AP will not
+ * accept any subsequent (Re-)Association requests from the STA, unless
+ * the received RSSI has improved by Delta RSSI.
+ */
+ uint32_t retryDelayS;
+ };
+
+ /**
+ * Association Rejection related information.
+ */
+ struct AssociationRejectionData {
+ /**
+ * SSID of the AP that rejected the association.
+ */
+ Ssid ssid;
+
+ /**
+ * BSSID of the AP that rejected the association.
+ */
+ Bssid bssid;
+
+ /*
+ * 802.11 code to indicate the reject reason.
+ * Refer to section 8.4.1.9 of IEEE 802.11 spec.
+ */
+ StatusCode statusCode;
+
+ /*
+ * Flag to indicate that failure is due to timeout rather than
+ * explicit rejection response from the AP.
+ */
+ bool timedOut;
+
+ /**
+ * Flag to indicate that MboAssocDisallowedReasonCode is present
+ * in the (Re-)Association response frame.
+ */
+ bool isMboAssocDisallowedReasonCodePresent;
+
+ /**
+ * mboAssocDisallowedReason is extracted from MBO association disallowed attribute
+ * in (Re-)Association response frame to indicate that the AP is not accepting new
+ * associations.
+ * Refer MBO spec v1.2 section 4.2.4 Table 13 for the details of reason code.
+ * The value is undefined if isMboAssocDisallowedReasonCodePresent is false.
+ */
+ MboAssocDisallowedReasonCode mboAssocDisallowedReason;
+
+ /**
+ * Flag to indicate that OceRssiBasedAssocRejectAttr is present
+ * in the (Re-)Association response frame.
+ */
+ bool isOceRssiBasedAssocRejectAttrPresent;
+
+ /*
+ * OCE RSSI-based (Re-)Association rejection attribute.
+ * The contents are undefined if isOceRssiBasedAssocRejectAttrPresent is false.
+ */
+ OceRssiBasedAssocRejectAttr oceRssiBasedAssocRejectData;
+ };
+
+ /**
* Used to indicate a Hotspot 2.0 terms and conditions acceptance is requested from the user
* before allowing the device to get internet access.
*
@@ -68,4 +160,12 @@
* All the fields in this struct must be empty if the query failed.
*/
oneway onAnqpQueryDone_1_4(Bssid bssid, AnqpData data, Hs20AnqpData hs20Data);
+
+ /**
+ * Used to indicate an association rejection received from the AP
+ * to which the connection is being attempted.
+ *
+ * @param assocRejectData Association Rejection related information.
+ */
+ oneway onAssociationRejected_1_4(AssociationRejectionData assocRejectData);
};
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
index ccd469d..1794a39 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -232,6 +232,11 @@
override {
return Void();
}
+ Return<void> onAssociationRejected_1_4(
+ const ISupplicantStaIfaceCallback::AssociationRejectionData& /* data */)
+ override {
+ return Void();
+ }
};
/*