Merge "vts: Correct the test RSA key format"
diff --git a/audio/7.0/IStreamOutEventCallback.hal b/audio/7.0/IStreamOutEventCallback.hal
index 4de767f..8ef0060 100644
--- a/audio/7.0/IStreamOutEventCallback.hal
+++ b/audio/7.0/IStreamOutEventCallback.hal
@@ -51,6 +51,25 @@
* "has-atmos", int32
* "audio-encoding", int32
*
+ * S (audio HAL 7.0) in addition adds the following keys:
+ * "presentation-id", int32
+ * "program-id", int32
+ * "presentation-content-classifier", int32
+ * presentation-content-classifier key values can be referenced from
+ * frameworks/base/media/java/android/media/AudioPresentation.java
+ * i.e AudioPresentation.ContentClassifier
+ * It can contain any of the below values
+ * CONTENT_UNKNOWN = -1,
+ * CONTENT_MAIN = 0,
+ * CONTENT_MUSIC_AND_EFFECTS = 1,
+ * CONTENT_VISUALLY_IMPAIRED = 2,
+ * CONTENT_HEARING_IMPAIRED = 3,
+ * CONTENT_DIALOG = 4,
+ * CONTENT_COMMENTARY = 5,
+ * CONTENT_EMERGENCY = 6,
+ * CONTENT_VOICEOVER = 7
+ * "presentation-language", string // represents ISO 639-2 (three letter code)
+ *
* Parceling Format:
* All values are native endian order. [1]
*
diff --git a/audio/core/all-versions/default/TEST_MAPPING b/audio/core/all-versions/default/TEST_MAPPING
index d53c97a..1e29440 100644
--- a/audio/core/all-versions/default/TEST_MAPPING
+++ b/audio/core/all-versions/default/TEST_MAPPING
@@ -2,6 +2,12 @@
"presubmit": [
{
"name": "android.hardware.audio@7.0-util_tests"
+ },
+ {
+ "name": "HalAudioV6_0GeneratorTest"
+ },
+ {
+ "name": "HalAudioV7_0GeneratorTest"
}
]
}
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 0ebe4c2..8af4c78 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -17,105 +17,6 @@
// pull in all the <= 5.0 tests
#include "5.0/AudioPrimaryHidlHalTest.cpp"
-#if MAJOR_VERSION <= 6
-static std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(
- bool oneProfilePerDevice) {
- std::vector<DeviceConfigParameter> result;
- for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
- for (const auto& ioProfile : module->getOutputProfiles()) {
- for (const auto& profile : ioProfile->getAudioProfiles()) {
- const auto& channels = profile->getChannels();
- const auto& sampleRates = profile->getSampleRates();
- auto configs = ConfigHelper::combineAudioConfig(
- std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
- std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
- profile->getFormat());
- auto flags = ioProfile->getFlags();
- for (auto& config : configs) {
- // Some combinations of flags declared in the config file require special
- // treatment.
- if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
- config.offloadInfo.sampleRateHz = config.sampleRateHz;
- config.offloadInfo.channelMask = config.channelMask;
- config.offloadInfo.format = config.format;
- config.offloadInfo.streamType = AudioStreamType::MUSIC;
- config.offloadInfo.bitRatePerSecond = 320;
- config.offloadInfo.durationMicroseconds = -1;
- config.offloadInfo.bitWidth = 16;
- config.offloadInfo.bufferSize = 256; // arbitrary value
- config.offloadInfo.usage = AudioUsage::MEDIA;
- result.emplace_back(device, config,
- AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD |
- AudioOutputFlag::DIRECT));
- } else {
- if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
- flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
- }
- result.emplace_back(device, config, AudioOutputFlag(flags));
- }
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- }
- return result;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateOutputDeviceConfigParameters(false);
- return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateOutputDeviceConfigParameters(true);
- return parameters;
-}
-
-static std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(
- bool oneProfilePerDevice) {
- std::vector<DeviceConfigParameter> result;
- for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
- for (const auto& ioProfile : module->getInputProfiles()) {
- for (const auto& profile : ioProfile->getAudioProfiles()) {
- const auto& channels = profile->getChannels();
- const auto& sampleRates = profile->getSampleRates();
- auto configs = ConfigHelper::combineAudioConfig(
- std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
- std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
- profile->getFormat());
- for (const auto& config : configs) {
- result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- }
- return result;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateInputDeviceConfigParameters(false);
- return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateInputDeviceConfigParameters(true);
- return parameters;
-}
-#endif // MAJOR_VERSION <= 6
-
class SingleConfigOutputStreamTest : public OutputStreamTest {};
TEST_P(SingleConfigOutputStreamTest, CloseDeviceWithOpenedOutputStreams) {
doc::test("Verify that a device can't be closed if there are output streams opened");
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
new file mode 100644
index 0000000..6b4dbc1
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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/macros.h>
+
+#include "6.0/Generators.h"
+#include "ConfigHelper.h"
+#include "PolicyConfig.h"
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+// Forward declaration for functions that are substituted
+// in generator unit tests.
+const PolicyConfig& getCachedPolicyConfig();
+const std::vector<DeviceParameter>& getDeviceParameters();
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ for (const auto& ioProfile : module->getOutputProfiles()) {
+ for (const auto& profile : ioProfile->getAudioProfiles()) {
+ const auto& channels = profile->getChannels();
+ const auto& sampleRates = profile->getSampleRates();
+ auto configs = ConfigHelper::combineAudioConfig(
+ std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+ std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+ profile->getFormat());
+ auto flags = ioProfile->getFlags();
+ for (auto& config : configs) {
+ // Some combinations of flags declared in the config file require special
+ // treatment.
+ if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+ config.offloadInfo.sampleRateHz = config.sampleRateHz;
+ config.offloadInfo.channelMask = config.channelMask;
+ config.offloadInfo.format = config.format;
+ config.offloadInfo.streamType = AudioStreamType::MUSIC;
+ config.offloadInfo.bitRatePerSecond = 320;
+ config.offloadInfo.durationMicroseconds = -1;
+ config.offloadInfo.bitWidth = 16;
+ config.offloadInfo.bufferSize = 256; // arbitrary value
+ config.offloadInfo.usage = AudioUsage::MEDIA;
+ result.emplace_back(device, config,
+ AudioOutputFlag(AudioOutputFlag::COMPRESS_OFFLOAD |
+ AudioOutputFlag::DIRECT));
+ } else {
+ if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) { // ignore the flag
+ flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
+ }
+ result.emplace_back(device, config, AudioOutputFlag(flags));
+ }
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ }
+ return result;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateOutputDeviceConfigParameters(false);
+ return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateOutputDeviceConfigParameters(true);
+ return parameters;
+}
+
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ for (const auto& ioProfile : module->getInputProfiles()) {
+ for (const auto& profile : ioProfile->getAudioProfiles()) {
+ const auto& channels = profile->getChannels();
+ const auto& sampleRates = profile->getSampleRates();
+ auto configs = ConfigHelper::combineAudioConfig(
+ std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+ std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+ profile->getFormat());
+ for (const auto& config : configs) {
+ result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ }
+ return result;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateInputDeviceConfigParameters(false);
+ return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateInputDeviceConfigParameters(true);
+ return parameters;
+}
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.h b/audio/core/all-versions/vts/functional/6.0/Generators.h
new file mode 100644
index 0000000..1e87163
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.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 <vector>
+
+#include "AudioTestDefinitions.h"
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
+
+// For unit tests
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice);
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice);
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 be1ffbb..c1923f1 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -14,277 +14,11 @@
* limitations under the License.
*/
+#include "Generators.h"
+
// pull in all the <= 6.0 tests
#include "6.0/AudioPrimaryHidlHalTest.cpp"
-static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
- std::vector<int64_t> sampleRates,
- const std::string& format) {
- std::vector<AudioConfig> configs;
- configs.reserve(channelMasks.size() * sampleRates.size());
- for (auto channelMask : channelMasks) {
- for (auto sampleRate : sampleRates) {
- AudioConfig config{};
- config.base.channelMask = toString(channelMask);
- config.base.sampleRateHz = sampleRate;
- config.base.format = format;
- configs.push_back(config);
- }
- }
- return configs;
-}
-
-static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
- const xsd::MixPorts::MixPort& mixPort) {
- static const std::vector<AudioInOutFlag> offloadFlags = {
- toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
- toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
- std::vector<AudioInOutFlag> flags;
- bool isOffload = false;
- if (mixPort.hasFlags()) {
- auto xsdFlags = mixPort.getFlags();
- isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
- xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
- xsdFlags.end();
- if (!isOffload) {
- for (auto flag : xsdFlags) {
- if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
- flags.push_back(toString(flag));
- }
- }
- } else {
- flags = offloadFlags;
- }
- }
- return {flags, isOffload};
-}
-
-static AudioOffloadInfo generateOffloadInfo(const AudioConfigBase& base) {
- return AudioOffloadInfo{
- .base = base,
- .streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
- .usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
- .bitRatePerSecond = 320,
- .durationMicroseconds = -1,
- .bitWidth = 16,
- .bufferSize = 256 // arbitrary value
- };
-}
-
-static std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(
- bool oneProfilePerDevice) {
- std::vector<DeviceConfigParameter> result;
- for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
- if (!module || !module->getFirstMixPorts()) break;
- for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
- if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
- auto [flags, isOffload] = generateOutFlags(mixPort);
- for (const auto& profile : mixPort.getProfile()) {
- auto configs = combineAudioConfig(profile.getChannelMasks(),
- profile.getSamplingRates(), profile.getFormat());
- for (auto& config : configs) {
- // Some combinations of flags declared in the config file require special
- // treatment.
- if (isOffload) {
- config.offloadInfo.info(generateOffloadInfo(config.base));
- }
- result.emplace_back(device, config, flags);
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- }
- return result;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateOutputDeviceConfigParameters(false);
- return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateOutputDeviceConfigParameters(true);
- return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
- bool generateInvalidFlags = true) {
- static std::vector<DeviceConfigParameter> parameters = [&] {
- std::vector<DeviceConfigParameter> result;
- for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
- if (!module || !module->getFirstMixPorts()) break;
- bool hasRegularConfig = false, hasOffloadConfig = false;
- for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
- if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
- auto [validFlags, isOffload] = generateOutFlags(mixPort);
- if ((!isOffload && hasRegularConfig) || (isOffload && hasOffloadConfig)) continue;
- for (const auto& profile : mixPort.getProfile()) {
- if (!profile.hasFormat() || !profile.hasSamplingRates() ||
- !profile.hasChannelMasks())
- continue;
- AudioConfigBase validBase = {
- profile.getFormat(),
- static_cast<uint32_t>(profile.getSamplingRates()[0]),
- toString(profile.getChannelMasks()[0])};
- {
- AudioConfig config{.base = validBase};
- config.base.channelMask = "random_string";
- if (isOffload) {
- config.offloadInfo.info(generateOffloadInfo(validBase));
- }
- result.emplace_back(device, config, validFlags);
- }
- {
- AudioConfig config{.base = validBase};
- config.base.format = "random_string";
- if (isOffload) {
- config.offloadInfo.info(generateOffloadInfo(validBase));
- }
- result.emplace_back(device, config, validFlags);
- }
- if (generateInvalidFlags) {
- AudioConfig config{.base = validBase};
- if (isOffload) {
- config.offloadInfo.info(generateOffloadInfo(validBase));
- }
- std::vector<AudioInOutFlag> flags = {"random_string", ""};
- result.emplace_back(device, config, flags);
- }
- if (isOffload) {
- {
- AudioConfig config{.base = validBase};
- config.offloadInfo.info(generateOffloadInfo(validBase));
- config.offloadInfo.info().base.channelMask = "random_string";
- }
- {
- AudioConfig config{.base = validBase};
- config.offloadInfo.info(generateOffloadInfo(validBase));
- config.offloadInfo.info().base.format = "random_string";
- }
- {
- AudioConfig config{.base = validBase};
- config.offloadInfo.info(generateOffloadInfo(validBase));
- config.offloadInfo.info().streamType = "random_string";
- }
- {
- AudioConfig config{.base = validBase};
- config.offloadInfo.info(generateOffloadInfo(validBase));
- config.offloadInfo.info().usage = "random_string";
- }
- hasOffloadConfig = true;
- } else {
- hasRegularConfig = true;
- }
- break;
- }
- if (hasOffloadConfig && hasRegularConfig) break;
- }
- }
- return result;
- }();
- return parameters;
-}
-
-static std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(
- bool oneProfilePerDevice) {
- std::vector<DeviceConfigParameter> result;
- for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
- if (!module || !module->getFirstMixPorts()) break;
- for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
- if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
- std::vector<AudioInOutFlag> flags;
- if (mixPort.hasFlags()) {
- std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
- std::back_inserter(flags), [](auto flag) { return toString(flag); });
- }
- for (const auto& profile : mixPort.getProfile()) {
- auto configs = combineAudioConfig(profile.getChannelMasks(),
- profile.getSamplingRates(), profile.getFormat());
- for (const auto& config : configs) {
- result.emplace_back(device, config, flags);
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- if (oneProfilePerDevice) break;
- }
- }
- return result;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateInputDeviceConfigParameters(false);
- return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
- static std::vector<DeviceConfigParameter> parameters =
- generateInputDeviceConfigParameters(true);
- return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
- bool generateInvalidFlags = true) {
- static std::vector<DeviceConfigParameter> parameters = [&] {
- std::vector<DeviceConfigParameter> result;
- for (const auto& device : getDeviceParameters()) {
- auto module =
- getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
- if (!module || !module->getFirstMixPorts()) break;
- bool hasConfig = false;
- for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
- if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
- std::vector<AudioInOutFlag> validFlags;
- if (mixPort.hasFlags()) {
- std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
- std::back_inserter(validFlags),
- [](auto flag) { return toString(flag); });
- }
- for (const auto& profile : mixPort.getProfile()) {
- if (!profile.hasFormat() || !profile.hasSamplingRates() ||
- !profile.hasChannelMasks())
- continue;
- AudioConfigBase validBase = {
- profile.getFormat(),
- static_cast<uint32_t>(profile.getSamplingRates()[0]),
- toString(profile.getChannelMasks()[0])};
- {
- AudioConfig config{.base = validBase};
- config.base.channelMask = "random_string";
- result.emplace_back(device, config, validFlags);
- }
- {
- AudioConfig config{.base = validBase};
- config.base.format = "random_string";
- result.emplace_back(device, config, validFlags);
- }
- if (generateInvalidFlags) {
- AudioConfig config{.base = validBase};
- std::vector<AudioInOutFlag> flags = {"random_string", ""};
- result.emplace_back(device, config, flags);
- }
- hasConfig = true;
- break;
- }
- if (hasConfig) break;
- }
- }
- return result;
- }();
- return parameters;
-}
-
class InvalidInputConfigNoFlagsTest : public AudioHidlTestWithDeviceConfigParameter {};
TEST_P(InvalidInputConfigNoFlagsTest, InputBufferSizeTest) {
doc::test("Verify that invalid config is rejected by IDevice::getInputBufferSize method.");
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.cpp b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
new file mode 100644
index 0000000..eafc813
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -0,0 +1,309 @@
+/*
+ * 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/macros.h>
+
+#include "7.0/Generators.h"
+#include "7.0/PolicyConfig.h"
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+#include <android_audio_policy_configuration_V7_0-enums.h>
+#include <android_audio_policy_configuration_V7_0.h>
+
+// Forward declaration for functions that are substituted
+// in generator unit tests.
+const PolicyConfig& getCachedPolicyConfig();
+const std::vector<DeviceParameter>& getDeviceParameters();
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+namespace xsd {
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
+}
+
+static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
+ std::vector<int64_t> sampleRates,
+ const std::string& format) {
+ std::vector<AudioConfig> configs;
+ configs.reserve(channelMasks.size() * sampleRates.size());
+ for (auto channelMask : channelMasks) {
+ for (auto sampleRate : sampleRates) {
+ AudioConfig config{};
+ config.base.channelMask = toString(channelMask);
+ config.base.sampleRateHz = sampleRate;
+ config.base.format = format;
+ configs.push_back(config);
+ }
+ }
+ return configs;
+}
+
+static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
+ const xsd::MixPorts::MixPort& mixPort) {
+ static const std::vector<AudioInOutFlag> offloadFlags = {
+ toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
+ toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
+ std::vector<AudioInOutFlag> flags;
+ bool isOffload = false;
+ if (mixPort.hasFlags()) {
+ auto xsdFlags = mixPort.getFlags();
+ isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
+ xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
+ xsdFlags.end();
+ if (!isOffload) {
+ for (auto flag : xsdFlags) {
+ if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
+ flags.push_back(toString(flag));
+ }
+ }
+ } else {
+ flags = offloadFlags;
+ }
+ }
+ return {flags, isOffload};
+}
+
+static AudioOffloadInfo generateOffloadInfo(const AudioConfigBase& base) {
+ return AudioOffloadInfo{
+ .base = base,
+ .streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
+ .usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
+ .bitRatePerSecond = 320,
+ .durationMicroseconds = -1,
+ .bitWidth = 16,
+ .bufferSize = 256 // arbitrary value
+ };
+}
+
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ if (!module || !module->getFirstMixPorts()) break;
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
+ auto [flags, isOffload] = generateOutFlags(mixPort);
+ for (const auto& profile : mixPort.getProfile()) {
+ auto configs = combineAudioConfig(profile.getChannelMasks(),
+ profile.getSamplingRates(), profile.getFormat());
+ for (auto& config : configs) {
+ // Some combinations of flags declared in the config file require special
+ // treatment.
+ if (isOffload) {
+ config.offloadInfo.info(generateOffloadInfo(config.base));
+ }
+ result.emplace_back(device, config, flags);
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ }
+ return result;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateOutputDeviceConfigParameters(false);
+ return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateOutputDeviceConfigParameters(true);
+ return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
+ bool generateInvalidFlags) {
+ static std::vector<DeviceConfigParameter> parameters = [&] {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ if (!module || !module->getFirstMixPorts()) break;
+ bool hasRegularConfig = false, hasOffloadConfig = false;
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
+ auto [validFlags, isOffload] = generateOutFlags(mixPort);
+ if ((!isOffload && hasRegularConfig) || (isOffload && hasOffloadConfig)) continue;
+ for (const auto& profile : mixPort.getProfile()) {
+ if (!profile.hasFormat() || !profile.hasSamplingRates() ||
+ !profile.hasChannelMasks())
+ continue;
+ AudioConfigBase validBase = {
+ profile.getFormat(),
+ static_cast<uint32_t>(profile.getSamplingRates()[0]),
+ toString(profile.getChannelMasks()[0])};
+ {
+ AudioConfig config{.base = validBase};
+ config.base.channelMask = "random_string";
+ if (isOffload) {
+ config.offloadInfo.info(generateOffloadInfo(validBase));
+ }
+ result.emplace_back(device, config, validFlags);
+ }
+ {
+ AudioConfig config{.base = validBase};
+ config.base.format = "random_string";
+ if (isOffload) {
+ config.offloadInfo.info(generateOffloadInfo(validBase));
+ }
+ result.emplace_back(device, config, validFlags);
+ }
+ if (generateInvalidFlags) {
+ AudioConfig config{.base = validBase};
+ if (isOffload) {
+ config.offloadInfo.info(generateOffloadInfo(validBase));
+ }
+ std::vector<AudioInOutFlag> flags = {"random_string", ""};
+ result.emplace_back(device, config, flags);
+ }
+ if (isOffload) {
+ {
+ AudioConfig config{.base = validBase};
+ config.offloadInfo.info(generateOffloadInfo(validBase));
+ config.offloadInfo.info().base.channelMask = "random_string";
+ result.emplace_back(device, config, validFlags);
+ }
+ {
+ AudioConfig config{.base = validBase};
+ config.offloadInfo.info(generateOffloadInfo(validBase));
+ config.offloadInfo.info().base.format = "random_string";
+ result.emplace_back(device, config, validFlags);
+ }
+ {
+ AudioConfig config{.base = validBase};
+ config.offloadInfo.info(generateOffloadInfo(validBase));
+ config.offloadInfo.info().streamType = "random_string";
+ result.emplace_back(device, config, validFlags);
+ }
+ {
+ AudioConfig config{.base = validBase};
+ config.offloadInfo.info(generateOffloadInfo(validBase));
+ config.offloadInfo.info().usage = "random_string";
+ result.emplace_back(device, config, validFlags);
+ }
+ hasOffloadConfig = true;
+ } else {
+ hasRegularConfig = true;
+ }
+ break;
+ }
+ if (hasOffloadConfig && hasRegularConfig) break;
+ }
+ }
+ return result;
+ }();
+ return parameters;
+}
+
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ if (!module || !module->getFirstMixPorts()) break;
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
+ std::vector<AudioInOutFlag> flags;
+ if (mixPort.hasFlags()) {
+ std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
+ std::back_inserter(flags), [](auto flag) { return toString(flag); });
+ }
+ for (const auto& profile : mixPort.getProfile()) {
+ auto configs = combineAudioConfig(profile.getChannelMasks(),
+ profile.getSamplingRates(), profile.getFormat());
+ for (const auto& config : configs) {
+ result.emplace_back(device, config, flags);
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ if (oneProfilePerDevice) break;
+ }
+ }
+ return result;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateInputDeviceConfigParameters(false);
+ return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
+ static std::vector<DeviceConfigParameter> parameters =
+ generateInputDeviceConfigParameters(true);
+ return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
+ bool generateInvalidFlags) {
+ static std::vector<DeviceConfigParameter> parameters = [&] {
+ std::vector<DeviceConfigParameter> result;
+ for (const auto& device : getDeviceParameters()) {
+ auto module =
+ getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+ if (!module || !module->getFirstMixPorts()) break;
+ bool hasConfig = false;
+ for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+ if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
+ std::vector<AudioInOutFlag> validFlags;
+ if (mixPort.hasFlags()) {
+ std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
+ std::back_inserter(validFlags),
+ [](auto flag) { return toString(flag); });
+ }
+ for (const auto& profile : mixPort.getProfile()) {
+ if (!profile.hasFormat() || !profile.hasSamplingRates() ||
+ !profile.hasChannelMasks())
+ continue;
+ AudioConfigBase validBase = {
+ profile.getFormat(),
+ static_cast<uint32_t>(profile.getSamplingRates()[0]),
+ toString(profile.getChannelMasks()[0])};
+ {
+ AudioConfig config{.base = validBase};
+ config.base.channelMask = "random_string";
+ result.emplace_back(device, config, validFlags);
+ }
+ {
+ AudioConfig config{.base = validBase};
+ config.base.format = "random_string";
+ result.emplace_back(device, config, validFlags);
+ }
+ if (generateInvalidFlags) {
+ AudioConfig config{.base = validBase};
+ std::vector<AudioInOutFlag> flags = {"random_string", ""};
+ result.emplace_back(device, config, flags);
+ }
+ hasConfig = true;
+ break;
+ }
+ if (hasConfig) break;
+ }
+ }
+ return result;
+ }();
+ return parameters;
+}
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.h b/audio/core/all-versions/vts/functional/7.0/Generators.h
new file mode 100644
index 0000000..e36cfad
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.h
@@ -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.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "AudioTestDefinitions.h"
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
+const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
+ bool generateInvalidFlags = true);
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
+ bool generateInvalidFlags = true);
+
+// For unit tests
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice);
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice);
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
index 7d88642..feb4d4b 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -16,11 +16,35 @@
#pragma once
-// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
-// and thus it doesn't have all '#include' and 'using' directives required
-// for a standalone compilation.
+#include <fcntl.h>
+#include <unistd.h>
+#include <optional>
+#include <set>
+#include <string>
+
+#include <gtest/gtest.h>
+#include <system/audio_config.h>
+#include <utils/Errors.h>
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+#include <android_audio_policy_configuration_V7_0-enums.h>
+#include <android_audio_policy_configuration_V7_0.h>
+
+#include "DeviceManager.h"
+
+using ::android::NO_INIT;
+using ::android::OK;
+using ::android::status_t;
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
namespace xsd {
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
using Module = Modules::Module;
}
@@ -30,20 +54,13 @@
: mConfigFileName{configFileName},
mFilePath{findExistingConfigurationFile(mConfigFileName)},
mConfig{xsd::read(mFilePath.c_str())} {
- if (mConfig) {
- mStatus = OK;
- mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
- if (mConfig->getFirstModules()) {
- for (const auto& module : mConfig->getFirstModules()->get_module()) {
- if (module.getFirstAttachedDevices()) {
- auto attachedDevices = module.getFirstAttachedDevices()->getItem();
- if (!attachedDevices.empty()) {
- mModulesWithDevicesNames.insert(module.getName());
- }
- }
- }
- }
- }
+ init();
+ }
+ PolicyConfig(const std::string& configPath, const std::string& configFileName)
+ : mConfigFileName{configFileName},
+ mFilePath{configPath + "/" + mConfigFileName},
+ mConfig{xsd::read(mFilePath.c_str())} {
+ init();
}
status_t getStatus() const { return mStatus; }
std::string getError() const {
@@ -87,6 +104,22 @@
}
return std::string{};
}
+ void init() {
+ if (mConfig) {
+ mStatus = OK;
+ mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
+ if (mConfig->getFirstModules()) {
+ for (const auto& module : mConfig->getFirstModules()->get_module()) {
+ if (module.getFirstAttachedDevices()) {
+ auto attachedDevices = module.getFirstAttachedDevices()->getItem();
+ if (!attachedDevices.empty()) {
+ mModulesWithDevicesNames.insert(module.getName());
+ }
+ }
+ }
+ }
+ }
+ }
const std::string mConfigFileName;
const std::string mFilePath;
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 4520dc3..91c54dc 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -126,6 +126,7 @@
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
"6.0/AudioPrimaryHidlHalTest.cpp",
+ "6.0/Generators.cpp",
],
static_libs: [
"libaudiofoundation",
@@ -152,6 +153,7 @@
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
"7.0/AudioPrimaryHidlHalTest.cpp",
+ "7.0/Generators.cpp",
],
generated_headers: ["audio_policy_configuration_V7_0_parser"],
generated_sources: ["audio_policy_configuration_V7_0_parser"],
@@ -172,3 +174,57 @@
// TODO(b/146104851): Add auto-gen rules and remove it.
test_config: "VtsHalAudioV7_0TargetTest.xml",
}
+
+// Note: the following aren't VTS tests, but rather unit tests
+// to verify correctness of test parameter generator utilities.
+cc_test {
+ name: "HalAudioV6_0GeneratorTest",
+ defaults: ["VtsHalAudioTargetTest_defaults"],
+ srcs: [
+ "6.0/Generators.cpp",
+ "tests/generators_tests.cpp",
+ ],
+ static_libs: [
+ "android.hardware.audio@6.0",
+ "android.hardware.audio.common@6.0",
+ "libaudiofoundation",
+ "libaudiopolicycomponents",
+ "libmedia_helper",
+ ],
+ cflags: [
+ "-DMAJOR_VERSION=6",
+ "-DMINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+ data: [
+ "tests/apm_config_no_vx.xml",
+ "tests/apm_config_with_vx.xml",
+ ],
+ test_config: "tests/HalAudioV6_0GeneratorTest.xml",
+}
+
+cc_test {
+ name: "HalAudioV7_0GeneratorTest",
+ defaults: ["VtsHalAudioTargetTest_defaults"],
+ srcs: [
+ "7.0/Generators.cpp",
+ "tests/generators_tests.cpp",
+ ],
+ generated_headers: ["audio_policy_configuration_V7_0_parser"],
+ generated_sources: ["audio_policy_configuration_V7_0_parser"],
+ static_libs: [
+ "android.hardware.audio@7.0",
+ "android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.0-enums",
+ ],
+ cflags: [
+ "-DMAJOR_VERSION=7",
+ "-DMINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+ data: [
+ "tests/apm_config_no_vx_7_0.xml",
+ "tests/apm_config_with_vx_7_0.xml",
+ ],
+ test_config: "tests/HalAudioV7_0GeneratorTest.xml",
+}
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 61e99e8..56939fe 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -59,6 +59,7 @@
#include "utility/ReturnIn.h"
#include "utility/ValidateXml.h"
+#include "AudioTestDefinitions.h"
/** Provide version specific functions that are used in the generic tests */
#if MAJOR_VERSION == 2
#include "2.0/AudioPrimaryHidlHalUtils.h"
@@ -107,7 +108,11 @@
#include "DeviceManager.h"
#if MAJOR_VERSION <= 6
#include "PolicyConfig.h"
+#if MAJOR_VERSION == 6
+#include "6.0/Generators.h"
+#endif
#elif MAJOR_VERSION >= 7
+#include "7.0/Generators.h"
#include "7.0/PolicyConfig.h"
#endif
@@ -175,9 +180,6 @@
//////////////////// Test parameter types and definitions ////////////////////
//////////////////////////////////////////////////////////////////////////////
-enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
-using DeviceParameter = std::tuple<std::string, std::string>;
-
static inline std::string DeviceParameterToString(
const ::testing::TestParamInfo<DeviceParameter>& info) {
const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
@@ -509,24 +511,6 @@
// list is empty, this isn't a problem.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPatchHidlTest);
-// Nesting a tuple in another tuple allows to use GTest Combine function to generate
-// all combinations of devices and configs.
-enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
-#if MAJOR_VERSION <= 6
-enum { INDEX_INPUT, INDEX_OUTPUT };
-using DeviceConfigParameter =
- std::tuple<DeviceParameter, AudioConfig, std::variant<AudioInputFlag, AudioOutputFlag>>;
-#elif MAJOR_VERSION >= 7
-using DeviceConfigParameter = std::tuple<DeviceParameter, AudioConfig, std::vector<AudioInOutFlag>>;
-#endif
-
-#if MAJOR_VERSION >= 6
-const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
-const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
-const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
-const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
-#endif
-
#if MAJOR_VERSION >= 4
static std::string SanitizeStringForGTestName(const std::string& s) {
std::string result = s;
diff --git a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
new file mode 100644
index 0000000..5b14a21
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
@@ -0,0 +1,45 @@
+/*
+ * 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 <string>
+#include <tuple>
+#include <variant>
+#include <vector>
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
+using DeviceParameter = std::tuple<std::string, std::string>;
+
+// Nesting a tuple in another tuple allows to use GTest Combine function to generate
+// all combinations of devices and configs.
+enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
+#if MAJOR_VERSION <= 6
+enum { INDEX_INPUT, INDEX_OUTPUT };
+using DeviceConfigParameter =
+ std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
+ std::variant<android::hardware::audio::common::CPP_VERSION::AudioInputFlag,
+ android::hardware::audio::common::CPP_VERSION::AudioOutputFlag>>;
+#elif MAJOR_VERSION >= 7
+using DeviceConfigParameter =
+ std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
+ std::vector<android::hardware::audio::CPP_VERSION::AudioInOutFlag>>;
+#endif
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index 1a1dbea..a2bb1ee 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -16,10 +16,21 @@
#pragma once
-// Code in this file uses 'getCachedPolicyConfig'
-#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
-#error Must be included from AudioPrimaryHidlTest.h
-#endif
+#include <common/all-versions/VersionUtils.h>
+
+#include "PolicyConfig.h"
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+using ::android::hardware::audio::common::utils::EnumBitfield;
+using ::android::hardware::audio::common::utils::mkEnumBitfield;
+
+// Forward declaration for functions that are substituted
+// in generator unit tests.
+const PolicyConfig& getCachedPolicyConfig();
//////////////////////////////////////////////////////////////////////////////
//////////////// Required and recommended audio format support ///////////////
@@ -35,7 +46,7 @@
// FIXME: in the next audio HAL version, test all available devices
static bool primaryHasMic() {
auto& policyConfig = getCachedPolicyConfig();
- if (policyConfig.getStatus() != OK || policyConfig.getPrimaryModule() == nullptr) {
+ if (policyConfig.getStatus() != android::OK || policyConfig.getPrimaryModule() == nullptr) {
return true; // Could not get the information, run all tests
}
auto getMic = [](auto& devs) {
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index 6efed79..6db78a7 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -16,9 +16,27 @@
#pragma once
-// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
-// and thus it doesn't have all '#include' and 'using' directives required
-// for a standalone compilation.
+#include <unistd.h>
+
+#include <map>
+
+#include <android-base/logging.h>
+#include <hwbinder/IPCThreadState.h>
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+#include "utility/ReturnIn.h"
+
+using ::android::sp;
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::test::utility;
+using namespace ::android::hardware::audio::CPP_VERSION;
template <class Derived, class Key, class Interface>
class InterfaceManager {
@@ -56,7 +74,7 @@
// the remote device has the time to be destroyed.
// flushCommand makes sure all local command are sent, thus should reduce
// the latency between local and remote destruction.
- IPCThreadState::self()->flushCommands();
+ ::android::hardware::IPCThreadState::self()->flushCommands();
usleep(100 * 1000);
}
diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h
index c9e0c0d..a94041c 100644
--- a/audio/core/all-versions/vts/functional/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/PolicyConfig.h
@@ -16,11 +16,19 @@
#pragma once
-// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
-// and thus it doesn't have all '#include' and 'using' directives required
-// for a standalone compilation.
+#include <set>
+#include <string>
+#include <DeviceDescriptor.h>
+#include <HwModule.h>
#include <Serializer.h>
+#include <gtest/gtest.h>
+#include <system/audio_config.h>
+
+#include "DeviceManager.h"
+
+using ::android::sp;
+using ::android::status_t;
struct PolicyConfigData {
android::HwModuleCollection hwModules;
@@ -42,28 +50,14 @@
break;
}
}
- mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
- if (mStatus == OK) {
- mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
- // Available devices are not 'attached' to modules at this moment.
- // Need to go over available devices and find their module.
- for (const auto& device : availableOutputDevices) {
- for (const auto& module : hwModules) {
- if (module->getDeclaredDevices().indexOf(device) >= 0) {
- mModulesWithDevicesNames.insert(module->getName());
- break;
- }
- }
- }
- for (const auto& device : availableInputDevices) {
- for (const auto& module : hwModules) {
- if (module->getDeclaredDevices().indexOf(device) >= 0) {
- mModulesWithDevicesNames.insert(module->getName());
- break;
- }
- }
- }
- }
+ init();
+ }
+ PolicyConfig(const std::string& configPath, const std::string& configFileName)
+ : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
+ defaultOutputDevice),
+ mConfigFileName{configFileName},
+ mFilePath{configPath + "/" + mConfigFileName} {
+ init();
}
status_t getStatus() const { return mStatus; }
std::string getError() const {
@@ -88,8 +82,33 @@
}
private:
+ void init() {
+ mStatus = android::deserializeAudioPolicyFileForVts(mFilePath.c_str(), this);
+ if (mStatus == android::OK) {
+ mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
+ // Available devices are not 'attached' to modules at this moment.
+ // Need to go over available devices and find their module.
+ for (const auto& device : availableOutputDevices) {
+ for (const auto& module : hwModules) {
+ if (module->getDeclaredDevices().indexOf(device) >= 0) {
+ mModulesWithDevicesNames.insert(module->getName());
+ break;
+ }
+ }
+ }
+ for (const auto& device : availableInputDevices) {
+ for (const auto& module : hwModules) {
+ if (module->getDeclaredDevices().indexOf(device) >= 0) {
+ mModulesWithDevicesNames.insert(module->getName());
+ break;
+ }
+ }
+ }
+ }
+ }
+
const std::string mConfigFileName;
- status_t mStatus = NO_INIT;
+ status_t mStatus = android::NO_INIT;
std::string mFilePath;
sp<const android::HwModule> mPrimaryModule = nullptr;
std::set<std::string> mModulesWithDevicesNames;
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
new file mode 100644
index 0000000..0c85a05
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
@@ -0,0 +1,34 @@
+<?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 HalAudioV6_0GeneratorTest.">
+ <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="apm_config_no_vx.xml->/data/local/tmp/apm_config_no_vx.xml" />
+ <option name="push" value="apm_config_with_vx.xml->/data/local/tmp/apm_config_with_vx.xml" />
+ <option name="push" value="HalAudioV6_0GeneratorTest->/data/local/tmp/HalAudioV6_0GeneratorTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="HalAudioV6_0GeneratorTest" />
+ </test>
+</configuration>
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
new file mode 100644
index 0000000..2e79455
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
@@ -0,0 +1,34 @@
+<?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 HalAudioV7_0GeneratorTest.">
+ <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="apm_config_no_vx_7_0.xml->/data/local/tmp/apm_config_no_vx.xml" />
+ <option name="push" value="apm_config_with_vx_7_0.xml->/data/local/tmp/apm_config_with_vx.xml" />
+ <option name="push" value="HalAudioV7_0GeneratorTest->/data/local/tmp/HalAudioV7_0GeneratorTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="HalAudioV7_0GeneratorTest" />
+ </test>
+</configuration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_no_vx.xml b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx.xml
new file mode 100644
index 0000000..61972b2
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <globalConfiguration speaker_drc_enabled="true"/>
+ <modules>
+ <module name="primary" halVersion="3.0">
+ <attachedDevices>
+ <item>Speaker</item>
+ <item>Built-In Mic</item>
+ </attachedDevices>
+ <defaultOutputDevice>Speaker</defaultOutputDevice>
+ <mixPorts>
+ <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="primary input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ <gains>
+ <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+ minValueMB="-8400"
+ maxValueMB="4000"
+ defaultValueMB="0"
+ stepValueMB="100"/>
+ </gains>
+ </devicePort>
+ <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="Speaker" sources="primary output"/>
+ <route type="mix" sink="primary input" sources="Built-In Mic"/>
+ </routes>
+ </module>
+ </modules>
+ <volumes/>
+ <surroundSound>
+ <formats>
+ <format name="AUDIO_FORMAT_AC3" />
+ <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+ </formats>
+ </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_no_vx_7_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx_7_0.xml
new file mode 100644
index 0000000..abcdb12
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx_7_0.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <globalConfiguration speaker_drc_enabled="true"/>
+ <modules>
+ <module name="primary" halVersion="3.0">
+ <attachedDevices>
+ <item>Speaker</item>
+ <item>Built-In Mic</item>
+ </attachedDevices>
+ <defaultOutputDevice>Speaker</defaultOutputDevice>
+ <mixPorts>
+ <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="primary input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ <gains>
+ <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+ minValueMB="-8400"
+ maxValueMB="4000"
+ defaultValueMB="0"
+ stepValueMB="100"/>
+ </gains>
+ </devicePort>
+ <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="Speaker" sources="primary output"/>
+ <route type="mix" sink="primary input" sources="Built-In Mic"/>
+ </routes>
+ </module>
+ </modules>
+ <volumes/>
+ <surroundSound>
+ <formats>
+ <format name="AUDIO_FORMAT_AC3" />
+ <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+ </formats>
+ </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_with_vx.xml b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx.xml
new file mode 100644
index 0000000..aabb52e
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <globalConfiguration speaker_drc_enabled="true"/>
+ <modules>
+ <module name="primary" halVersion="3.0">
+ <attachedDevices>
+ <item>Speaker</item>
+ <item>Built-In Mic</item>
+ </attachedDevices>
+ <defaultOutputDevice>Speaker</defaultOutputDevice>
+ <mixPorts>
+ <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="primary input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ <profile name="" format="VX_GOOGLE_B_FORMAT"
+ samplingRates="192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ <gains>
+ <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+ minValueMB="-8400"
+ maxValueMB="4000"
+ defaultValueMB="0"
+ stepValueMB="100"/>
+ </gains>
+ </devicePort>
+ <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ <profile name="" format="VX_GOOGLE_B_FORMAT"
+ samplingRates="192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="Ambient Mic" type="VX_GOOGLE_AUDIO_DEVICE_AMBIENT_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="Speaker" sources="primary output"/>
+ <route type="mix" sink="primary input" sources="Built-In Mic,Ambient Mic"/>
+ </routes>
+ </module>
+ </modules>
+ <volumes/>
+ <surroundSound>
+ <formats>
+ <format name="AUDIO_FORMAT_AC3" />
+ <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+ <format name="VX_GOOGLE_B_FORMAT" />
+ <format name="AUDIO_FORMAT_AC4" subformats="VX_GOOGLE_B_FORMAT" />
+ </formats>
+ </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_with_vx_7_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx_7_0.xml
new file mode 100644
index 0000000..8dd5f45
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx_7_0.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <globalConfiguration speaker_drc_enabled="true"/>
+ <modules>
+ <module name="primary" halVersion="3.0">
+ <attachedDevices>
+ <item>Speaker</item>
+ <item>Built-In Mic</item>
+ </attachedDevices>
+ <defaultOutputDevice>Speaker</defaultOutputDevice>
+ <mixPorts>
+ <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+ <mixPort name="primary input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ <profile name="" format="VX_GOOGLE_B_FORMAT"
+ samplingRates="192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ <gains>
+ <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+ minValueMB="-8400"
+ maxValueMB="4000"
+ defaultValueMB="0"
+ stepValueMB="100"/>
+ </gains>
+ </devicePort>
+ <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ <profile name="" format="VX_GOOGLE_B_FORMAT"
+ samplingRates="192000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ <devicePort tagName="Ambient Mic" type="VX_GOOGLE_AUDIO_DEVICE_AMBIENT_MIC" role="source">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+ channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="Speaker" sources="primary output"/>
+ <route type="mix" sink="primary input" sources="Built-In Mic,Ambient Mic"/>
+ </routes>
+ </module>
+ </modules>
+ <volumes/>
+ <surroundSound>
+ <formats>
+ <format name="AUDIO_FORMAT_AC3" />
+ <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+ <format name="VX_GOOGLE_B_FORMAT" />
+ <format name="AUDIO_FORMAT_AC4" subformats="VX_GOOGLE_B_FORMAT" />
+ </formats>
+ </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
new file mode 100644
index 0000000..583ff01
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
@@ -0,0 +1,132 @@
+/*
+ * 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 <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/macros.h>
+#include <gtest/gtest.h>
+#define LOG_TAG "Generators_Test"
+#include <log/log.h>
+
+#if MAJOR_VERSION == 6
+#include <system/audio.h>
+#include "6.0/Generators.h"
+#include "PolicyConfig.h"
+#elif MAJOR_VERSION == 7
+#include "7.0/Generators.h"
+#include "7.0/PolicyConfig.h"
+#endif
+
+using namespace android;
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+#if MAJOR_VERSION == 7
+namespace xsd {
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
+}
+#endif
+
+// Stringify the argument.
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+
+struct PolicyConfigManager {
+ static PolicyConfigManager& getInstance() {
+ static PolicyConfigManager instance;
+ return instance;
+ }
+ bool init(const std::string& filePath, const std::string& fileName) {
+ mConfig = std::make_unique<PolicyConfig>(filePath, fileName);
+ mDeviceParameters.clear();
+ if (mConfig->getStatus() == OK) {
+ const auto devices = mConfig->getModulesWithDevicesNames();
+ mDeviceParameters.reserve(devices.size());
+ for (const auto& deviceName : devices) {
+ mDeviceParameters.emplace_back(
+ "android.hardware.audio.IDevicesFactory@" STRINGIFY(FILE_VERSION),
+ deviceName);
+ }
+ return true;
+ } else {
+ ALOGE("%s", mConfig->getError().c_str());
+ return false;
+ }
+ }
+ const PolicyConfig& getConfig() { return *mConfig; }
+ const std::vector<DeviceParameter>& getDeviceParameters() { return mDeviceParameters; }
+
+ private:
+ std::unique_ptr<PolicyConfig> mConfig;
+ std::vector<DeviceParameter> mDeviceParameters;
+};
+
+// Test implementations
+const PolicyConfig& getCachedPolicyConfig() {
+ return PolicyConfigManager::getInstance().getConfig();
+}
+
+const std::vector<DeviceParameter>& getDeviceParameters() {
+ return PolicyConfigManager::getInstance().getDeviceParameters();
+}
+
+static const std::string kDataDir = "/data/local/tmp";
+
+class GeneratorsTest : public ::testing::TestWithParam<std::string> {
+ public:
+ static void validateConfig(const AudioConfig& config) {
+#if MAJOR_VERSION == 6
+ ASSERT_TRUE(audio_is_valid_format(static_cast<audio_format_t>(config.format)))
+ << "Audio format is invalid " << ::testing::PrintToString(config.format);
+ ASSERT_TRUE(
+ audio_channel_mask_is_valid(static_cast<audio_channel_mask_t>(config.channelMask)))
+ << "Audio channel mask is invalid " << ::testing::PrintToString(config.channelMask);
+#elif MAJOR_VERSION == 7
+ ASSERT_FALSE(xsd::isUnknownAudioFormat(config.base.format))
+ << "Audio format is invalid " << ::testing::PrintToString(config.base.format);
+ ASSERT_FALSE(xsd::isUnknownAudioChannelMask(config.base.channelMask))
+ << "Audio channel mask is invalid "
+ << ::testing::PrintToString(config.base.channelMask);
+#endif
+ }
+ static void validateDeviceConfigs(const std::vector<DeviceConfigParameter>& params) {
+ for (const auto& param : params) {
+ ASSERT_NO_FATAL_FAILURE(validateConfig(std::get<PARAM_CONFIG>(param)));
+ }
+ }
+};
+
+TEST_P(GeneratorsTest, ValidateConfigs) {
+ ASSERT_TRUE(PolicyConfigManager::getInstance().init(kDataDir, GetParam()));
+ EXPECT_NE(nullptr, getCachedPolicyConfig().getPrimaryModule());
+ EXPECT_FALSE(getCachedPolicyConfig().getModulesWithDevicesNames().empty());
+ const auto allOutConfigs = generateOutputDeviceConfigParameters(false /*oneProfilePerDevice*/);
+ EXPECT_FALSE(allOutConfigs.empty());
+ EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(allOutConfigs));
+ const auto singleOutConfig = generateOutputDeviceConfigParameters(true /*oneProfilePerDevice*/);
+ EXPECT_FALSE(singleOutConfig.empty());
+ EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(singleOutConfig));
+ const auto allInConfigs = generateInputDeviceConfigParameters(false /*oneProfilePerDevice*/);
+ EXPECT_FALSE(allInConfigs.empty());
+ EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(allInConfigs));
+ const auto singleInConfig = generateInputDeviceConfigParameters(true /*oneProfilePerDevice*/);
+ EXPECT_FALSE(singleInConfig.empty());
+ EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(singleInConfig));
+}
+
+// Target file names are the same for all versions, see 'HalAudioVx_0GeneratorTest.xml' test configs
+INSTANTIATE_TEST_SUITE_P(Generators, GeneratorsTest,
+ ::testing::Values("apm_config_no_vx.xml", "apm_config_with_vx.xml"));
diff --git a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
index 687c70c..c09b265 100644
--- a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
+++ b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
@@ -34,11 +34,19 @@
authsecret = IAuthSecret::getService(GetParam());
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->primaryUserCredential(CORRECT_SECRET);
}
+ static void TearDownTestSuite() {
+ // clean up PIN code after testing
+ (void)system("cmd lock_settings clear --old 1234");
+ }
+
sp<IAuthSecret> authsecret;
hidl_vec<uint8_t> CORRECT_SECRET{61, 93, 124, 240, 5, 0, 7, 201, 9, 129, 11, 12, 0, 14, 0, 16};
hidl_vec<uint8_t> WRONG_SECRET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp
index 3cae4f1..7180a70 100644
--- a/automotive/audiocontrol/1.0/default/Android.bp
+++ b/automotive/audiocontrol/1.0/default/Android.bp
@@ -28,7 +28,7 @@
relative_install_path: "hw",
srcs: [
"AudioControl.cpp",
- "service.cpp"
+ "service.cpp",
],
init_rc: ["android.hardware.automotive.audiocontrol@1.0-service.rc"],
@@ -40,3 +40,16 @@
],
vintf_fragments: ["audiocontrol_manifest.xml"],
}
+
+filegroup {
+ name: "audiocontrolV1.0_source",
+ srcs: [
+ "AudioControl.cpp",
+ ],
+}
+
+cc_library_headers {
+ name: "audiocontrolV1.0_header",
+ host_supported: true,
+ export_include_dirs: ["."],
+}
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
new file mode 100644
index 0000000..78f5b52
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_fuzz {
+ name: "audiocontrolV1.0_fuzzer",
+ host_supported: true,
+ srcs: [
+ "audiocontrolV1.0_fuzzer.cpp",
+ ":audiocontrolV1.0_source",
+ ],
+ header_libs: [
+ "audiocontrolV1.0_header",
+ ],
+ shared_libs: [
+ "android.hardware.automotive.audiocontrol@1.0",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 533764,
+ },
+}
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/audiocontrolV1.0_fuzzer.cpp b/automotive/audiocontrol/1.0/default/test/fuzzer/audiocontrolV1.0_fuzzer.cpp
new file mode 100644
index 0000000..268df08
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/audiocontrolV1.0_fuzzer.cpp
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <AudioControl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using ::android::sp;
+using ::android::hardware::automotive::audiocontrol::V1_0::ContextNumber;
+using ::android::hardware::automotive::audiocontrol::V1_0::implementation::AudioControl;
+
+namespace android::hardware::automotive::audiocontrol::V1_0::implementation::fuzzer {
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size < 1) {
+ return 0;
+ }
+ if (sp<AudioControl> audioControl = new AudioControl(); audioControl != nullptr) {
+ FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+ ContextNumber contextNumber = static_cast<ContextNumber>(fdp.ConsumeIntegral<uint32_t>());
+ audioControl->getBusForContext(contextNumber);
+ audioControl->setBalanceTowardRight(fdp.ConsumeFloatingPoint<float>());
+ audioControl->setFadeTowardFront(fdp.ConsumeFloatingPoint<float>());
+ }
+ return 0;
+}
+} // namespace android::hardware::automotive::audiocontrol::V1_0::implementation::fuzzer
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index 8b68fd6..f1c8f9f 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -72,6 +72,8 @@
using ::android::hardware::automotive::evs::V1_0::DisplayDesc;
using ::android::hardware::automotive::evs::V1_0::DisplayState;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::frameworks::automotive::display::V1_0::HwDisplayConfig;
+using ::android::frameworks::automotive::display::V1_0::HwDisplayState;
using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera;
using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera;
using IEvsDisplay_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
@@ -303,11 +305,22 @@
const auto id = 0xFFFFFFFF; // meaningless id
hidl_vec<uint8_t> values;
auto err = pCam->setExtendedInfo_1_1(id, values);
- ASSERT_NE(EvsResult::INVALID_ARG, err);
+ if (isLogicalCam) {
+ // Logical camera device does not support setExtendedInfo
+ // method.
+ ASSERT_EQ(EvsResult::INVALID_ARG, err);
+ } else {
+ ASSERT_NE(EvsResult::INVALID_ARG, err);
+ }
- pCam->getExtendedInfo_1_1(id, [](const auto& result, const auto& data) {
- ASSERT_NE(EvsResult::INVALID_ARG, result);
- ASSERT_EQ(0, data.size());
+
+ pCam->getExtendedInfo_1_1(id, [&isLogicalCam](const auto& result, const auto& data) {
+ if (isLogicalCam) {
+ ASSERT_EQ(EvsResult::INVALID_ARG, result);
+ } else {
+ ASSERT_NE(EvsResult::INVALID_ARG, result);
+ ASSERT_EQ(0, data.size());
+ }
});
// Explicitly close the camera so resources are released right away
@@ -605,7 +618,10 @@
LOG(INFO) << "Display " << targetDisplayId << " is alreay in use.";
// Get the display descriptor
- pDisplay->getDisplayInfo_1_1([](const auto& config, const auto& state) {
+ pDisplay->getDisplayInfo_1_1([](const HwDisplayConfig& config, const HwDisplayState& state) {
+ ASSERT_GT(config.size(), 0);
+ ASSERT_GT(state.size(), 0);
+
android::DisplayConfig* pConfig = (android::DisplayConfig*)config.data();
const auto width = pConfig->resolution.getWidth();
const auto height = pConfig->resolution.getHeight();
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index d092f7a..f24b1f5 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -146,7 +146,6 @@
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["impl"],
srcs: [
- "impl/vhal_v2_0/EmulatedUserHal.cpp",
"impl/vhal_v2_0/GeneratorHub.cpp",
"impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
"impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
@@ -222,3 +221,29 @@
"android.hardware.automotive.vehicle@2.0-libproto-native",
],
}
+
+cc_fuzz {
+ name: "vehicleManager_fuzzer",
+ vendor: true,
+ defaults: ["vhal_v2_0_target_defaults"],
+ whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
+ srcs: [
+ "tests/fuzzer/VehicleManager_fuzzer.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libbinder_ndk",
+ ],
+ header_libs: ["libbase_headers"],
+ local_include_dirs: [
+ "common/include",
+ "tests",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 533764,
+ },
+}
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index 47133fd..ef29560 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -34,7 +34,7 @@
int main(int /* argc */, char* /* argv */ []) {
auto store = std::make_unique<VehiclePropertyStore>();
- auto connector = impl::makeEmulatedPassthroughConnector();
+ auto connector = std::make_unique<impl::EmulatedVehicleConnector>();
auto userHal = connector->getEmulatedUserHal();
auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal);
auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index cf18404..dec2d8c 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -417,7 +417,7 @@
.minSampleRate = 1.0f,
.maxSampleRate = 2.0f,
},
- .initialValue = {.floatValues = {100.0f}}}, // units in meters
+ .initialValue = {.floatValues = {50000.0f}}}, // units in meters
{.config =
{
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
index 7f9362f..ed3f4a2 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
@@ -35,13 +35,33 @@
namespace impl {
-class EmulatedPassthroughConnector : public PassthroughConnector {
- public:
- bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
-};
+EmulatedUserHal* EmulatedVehicleConnector::getEmulatedUserHal() {
+ return &mEmulatedUserHal;
+}
-bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle,
- const hidl_vec<hidl_string>& options) {
+StatusCode EmulatedVehicleConnector::onSetProperty(const VehiclePropValue& value,
+ bool updateStatus) {
+ if (mEmulatedUserHal.isSupported(value.prop)) {
+ LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
+
+ const auto& ret = mEmulatedUserHal.onSetProperty(value);
+ if (!ret.ok()) {
+ LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
+ return StatusCode(ret.error().code());
+ }
+ auto updatedValue = ret.value().get();
+ if (updatedValue != nullptr) {
+ LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
+ << toString(*updatedValue);
+ onPropertyValueFromCar(*updatedValue, updateStatus);
+ }
+ return StatusCode::OK;
+ }
+ return this->VehicleHalServer::onSetProperty(value, updateStatus);
+}
+
+bool EmulatedVehicleConnector::onDump(const hidl_handle& handle,
+ const hidl_vec<hidl_string>& options) {
int fd = handle->data[0];
if (options.size() > 0) {
@@ -68,10 +88,6 @@
return true;
}
-PassthroughConnectorPtr makeEmulatedPassthroughConnector() {
- return std::make_unique<EmulatedPassthroughConnector>();
-}
-
} // namespace impl
} // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
index 57cbb8b..4c6c661 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
@@ -19,6 +19,7 @@
#include <vhal_v2_0/VehicleConnector.h>
+#include "EmulatedUserHal.h"
#include "VehicleHalClient.h"
#include "VehicleHalServer.h"
@@ -30,10 +31,20 @@
namespace impl {
-using PassthroughConnector = IPassThroughConnector<VehicleHalClient, VehicleHalServer>;
-using PassthroughConnectorPtr = std::unique_ptr<PassthroughConnector>;
+class EmulatedVehicleConnector : public IPassThroughConnector<VehicleHalClient, VehicleHalServer> {
+ public:
+ EmulatedVehicleConnector() {}
-PassthroughConnectorPtr makeEmulatedPassthroughConnector();
+ EmulatedUserHal* getEmulatedUserHal();
+
+ // Methods from VehicleHalServer
+ StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
+
+ bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+
+ private:
+ EmulatedUserHal mEmulatedUserHal;
+};
} // namespace impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
index 890eb33..b62918f 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
@@ -96,11 +96,12 @@
std::vector<VehiclePropValue> JsonFakeValueGenerator::parseFakeValueJson(std::istream& is) {
std::vector<VehiclePropValue> fakeVhalEvents;
- Json::Reader reader;
+ Json::CharReaderBuilder builder;
Json::Value rawEvents;
- if (!reader.parse(is, rawEvents)) {
+ std::string errorMessage;
+ if (!Json::parseFromStream(builder, is, &rawEvents, &errorMessage)) {
ALOGE("%s: Failed to parse fake data JSON file. Error: %s", __func__,
- reader.getFormattedErrorMessages().c_str());
+ errorMessage.c_str());
return fakeVhalEvents;
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
index 36f2534..0ee1835 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
@@ -41,10 +41,6 @@
return mValuePool;
}
-EmulatedUserHal* VehicleHalServer::getEmulatedUserHal() {
- return &mEmulatedUserHal;
-}
-
void VehicleHalServer::setValuePool(VehiclePropValuePool* valuePool) {
if (!valuePool) {
LOG(WARNING) << __func__ << ": Setting value pool to nullptr!";
@@ -185,22 +181,6 @@
}
StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) {
- if (mEmulatedUserHal.isSupported(value.prop)) {
- LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
-
- const auto& ret = mEmulatedUserHal.onSetProperty(value);
- if (!ret.ok()) {
- LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
- return StatusCode(ret.error().code());
- }
- auto updatedValue = ret.value().get();
- if (updatedValue != nullptr) {
- LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
- << toString(*updatedValue);
- onPropertyValueFromCar(*updatedValue, updateStatus);
- }
- return StatusCode::OK;
- }
LOG(DEBUG) << "onSetProperty(" << value.prop << ")";
// Some properties need to be treated non-trivially
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
index fca78bc..117eadb 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
@@ -19,7 +19,6 @@
#include <vhal_v2_0/VehicleObjectPool.h>
#include <vhal_v2_0/VehicleServer.h>
-#include "EmulatedUserHal.h"
#include "GeneratorHub.h"
namespace android::hardware::automotive::vehicle::V2_0::impl {
@@ -38,8 +37,6 @@
// Set the Property Value Pool used in this server
void setValuePool(VehiclePropValuePool* valuePool);
- EmulatedUserHal* getEmulatedUserHal();
-
private:
using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
@@ -56,11 +53,6 @@
VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
int32_t targetDisplay);
- // data members
-
- protected:
- EmulatedUserHal mEmulatedUserHal;
-
private:
GeneratorHub mGeneratorHub{
std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)};
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/README.md b/automotive/vehicle/2.0/default/tests/fuzzer/README.md
new file mode 100644
index 0000000..3fa0d3f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/README.md
@@ -0,0 +1,66 @@
+# Fuzzer for android.hardware.automotive.vehicle@2.0-manager-lib
+
+## Plugin Design Considerations
+The fuzzer plugin for android.hardware.automotive.vehicle@2.0-manager-lib is
+designed based on the understanding of the library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+Vehicle Manager supports the following parameters:
+1. Vehicle Property (parameter name: `vehicleProp`)
+2. Diagnostic Integer Sensor Index (parameter name: `diagnosticIntIndex`)
+3. Diagnostic Float Sensor Index (parameter name: `diagnosticFloatIndex`)
+4. Availability Message Type (parameter name: `availabilityMsgType`)
+5. Subscription Message Type (parameter name: `subscriptionMsgType`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `vehicleProp` | 0.`VehicleProperty::INVALID` 1.`VehicleProperty::HVAC_FAN_SPEED` 2.`VehicleProperty::INFO_MAKE` 3.`VehicleProperty::DISPLAY_BRIGHTNESS` 4.`VehicleProperty::INFO_FUEL_CAPACITY` 5.`VehicleProperty::HVAC_SEAT_TEMPERATURE`| Value obtained from FuzzedDataProvider |
+| `diagnosticIntIndex` | 0.`DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS` 1.`DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON` 2.`DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT` 3.`DiagnosticIntegerSensorIndex::FUEL_TYPE` | Value obtained from FuzzedDataProvider |
+| `diagnosticFloatIndex` | 0.`DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD` 1.`DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1` 2.`DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1` 3.`DiagnosticFloatSensorIndex::THROTTLE_POSITION` | Value obtained from FuzzedDataProvider |
+| `availabilityMsgType` | 0.`VmsMessageType::AVAILABILITY_CHANGE` 1.`VmsMessageType::AVAILABILITY_RESPONSE` | Value obtained from FuzzedDataProvider |
+| `subscriptionMsgType` | 0.`VmsMessageType::SUBSCRIPTIONS_CHANGE` 1.`VmsMessageType::SUBSCRIPTIONS_RESPONSE` | Value obtained from FuzzedDataProvider |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+## Build
+
+This describes steps to build vehicleManager_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) vehicleManager_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR
+```
+ $ adb shell mkdir /data/local/tmp/CORPUS_DIR
+```
+
+##### Some Additional steps needed to run the vehicleManager_fuzzer successfully on device
+
+1. Push the following libraries from /vendor/lib/ and /vendor/lib64/ folders of your workspace to the device's /vendor/lib/ and /vendor/lib64/ :
+```
+1.1 android.hardware.automotive.vehicle@2.0.so
+1.2 carwatchdog_aidl_interface-V2-ndk_platform.so
+```
+2. Now, reboot the device using command
+```
+ $ adb reboot
+```
+
+##### To run the fuzzer on device
+```
+ $ adb sync data
+ $ adb shell LD_LIBRARY_PATH=/vendor/lib64 /data/fuzz/${TARGET_ARCH}/vehicleManager_fuzzer/vendor/vehicleManager_fuzzer /data/local/tmp/CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp
new file mode 100644
index 0000000..796c08f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp
@@ -0,0 +1,433 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "VehicleManager_fuzzer.h"
+#include <utils/SystemClock.h>
+#include <vhal_v2_0/Obd2SensorStore.h>
+#include <vhal_v2_0/WatchdogClient.h>
+
+namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
+
+using ::aidl::android::automotive::watchdog::TimeoutLength;
+using ::android::elapsedRealtimeNano;
+using ::android::Looper;
+using ::android::sp;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::automotive::vehicle::V2_0::DiagnosticFloatSensorIndex;
+using ::android::hardware::automotive::vehicle::V2_0::DiagnosticIntegerSensorIndex;
+using ::android::hardware::automotive::vehicle::V2_0::kCustomComplexProperty;
+using ::android::hardware::automotive::vehicle::V2_0::kVehicleProperties;
+using ::android::hardware::automotive::vehicle::V2_0::MockedVehicleCallback;
+using ::android::hardware::automotive::vehicle::V2_0::Obd2SensorStore;
+using ::android::hardware::automotive::vehicle::V2_0::recyclable_ptr;
+using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
+using ::android::hardware::automotive::vehicle::V2_0::SubscribeFlags;
+using ::android::hardware::automotive::vehicle::V2_0::SubscribeOptions;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleAreaConfig;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleHal;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleHalManager;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleProperty;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyAccess;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyChangeMode;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStore;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyType;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValue;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
+using ::android::hardware::automotive::vehicle::V2_0::VmsMessageType;
+using ::android::hardware::automotive::vehicle::V2_0::WatchdogClient;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createAvailabilityRequest;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createBaseVmsMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createPublisherIdRequest;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createStartSessionMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createSubscriptionsRequest;
+using ::android::hardware::automotive::vehicle::V2_0::vms::getAvailableLayers;
+using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForAvailabilityState;
+using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForSubscriptionsState;
+using ::android::hardware::automotive::vehicle::V2_0::vms::hasServiceNewlyStarted;
+using ::android::hardware::automotive::vehicle::V2_0::vms::isAvailabilitySequenceNumberNewer;
+using ::android::hardware::automotive::vehicle::V2_0::vms::isSequenceNumberNewer;
+using ::android::hardware::automotive::vehicle::V2_0::vms::isValidVmsMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parseData;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parseMessageType;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parsePublisherIdResponse;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parseStartSessionMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayer;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerAndPublisher;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerOffering;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsOffers;
+
+constexpr const char kCarMake[] = "Default Car";
+constexpr VehicleProperty kVehicleProp[] = {VehicleProperty::INVALID,
+ VehicleProperty::HVAC_FAN_SPEED,
+ VehicleProperty::INFO_MAKE,
+ VehicleProperty::DISPLAY_BRIGHTNESS,
+ VehicleProperty::INFO_FUEL_CAPACITY,
+ VehicleProperty::HVAC_SEAT_TEMPERATURE};
+constexpr DiagnosticIntegerSensorIndex kDiagnosticIntIndex[] = {
+ DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
+ DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON,
+ DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT,
+ DiagnosticIntegerSensorIndex::FUEL_TYPE};
+constexpr DiagnosticFloatSensorIndex kDiagnosticFloatIndex[] = {
+ DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD,
+ DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1,
+ DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1,
+ DiagnosticFloatSensorIndex::THROTTLE_POSITION};
+constexpr size_t kVehiclePropArrayLength = std::size(kVehicleProp);
+constexpr size_t kIntSensorArrayLength = std::size(kDiagnosticIntIndex);
+constexpr size_t kFloatSensorArrayLength = std::size(kDiagnosticFloatIndex);
+constexpr VmsMessageType kAvailabilityMessageType[] = {VmsMessageType::AVAILABILITY_CHANGE,
+ VmsMessageType::AVAILABILITY_RESPONSE};
+constexpr VmsMessageType kSubscriptionMessageType[] = {VmsMessageType::SUBSCRIPTIONS_CHANGE,
+ VmsMessageType::SUBSCRIPTIONS_RESPONSE};
+
+MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
+ const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
+ VehiclePropValuePtr pValue = nullptr;
+ if (outStatus == nullptr) {
+ return pValue;
+ }
+ auto property = static_cast<VehicleProperty>(requestedPropValue.prop);
+ int32_t areaId = requestedPropValue.areaId;
+ *outStatus = StatusCode::OK;
+
+ switch (property) {
+ case VehicleProperty::INFO_MAKE:
+ pValue = getValuePool()->obtainString(kCarMake);
+ break;
+ case VehicleProperty::INFO_FUEL_CAPACITY:
+ if (mFuelCapacityAttemptsLeft-- > 0) {
+ *outStatus = StatusCode::TRY_AGAIN;
+ } else {
+ pValue = getValuePool()->obtainFloat(42.42);
+ }
+ break;
+ default:
+ if (requestedPropValue.prop == kCustomComplexProperty) {
+ pValue = getValuePool()->obtainComplex();
+ pValue->value.int32Values = hidl_vec<int32_t>{10, 20};
+ pValue->value.int64Values = hidl_vec<int64_t>{30, 40};
+ pValue->value.floatValues = hidl_vec<float_t>{1.1, 2.2};
+ pValue->value.bytes = hidl_vec<uint8_t>{1, 2, 3};
+ pValue->value.stringValue = kCarMake;
+ break;
+ }
+ auto key = makeKey(toInt(property), areaId);
+ pValue = getValuePool()->obtain(mValues[key]);
+ }
+
+ if (*outStatus == StatusCode::OK && pValue.get() != nullptr) {
+ pValue->prop = toInt(property);
+ pValue->areaId = areaId;
+ pValue->timestamp = elapsedRealtimeNano();
+ }
+
+ return pValue;
+}
+
+void VehicleHalManagerFuzzer::process(const uint8_t* data, size_t size) {
+ mFuzzedDataProvider = new FuzzedDataProvider(data, size);
+ invokeDebug();
+ invokePropConfigs();
+ invokeSubscribe();
+ invokeSetAndGetValues();
+ invokeObd2SensorStore();
+ invokeVmsUtils();
+ invokeVehiclePropStore();
+ invokeWatchDogClient();
+}
+
+void VehicleHalManagerFuzzer::invokeDebug() {
+ hidl_string debugOption = mFuzzedDataProvider->PickValueInArray(
+ {"--help", "--list", "--get", "--set", "", "invalid"});
+ hidl_handle fd = {};
+ fd.setTo(native_handle_create(/*numFds=*/1, /*numInts=*/0), /*shouldOwn=*/true);
+
+ mManager->debug(fd, {});
+ mManager->debug(fd, {debugOption});
+}
+
+void VehicleHalManagerFuzzer::invokePropConfigs() {
+ int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+
+ hidl_vec<int32_t> properties = {vehicleProp1, vehicleProp2};
+
+ mManager->getPropConfigs(properties,
+ []([[maybe_unused]] StatusCode status,
+ [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
+
+ mManager->getPropConfigs({toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength])},
+ []([[maybe_unused]] StatusCode status,
+ [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
+
+ mManager->getAllPropConfigs(
+ []([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
+}
+
+void VehicleHalManagerFuzzer::invokeSubscribe() {
+ int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ int32_t vehicleProp3 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+
+ const auto prop1 = toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength]);
+ sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
+
+ hidl_vec<SubscribeOptions> options = {
+ SubscribeOptions{.propId = prop1, .flags = SubscribeFlags::EVENTS_FROM_CAR}};
+
+ mManager->subscribe(cb, options);
+
+ auto unsubscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
+ unsubscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
+
+ mHal->sendPropEvent(std::move(unsubscribedValue));
+ cb->getReceivedEvents();
+ cb->waitForExpectedEvents(0);
+
+ auto subscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
+ subscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
+ subscribedValue->value.int32Values[0] = INT32_MAX;
+
+ cb->reset();
+ VehiclePropValue actualValue(*subscribedValue.get());
+ mHal->sendPropEvent(std::move(subscribedValue));
+ cb->waitForExpectedEvents(1);
+ mManager->unsubscribe(cb, prop1);
+
+ sp<MockedVehicleCallback> cb2 = new MockedVehicleCallback();
+
+ hidl_vec<SubscribeOptions> options2 = {
+ SubscribeOptions{
+ .propId = toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
+ .flags = SubscribeFlags::EVENTS_FROM_CAR},
+ };
+
+ mManager->subscribe(cb2, options2);
+
+ mHal->sendHalError(StatusCode::TRY_AGAIN,
+ toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
+ /*areaId=*/0);
+}
+
+void VehicleHalManagerFuzzer::invokeSetAndGetValues() {
+ uint32_t vehicleProp1 =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
+ uint32_t vehicleProp2 =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
+ uint32_t vehicleProp3 =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
+
+ invokeGet(kCustomComplexProperty, 0);
+ invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
+ invokeGet(toInt(kVehicleProp[vehicleProp1]), 0);
+
+ auto expectedValue = mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+ mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>());
+ mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
+ mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool());
+ expectedValue->prop = toInt(kVehicleProp[vehicleProp2]);
+ expectedValue->areaId = 0;
+
+ mManager->set(*expectedValue.get());
+ invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
+ expectedValue->prop = toInt(kVehicleProp[vehicleProp3]);
+ mManager->set(*expectedValue.get());
+ expectedValue->prop = toInt(VehicleProperty::INVALID);
+ mManager->set(*expectedValue.get());
+}
+
+void VehicleHalManagerFuzzer::invokeObd2SensorStore() {
+ uint32_t diagnosticIntIndex =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kIntSensorArrayLength - 1);
+ int32_t diagnosticIntValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ uint32_t diagnosticFloatIndex =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kFloatSensorArrayLength - 1);
+ float diagnosticFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
+
+ std::unique_ptr<Obd2SensorStore> sensorStore(
+ new Obd2SensorStore(kIntSensorArrayLength, kFloatSensorArrayLength));
+ if (sensorStore) {
+ sensorStore->setIntegerSensor(kDiagnosticIntIndex[diagnosticIntIndex], diagnosticIntValue);
+ sensorStore->setFloatSensor(kDiagnosticFloatIndex[diagnosticFloatIndex],
+ diagnosticFloatValue);
+ sensorStore->getIntegerSensors();
+ sensorStore->getFloatSensors();
+ sensorStore->getSensorsBitmask();
+ static std::vector<std::string> sampleDtcs = {"P0070",
+ "P0102"
+ "P0123"};
+ for (auto&& dtc : sampleDtcs) {
+ auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
+ sensorStore->fillPropValue(dtc, freezeFrame.get());
+ freezeFrame->prop = static_cast<int>(VehicleProperty::OBD2_FREEZE_FRAME);
+ }
+ }
+}
+
+void VehicleHalManagerFuzzer::invokeVmsUtils() {
+ bool availabilityMsgType = mFuzzedDataProvider->ConsumeBool();
+ bool subscriptionMsgType = mFuzzedDataProvider->ConsumeBool();
+ int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+
+ VmsLayer layer(1, 0, 2);
+ auto message = createSubscribeMessage(layer);
+ isValidVmsMessage(*message);
+ message = createUnsubscribeMessage(layer);
+
+ VmsOffers offers = {intValue, {VmsLayerOffering(VmsLayer(1, 0, 2))}};
+ message = createOfferingMessage(offers);
+ std::vector<VmsLayer> dependencies = {VmsLayer(2, 0, 2), VmsLayer(3, 0, 3)};
+ std::vector<VmsLayerOffering> offering = {VmsLayerOffering(layer, dependencies)};
+ offers = {intValue, offering};
+ message = createOfferingMessage(offers);
+
+ message = createAvailabilityRequest();
+ message = createSubscriptionsRequest();
+
+ std::string bytes = "placeholder";
+ const VmsLayerAndPublisher layer_and_publisher(VmsLayer(2, 0, 1), intValue);
+ message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
+ parseData(*message);
+ createSubscribeToPublisherMessage(layer_and_publisher);
+ createUnsubscribeToPublisherMessage(layer_and_publisher);
+
+ std::string pub_bytes = "pub_id";
+ message = createPublisherIdRequest(pub_bytes);
+ message = createBaseVmsMessage(2);
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(VmsMessageType::PUBLISHER_ID_RESPONSE), intValue};
+ parsePublisherIdResponse(*message);
+
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(kSubscriptionMessageType[subscriptionMsgType]), intValue};
+ getSequenceNumberForSubscriptionsState(*message);
+
+ message->value.int32Values = hidl_vec<int32_t>{toInt(kSubscriptionMessageType[0]), intValue};
+ isSequenceNumberNewer(*message, intValue + 1);
+ invokeGetSubscribedLayers(kSubscriptionMessageType[subscriptionMsgType]);
+
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), 0};
+ hasServiceNewlyStarted(*message);
+ message = createStartSessionMessage(intValue, intValue + 1);
+ parseMessageType(*message);
+
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
+ isAvailabilitySequenceNumberNewer(*message, intValue + 1);
+
+ message->value.int32Values =
+ hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
+ getSequenceNumberForAvailabilityState(*message);
+ message = createBaseVmsMessage(3);
+ int new_service_id;
+ message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, -1};
+ parseStartSessionMessage(*message, -1, 0, &new_service_id);
+}
+
+void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
+ VehiclePropValue requestedValue{};
+ requestedValue.prop = property;
+ requestedValue.areaId = areaId;
+ mActualValue = VehiclePropValue{}; // reset previous values
+
+ StatusCode refStatus;
+ VehiclePropValue refValue;
+ mManager->get(requestedValue,
+ [&refStatus, &refValue](StatusCode status, const VehiclePropValue& value) {
+ refStatus = status;
+ refValue = value;
+ });
+
+ mActualValue = refValue;
+ mActualStatusCode = refStatus;
+}
+
+void VehicleHalManagerFuzzer::invokeGetSubscribedLayers(VmsMessageType type) {
+ VmsOffers offers = {123,
+ {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
+ VmsLayerOffering(VmsLayer(2, 0, 1))}};
+ auto message = createBaseVmsMessage(16);
+ message->value.int32Values = hidl_vec<int32_t>{toInt(type),
+ 1234, // sequence number
+ 2, // number of layers
+ 1, // number of associated layers
+ 1, // layer 1
+ 0, 1,
+ 4, // layer 2
+ 1, 1,
+ 2, // associated layer
+ 0, 1,
+ 2, // number of publisher IDs
+ 111, // publisher IDs
+ 123};
+ isValidVmsMessage(*message);
+ getSubscribedLayers(*message, offers);
+ getAvailableLayers(*message);
+}
+
+void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
+ bool shouldWriteStatus = mFuzzedDataProvider->ConsumeBool();
+ int32_t vehicleProp = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+ auto store = std::make_unique<VehiclePropertyStore>();
+ VehiclePropConfig config{
+ .prop = vehicleProp,
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::STATIC,
+ .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+ };
+ store->registerProperty(config);
+ VehiclePropValue propValue{};
+ propValue.prop = vehicleProp;
+ propValue.areaId = 0;
+ store->writeValue(propValue, shouldWriteStatus);
+ store->readAllValues();
+ store->getAllConfigs();
+ store->getConfigOrNull(vehicleProp);
+ store->readValuesForProperty(vehicleProp);
+ store->readValueOrNull(propValue);
+ store->readValueOrNull(propValue.prop, propValue.areaId, 0);
+ store->removeValuesForProperty(vehicleProp);
+ store->removeValue(propValue);
+ store->getConfigOrDie(vehicleProp);
+}
+
+void VehicleHalManagerFuzzer::invokeWatchDogClient() {
+ auto service = new VehicleHalManager(mHal.get());
+ sp<Looper> looper(Looper::prepare(/*opts=*/mFuzzedDataProvider->ConsumeBool()));
+ if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, service);
+ watchdogClient->initialize()) {
+ watchdogClient->checkIfAlive(-1, TimeoutLength::TIMEOUT_NORMAL);
+ watchdogClient->prepareProcessTermination();
+ }
+ delete service;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ VehicleHalManagerFuzzer vmFuzzer;
+ vmFuzzer.process(data, size);
+ return 0;
+}
+
+} // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h
new file mode 100644
index 0000000..e9335d3
--- /dev/null
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef __VEHICLE_MANAGER_FUZZER_H__
+#define __VEHICLE_MANAGER_FUZZER_H__
+
+#include <vhal_v2_0/VehicleHalManager.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
+#include <vhal_v2_0/VmsUtils.h>
+
+#include <VehicleHalTestUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
+
+constexpr int kRetriableAttempts = 3;
+
+class MockedVehicleHal : public VehicleHal {
+ public:
+ MockedVehicleHal()
+ : mFuelCapacityAttemptsLeft(kRetriableAttempts),
+ mMirrorFoldAttemptsLeft(kRetriableAttempts) {
+ mConfigs.assign(std::begin(kVehicleProperties), std::end(kVehicleProperties));
+ }
+
+ std::vector<VehiclePropConfig> listProperties() override { return mConfigs; }
+
+ VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
+ StatusCode* outStatus) override;
+
+ StatusCode set(const VehiclePropValue& propValue) override {
+ if (toInt(VehicleProperty::MIRROR_FOLD) == propValue.prop &&
+ mMirrorFoldAttemptsLeft-- > 0) {
+ return StatusCode::TRY_AGAIN;
+ }
+
+ mValues[makeKey(propValue)] = propValue;
+ return StatusCode::OK;
+ }
+
+ StatusCode subscribe(int32_t /* property */, float /* sampleRate */) override {
+ return StatusCode::OK;
+ }
+
+ StatusCode unsubscribe(int32_t /* property */) override { return StatusCode::OK; }
+
+ void sendPropEvent(recyclable_ptr<VehiclePropValue> value) { doHalEvent(std::move(value)); }
+
+ void sendHalError(StatusCode error, int32_t property, int32_t areaId) {
+ doHalPropertySetError(error, property, areaId);
+ }
+
+ private:
+ int64_t makeKey(const VehiclePropValue& v) const { return makeKey(v.prop, v.areaId); }
+
+ int64_t makeKey(int32_t prop, int32_t area) const {
+ return (static_cast<int64_t>(prop) << 32) | area;
+ }
+
+ private:
+ std::vector<VehiclePropConfig> mConfigs;
+ std::unordered_map<int64_t, VehiclePropValue> mValues;
+ int mFuelCapacityAttemptsLeft;
+ int mMirrorFoldAttemptsLeft;
+};
+
+class VehicleHalManagerFuzzer {
+ public:
+ VehicleHalManagerFuzzer() {
+ mHal.reset(new MockedVehicleHal);
+ mManager.reset(new VehicleHalManager(mHal.get()));
+ mObjectPool = mHal->getValuePool();
+ }
+ ~VehicleHalManagerFuzzer() {
+ mManager.reset(nullptr);
+ mHal.reset(nullptr);
+ mObjectPool = nullptr;
+ if (mFuzzedDataProvider) {
+ delete mFuzzedDataProvider;
+ }
+ }
+ void process(const uint8_t* data, size_t size);
+
+ private:
+ FuzzedDataProvider* mFuzzedDataProvider = nullptr;
+ VehiclePropValue mActualValue = VehiclePropValue{};
+ StatusCode mActualStatusCode = StatusCode::OK;
+
+ VehiclePropValuePool* mObjectPool = nullptr;
+ std::unique_ptr<MockedVehicleHal> mHal;
+ std::unique_ptr<VehicleHalManager> mManager;
+
+ void invokeDebug();
+ void invokePropConfigs();
+ void invokeSubscribe();
+ void invokeSetAndGetValues();
+ void invokeObd2SensorStore();
+ void invokeVmsUtils();
+ void invokeVehiclePropStore();
+ void invokeWatchDogClient();
+ void invokeGetSubscribedLayers(VmsMessageType type);
+ void invokeGet(int32_t property, int32_t areaId);
+};
+
+} // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
+
+#endif // __VEHICLE_MANAGER_FUZZER_H__
diff --git a/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp
index df89cc8..0e5b7e4 100644
--- a/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp
@@ -75,7 +75,7 @@
android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
if (db_codec_capabilities.size()) {
audio_capabilities.resize(db_codec_capabilities.size());
- for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+ for (std::size_t i = 0; i < db_codec_capabilities.size(); ++i) {
audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
}
}
diff --git a/bluetooth/audio/utils/OWNERS b/bluetooth/audio/utils/OWNERS
new file mode 100644
index 0000000..a35dde2
--- /dev/null
+++ b/bluetooth/audio/utils/OWNERS
@@ -0,0 +1,3 @@
+include platform/system/bt:/OWNERS
+
+cheneyni@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
index 50119bf..2f3ddaf 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
@@ -43,7 +43,10 @@
AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {};
static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending
+static constexpr int kFmqReceiveTimeoutMs =
+ 1000; // 1000 ms timeout for receiving
static constexpr int kWritePollMs = 1; // polled non-blocking interval
+static constexpr int kReadPollMs = 1; // polled non-blocking interval
static inline timespec timespec_convert_from_hal(const TimeSpec& TS) {
return {.tv_sec = static_cast<long>(TS.tvSec),
@@ -402,6 +405,39 @@
return totalWritten;
}
+// The control function reads stream from FMQ
+size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
+ if (buffer == nullptr || !bytes) return 0;
+ size_t totalRead = 0;
+ int ms_timeout = kFmqReceiveTimeoutMs;
+ do {
+ std::unique_lock<std::recursive_mutex> lock(mutex_);
+ if (!IsSessionReady()) break;
+ size_t availableToRead = mDataMQ->availableToRead();
+ if (availableToRead) {
+ if (availableToRead > (bytes - totalRead)) {
+ availableToRead = bytes - totalRead;
+ }
+ if (!mDataMQ->read(static_cast<uint8_t*>(buffer) + totalRead,
+ availableToRead)) {
+ ALOGE("FMQ datapath reading %zu/%zu failed", totalRead, bytes);
+ return totalRead;
+ }
+ totalRead += availableToRead;
+ } else if (ms_timeout >= kReadPollMs) {
+ lock.unlock();
+ usleep(kReadPollMs * 1000);
+ ms_timeout -= kReadPollMs;
+ continue;
+ } else {
+ ALOGD("in data %zu/%zu overflow %d ms", totalRead, bytes,
+ (kFmqReceiveTimeoutMs - ms_timeout));
+ return totalRead;
+ }
+ } while (totalRead < bytes);
+ return totalRead;
+}
+
std::unique_ptr<BluetoothAudioSessionInstance>
BluetoothAudioSessionInstance::instance_ptr =
std::unique_ptr<BluetoothAudioSessionInstance>(
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.h b/bluetooth/audio/utils/session/BluetoothAudioSession.h
index 838d1cc..83e20ad 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession.h
@@ -79,6 +79,8 @@
};
class BluetoothAudioSession {
+ friend class BluetoothAudioSession_2_1;
+
private:
// using recursive_mutex to allow hwbinder to re-enter agian.
std::recursive_mutex mutex_;
@@ -153,6 +155,8 @@
// The control function writes stream to FMQ
size_t OutWritePcmData(const void* buffer, size_t bytes);
+ // The control function read stream from FMQ
+ size_t InReadPcmData(void* buffer, size_t bytes);
static constexpr PcmParameters kInvalidPcmParameters = {
.sampleRate = SampleRate::RATE_UNKNOWN,
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
index 86af468..4d7be21 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
@@ -25,6 +25,8 @@
class BluetoothAudioSessionControl_2_1 {
using SessionType_2_1 =
::android::hardware::bluetooth::audio::V2_1::SessionType;
+ using AudioConfiguration_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
public:
// The control API helps to check if session is ready or not
@@ -65,18 +67,17 @@
// The control API for the bluetooth_audio module to get current
// AudioConfiguration
- static const AudioConfiguration& GetAudioConfig(
+ static const AudioConfiguration_2_1 GetAudioConfig(
const SessionType_2_1& session_type) {
std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
- // TODO: map 2.1 to 2.0 audio config inside GetAudioConfig?
- return session_ptr->GetAudioSession()->GetAudioConfig();
+ return session_ptr->GetAudioConfig();
} else if (session_type ==
SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return BluetoothAudioSession::kInvalidOffloadAudioConfiguration;
+ return BluetoothAudioSession_2_1::kInvalidOffloadAudioConfiguration;
} else {
- return BluetoothAudioSession::kInvalidSoftwareAudioConfiguration;
+ return BluetoothAudioSession_2_1::kInvalidSoftwareAudioConfiguration;
}
}
@@ -141,6 +142,17 @@
}
return 0;
}
+
+ // The control API reads stream from FMQ
+ static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer,
+ size_t bytes) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes);
+ }
+ return 0;
+ }
};
} // namespace audio
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
index 9e1baf4..9d91196 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -29,6 +29,11 @@
using SessionType_2_0 =
::android::hardware::bluetooth::audio::V2_0::SessionType;
+::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+ BluetoothAudioSession_2_1::invalidSoftwareAudioConfiguration = {};
+::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+ BluetoothAudioSession_2_1::invalidOffloadAudioConfiguration = {};
+
namespace {
bool is_2_0_session_type(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -60,6 +65,71 @@
return audio_session;
}
+// The control function is for the bluetooth_audio module to get the current
+// AudioConfiguration
+const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+BluetoothAudioSession_2_1::GetAudioConfig() {
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ if (audio_session->IsSessionReady()) {
+ // If session is unknown it means it should be 2.0 type
+ if (session_type_2_1_ != SessionType_2_1::UNKNOWN)
+ return audio_config_2_1_;
+
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration toConf;
+ const AudioConfiguration fromConf = GetAudioSession()->GetAudioConfig();
+ // pcmConfig only differs between 2.0 and 2.1 in AudioConfiguration
+ if (fromConf.getDiscriminator() ==
+ AudioConfiguration::hidl_discriminator::codecConfig) {
+ toConf.codecConfig() = fromConf.codecConfig();
+ } else {
+ toConf.pcmConfig() = {
+ .sampleRate = static_cast<
+ ::android::hardware::bluetooth::audio::V2_1::SampleRate>(
+ fromConf.pcmConfig().sampleRate),
+ .channelMode = fromConf.pcmConfig().channelMode,
+ .bitsPerSample = fromConf.pcmConfig().bitsPerSample,
+ .dataIntervalUs = 0};
+ }
+ return toConf;
+ } else if (session_type_2_1_ ==
+ SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ return kInvalidOffloadAudioConfiguration;
+ } else {
+ return kInvalidSoftwareAudioConfiguration;
+ }
+}
+
+bool BluetoothAudioSession_2_1::UpdateAudioConfig(
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ audio_config) {
+ bool is_software_session =
+ (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_2_1_ ==
+ SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_2_1_ ==
+ SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_2_1_ ==
+ SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
+ bool is_offload_session =
+ (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
+ auto audio_config_discriminator = audio_config.getDiscriminator();
+ bool is_software_audio_config =
+ (is_software_session &&
+ audio_config_discriminator ==
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
+ hidl_discriminator::pcmConfig);
+ bool is_offload_audio_config =
+ (is_offload_session &&
+ audio_config_discriminator ==
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
+ hidl_discriminator::codecConfig);
+ if (!is_software_audio_config && !is_offload_audio_config) {
+ return false;
+ }
+ audio_config_2_1_ = audio_config;
+ return true;
+}
+
// The report function is used to report that the Bluetooth stack has started
// this session without any failure, and will invoke session_changed_cb_ to
// notify those registered bluetooth_audio outputs
@@ -86,7 +156,27 @@
audio_session->OnSessionStarted(stack_iface, dataMQ, config);
} else {
- LOG(FATAL) << " Not implemented yet!!";
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ if (stack_iface == nullptr) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << ", IBluetoothAudioPort Invalid";
+ } else if (!UpdateAudioConfig(audio_config)) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << ", AudioConfiguration=" << toString(audio_config)
+ << " Invalid";
+ } else if (!audio_session->UpdateDataPath(dataMQ)) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " DataMQ Invalid";
+ audio_config_2_1_ =
+ (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH
+ ? kInvalidOffloadAudioConfiguration
+ : kInvalidSoftwareAudioConfiguration);
+ } else {
+ audio_session->stack_iface_ = stack_iface;
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << ", AudioConfiguration=" << toString(audio_config);
+ audio_session->ReportSessionStatus();
+ };
}
}
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
index 0e9c12b..5a35153 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
@@ -40,6 +40,11 @@
const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
audio_config);
+ static ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+ invalidSoftwareAudioConfiguration;
+ static ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+ invalidOffloadAudioConfiguration;
+
public:
BluetoothAudioSession_2_1(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -58,8 +63,15 @@
// The control function is for the bluetooth_audio module to get the current
// AudioConfiguration
- const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
GetAudioConfig();
+
+ static constexpr ::android::hardware::bluetooth::audio::V2_1::
+ AudioConfiguration& kInvalidSoftwareAudioConfiguration =
+ invalidSoftwareAudioConfiguration;
+ static constexpr ::android::hardware::bluetooth::audio::V2_1::
+ AudioConfiguration& kInvalidOffloadAudioConfiguration =
+ invalidOffloadAudioConfiguration;
};
class BluetoothAudioSessionInstance_2_1 {
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index ce50f25..5ba7a76 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -486,6 +486,50 @@
}
/**
+ * Test tuning with DAB selector.
+ *
+ * Verifies that:
+ * - if DAB selector is not supported, the method returns NOT_SUPPORTED;
+ * - if it is supported, the method succeeds;
+ * - after a successful tune call, onCurrentProgramInfoChanged callback is
+ * invoked carrying a proper selector;
+ * - program changes exactly to what was requested.
+ */
+TEST_F(BroadcastRadioHalTest, DabTune) {
+ ASSERT_TRUE(openSession());
+
+ ProgramSelector sel = {};
+ uint64_t freq = 178352;
+ sel.primaryId = make_identifier(IdentifierType::DAB_FREQUENCY,freq);
+
+ std::this_thread::sleep_for(gTuneWorkaround);
+
+ // try tuning
+ ProgramInfo infoCb = {};
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged_,
+ InfoHasId(utils::make_identifier(IdentifierType::DAB_FREQUENCY, freq)))
+ .Times(AnyNumber())
+ .WillOnce(DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(Void()))));
+ auto result = mSession->tune(sel);
+
+ // expect a failure if it's not supported
+ if (!utils::isSupported(mProperties, sel)) {
+ EXPECT_EQ(Result::NOT_SUPPORTED, result);
+ return;
+ }
+
+ // expect a callback if it succeeds
+ EXPECT_EQ(Result::OK, result);
+ EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChanged_, timeout::tune);
+
+ LOG(DEBUG) << "current program info: " << toString(infoCb);
+
+ // it should tune exactly to what was requested
+ auto freqs = utils::getAllIds(infoCb.selector, IdentifierType::DAB_FREQUENCY);
+ EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq));
+}
+
+/**
* Test tuning with empty program selector.
*
* Verifies that:
@@ -516,6 +560,12 @@
EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged_, _).Times(AnyNumber());
auto result = mSession->scan(true /* up */, true /* skip subchannel */);
+
+ if (result == Result::NOT_SUPPORTED) {
+ printSkipped("seek not supported");
+ return;
+ }
+
EXPECT_EQ(Result::OK, result);
EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChanged_, timeout::tune);
@@ -565,6 +615,12 @@
for (int i = 0; i < 10; i++) {
auto result = mSession->scan(true /* up */, true /* skip subchannel */);
+
+ if (result == Result::NOT_SUPPORTED) {
+ printSkipped("cancel is skipped because of seek not supported");
+ return;
+ }
+
ASSERT_EQ(Result::OK, result);
auto cancelResult = mSession->cancel();
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 127b6c0..912bfdc 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -31,6 +31,7 @@
apex_available: [
"//apex_available:platform",
"com.android.media.swcodec",
+ "com.android.neuralnetworks",
],
min_sdk_version: "29",
},
diff --git a/compatibility_matrices/build/vintf_compatibility_matrix.go b/compatibility_matrices/build/vintf_compatibility_matrix.go
index 2772ba3..f1bd0ae 100644
--- a/compatibility_matrices/build/vintf_compatibility_matrix.go
+++ b/compatibility_matrices/build/vintf_compatibility_matrix.go
@@ -41,7 +41,7 @@
}, "inputs")
xmllintXsd = pctx.AndroidStaticRule("xmllint-xsd", blueprint.RuleParams{
- Command: `$XmlLintCmd --schema $xsd $in > /dev/null && touch -a $out`,
+ Command: `$XmlLintCmd --quiet --schema $xsd $in > /dev/null && touch -a $out`,
CommandDeps: []string{"$XmlLintCmd"},
Restat: true,
}, "xsd")
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 96a3692..8e175f0 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -256,6 +256,13 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.identity</name>
+ <!--
+ b/178458001: identity V2 is introduced in R, but Android R VINTF does not support AIDL
+ versions. Hence, we only specify identity V2 in compatibility_matrix.5.xml in Android S+
+ branches. In Android R branches, the matrix implicitly specifies V1.
+ SingleManifestTest.ManifestAidlHalsServed has an exemption for this.
+ -->
+ <version>1-2</version>
<interface>
<name>IIdentityCredentialStore</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 6631d8a..30af25f 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -368,14 +368,6 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.memtrack</name>
- <version>1.0</version>
- <interface>
- <name>IMemtrack</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
<name>android.hardware.neuralnetworks</name>
<version>1.0-3</version>
<interface>
diff --git a/current.txt b/current.txt
index 29a837f..c90c7dd 100644
--- a/current.txt
+++ b/current.txt
@@ -776,7 +776,7 @@
dabe23dde7c9e3ad65c61def7392f186d7efe7f4216f9b6f9cf0863745b1a9f4 android.hardware.keymaster@4.1::IKeymasterDevice
cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice
f729ee6a5f136b25d79ea6895d24700fce413df555baaecf2c39e4440d15d043 android.hardware.neuralnetworks@1.0::types
-c6ae443608502339aec4256feef48e7b2d36f7477ca5361cc95cd27a8ed9c612 android.hardware.neuralnetworks@1.2::types
+ba84f3a750b1cc43ac51074e8b8e22df924f3e6d9068fac50d95bcf57b2b1d61 android.hardware.neuralnetworks@1.2::types
9fe5a4093043c2b5da4e9491aed1646c388a5d3059b8fd77d5b6a9807e6d3a3e android.hardware.neuralnetworks@1.3::types
e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback
b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardware.renderscript@1.0::types
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index 9477997..c8ee0dd 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -253,14 +253,17 @@
}
}
- // Feed the auth token to secure hardware.
- if (!hwProxy_->setAuthToken(authToken.challenge, authToken.userId, authToken.authenticatorId,
- int(authToken.authenticatorType), authToken.timestamp.milliSeconds,
- authToken.mac, verificationToken_.challenge,
- verificationToken_.timestamp.milliSeconds,
- int(verificationToken_.securityLevel), verificationToken_.mac)) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_INVALID_DATA, "Invalid Auth Token"));
+ // Feed the auth token to secure hardware only if they're valid.
+ if (authToken.timestamp.milliSeconds != 0) {
+ if (!hwProxy_->setAuthToken(
+ authToken.challenge, authToken.userId, authToken.authenticatorId,
+ int(authToken.authenticatorType), authToken.timestamp.milliSeconds,
+ authToken.mac, verificationToken_.challenge,
+ verificationToken_.timestamp.milliSeconds,
+ int(verificationToken_.securityLevel), verificationToken_.mac)) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+ IIdentityCredentialStore::STATUS_INVALID_DATA, "Invalid Auth Token"));
+ }
}
// We'll be feeding ACPs interleaved with certificates from the reader
diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c
index 5e9a280..9e033b3 100644
--- a/identity/aidl/default/libeic/EicPresentation.c
+++ b/identity/aidl/default/libeic/EicPresentation.c
@@ -336,6 +336,18 @@
int verificationTokenSecurityLevel,
const uint8_t* verificationTokenMac,
size_t verificationTokenMacSize) {
+ // It doesn't make sense to accept any tokens if eicPresentationCreateAuthChallenge()
+ // was never called.
+ if (ctx->authChallenge == 0) {
+ eicDebug("Trying validate tokens when no auth-challenge was previously generated");
+ return false;
+ }
+ // At least the verification-token must have the same challenge as what was generated.
+ if (verificationTokenChallenge != ctx->authChallenge) {
+ eicDebug("Challenge in verification token does not match the challenge "
+ "previously generated");
+ return false;
+ }
if (!eicOpsValidateAuthToken(
challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac,
macSize, verificationTokenChallenge, verificationTokenTimestamp,
@@ -360,18 +372,9 @@
return false;
}
+ // Only ACP with auth-on-every-presentation - those with timeout == 0 - need the
+ // challenge to match...
if (timeoutMillis == 0) {
- if (ctx->authTokenChallenge == 0) {
- eicDebug("No challenge in authToken");
- return false;
- }
-
- // If we didn't create a challenge, too bad but user auth with
- // timeoutMillis set to 0 needs it.
- if (ctx->authChallenge == 0) {
- eicDebug("No challenge was created for this session");
- return false;
- }
if (ctx->authTokenChallenge != ctx->authChallenge) {
eicDebug("Challenge in authToken (%" PRIu64
") doesn't match the challenge "
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 6418028..aba89c1 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -928,7 +928,7 @@
// translate certificate format from keymaster_cert_chain_t to vector<vector<uint8_t>>.
vector<vector<uint8_t>> attestationCertificate;
- for (int i = 0; i < cert_chain_out.entry_count; i++) {
+ for (std::size_t i = 0; i < cert_chain_out.entry_count; i++) {
attestationCertificate.insert(
attestationCertificate.end(),
vector<uint8_t>(
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index b32298e..e0d60fc 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -2567,7 +2567,8 @@
string message = "Hello World!";
auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
string ciphertext1 = EncryptMessage(message, params);
- EXPECT_EQ(2048U / 8, ciphertext1.size());
+ // Die here on failure because we try to modify ciphertext1 below
+ ASSERT_EQ(2048U / 8, ciphertext1.size()) << "Failed to encrypt the message";
string ciphertext2 = EncryptMessage(message, params);
EXPECT_EQ(2048U / 8, ciphertext2.size());
diff --git a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
index 18587ee..e78d4d7 100644
--- a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
+++ b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
@@ -30,6 +30,22 @@
* GL, graphics, etc. All memory sizes must be in real memory usage,
* accounting for stride, bit depth, rounding up to page size, etc.
*
+ * The following getMemory() categories are important for memory accounting in
+ * `dumpsys meminfo` and should be reported as described below:
+ *
+ * - MemtrackType::GRAPHICS and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
+ * This should report the PSS of all DMA buffers mapped by the process
+ * with the specified PID. This PSS can be calculated using ReadDmaBufPss()
+ * form libdmabufinfo.
+ *
+ * - MemtrackType::GL and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
+ * This category should report all GPU private allocations for the specified
+ * PID that are not accounted in /proc/<pid>/smaps.
+ *
+ * - MemtrackType::OTHER and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
+ * Any other memory not accounted for in /proc/<pid>/smaps if any, otherwise
+ * this should return 0.
+ *
* Constructor for the interface should be used to perform memtrack management
* setup actions and must be called once before any calls to getMemory().
*/
@@ -76,7 +92,10 @@
* This information is used to identify GPU devices for GPU specific
* memory accounting (e.g. DMA buffer usage).
*
+ * The device name(s) provided in getGpuDeviceInfo() must match the
+ * device name in the corresponding device(s) sysfs entry.
+ *
* @return vector of DeviceInfo populated for all GPU devices.
*/
- DeviceInfo[] getGpuDeviceInfo();
+ DeviceInfo[] getGpuDeviceInfo();
}
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 7cec49e..e3cee93 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -4711,14 +4711,14 @@
// HAL equivalent of unknown type and a 1.2 HAL implementation must belong
// to one of the categories below.
/** The device does not fall into any category below. */
- OTHER = 1,
+ OTHER = 1,
/** The device runs NNAPI models on single or multi-core CPU. */
- CPU = 2,
+ CPU = 2,
/** The device can run NNAPI models and also accelerate graphics APIs such
- * as OpenGL ES and Vulkan. */
- GPU = 3,
+ * as OpenGL ES and Vulkan. */
+ GPU = 3,
/** Dedicated accelerator for Machine Learning workloads. */
- ACCELERATOR = 4,
+ ACCELERATOR = 4,
};
/**
@@ -5054,7 +5054,7 @@
* Specifies whether or not to measure timing information during execution.
*/
enum MeasureTiming : int32_t {
- NO = 0,
+ NO = 0,
YES = 1,
};
diff --git a/neuralnetworks/1.2/types.t b/neuralnetworks/1.2/types.t
index 21d88ac..054d516 100644
--- a/neuralnetworks/1.2/types.t
+++ b/neuralnetworks/1.2/types.t
@@ -107,14 +107,14 @@
// HAL equivalent of unknown type and a 1.2 HAL implementation must belong
// to one of the categories below.
/** The device does not fall into any category below. */
- OTHER = 1,
+ OTHER = 1,
/** The device runs NNAPI models on single or multi-core CPU. */
- CPU = 2,
+ CPU = 2,
/** The device can run NNAPI models and also accelerate graphics APIs such
- * as OpenGL ES and Vulkan. */
- GPU = 3,
+ * as OpenGL ES and Vulkan. */
+ GPU = 3,
/** Dedicated accelerator for Machine Learning workloads. */
- ACCELERATOR = 4,
+ ACCELERATOR = 4,
};
/**
@@ -450,7 +450,7 @@
* Specifies whether or not to measure timing information during execution.
*/
enum MeasureTiming : int32_t {
- NO = 0,
+ NO = 0,
YES = 1,
};
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
index de84624..5d168d2 100644
--- a/neuralnetworks/TEST_MAPPING
+++ b/neuralnetworks/TEST_MAPPING
@@ -60,6 +60,17 @@
"include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
}
]
+ },
+ {
+ "name": "VtsHalNeuralnetworksTargetTest",
+ "options": [
+ {
+ // Do not use any sample driver except sample-all in order to reduce
+ // testing time. The other sample drivers (fast-float, quant, etc.)
+ // are subsets of sample-all.
+ "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
+ }
+ ]
}
]
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/FencedExecutionResult.aidl
similarity index 82%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/FencedExecutionResult.aidl
index 2706623..7952b34 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/FencedExecutionResult.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -12,7 +12,8 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *////////////////////////////////////////////////////////////////////////////////
+ */
+///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
@@ -30,8 +31,9 @@
// 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.neuralnetworks;
@VintfStability
-parcelable KeyParameterArray {
- android.hardware.security.keymint.KeyParameter[] params;
+parcelable FencedExecutionResult {
+ android.hardware.neuralnetworks.IFencedExecutionCallback callback;
+ @nullable ParcelFileDescriptor syncFence;
}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
index 3ca1550..1f7cbe0 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -34,7 +34,7 @@
@VintfStability
interface IPreparedModel {
android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadline, in long loopTimeoutDuration);
- android.hardware.neuralnetworks.IFencedExecutionCallback executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadline, in long loopTimeoutDuration, in long duration, out @nullable ParcelFileDescriptor syncFence);
+ android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadline, in long loopTimeoutDuration, in long duration);
const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/FencedExecutionResult.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/FencedExecutionResult.aidl
new file mode 100644
index 0000000..ba3be31
--- /dev/null
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/FencedExecutionResult.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.neuralnetworks;
+
+import android.hardware.neuralnetworks.IFencedExecutionCallback;
+
+/**
+ * A result from running an asynchronous execution of a prepared model.
+ */
+@VintfStability
+parcelable FencedExecutionResult {
+ /**
+ * IFencedExecutionCallback can be used to query information like duration and error
+ * status when the execution is completed.
+ */
+ IFencedExecutionCallback callback;
+ /**
+ * The sync fence that will be signaled when the task is completed. The
+ * sync fence will be set to error if a critical error, e.g. hardware
+ * failure or kernel panic, occurs when doing execution.
+ */
+ @nullable ParcelFileDescriptor syncFence;
+}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
index 2414a4a..0240e3c 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -19,7 +19,7 @@
import android.hardware.common.NativeHandle;
import android.hardware.neuralnetworks.ErrorStatus;
import android.hardware.neuralnetworks.ExecutionResult;
-import android.hardware.neuralnetworks.IFencedExecutionCallback;
+import android.hardware.neuralnetworks.FencedExecutionResult;
import android.hardware.neuralnetworks.Request;
/**
@@ -152,11 +152,8 @@
* complete after all sync fences in waitFor are signaled. If the execution
* cannot be finished within the duration, the execution may be aborted. Passing
* -1 means the duration is omitted. Other negative values are invalid.
- * @param out syncFence The sync fence that will be signaled when the task is completed. The
- * sync fence will be set to error if a critical error, e.g. hardware
- * failure or kernel panic, occurs when doing execution.
- * @return The IFencedExecutionCallback can be used to query information like duration and error
- * status when the execution is completed.
+ * @return The FencedExecutionResult parcelable, containing IFencedExecutionCallback and the
+ * sync fence.
* @throws ServiceSpecificException with one of the following ErrorStatus values:
* - DEVICE_UNAVAILABLE if driver is offline or busy
* - GENERAL_FAILURE if there is an unspecified error
@@ -166,7 +163,7 @@
* deadline
* - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
*/
- IFencedExecutionCallback executeFenced(in Request request, in ParcelFileDescriptor[] waitFor,
+ FencedExecutionResult executeFenced(in Request request, in ParcelFileDescriptor[] waitFor,
in boolean measureTiming, in long deadline, in long loopTimeoutDuration,
- in long duration, out @nullable ParcelFileDescriptor syncFence);
+ in long duration);
}
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index 4beb828..4eb704b 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -571,33 +571,32 @@
case Executor::FENCED: {
SCOPED_TRACE("fenced");
ErrorStatus result = ErrorStatus::NONE;
- ndk::ScopedFileDescriptor syncFenceFd;
- std::shared_ptr<IFencedExecutionCallback> fencedCallback;
+ FencedExecutionResult executionResult;
auto ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming,
kNoDeadline, loopTimeoutDuration, kNoDuration,
- &syncFenceFd, &fencedCallback);
+ &executionResult);
ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
<< ret.getDescription();
if (!ret.isOk()) {
result = static_cast<ErrorStatus>(ret.getServiceSpecificError());
executionStatus = result;
- } else if (syncFenceFd.get() != -1) {
+ } else if (executionResult.syncFence.get() != -1) {
std::vector<ndk::ScopedFileDescriptor> waitFor;
- auto dupFd = dup(syncFenceFd.get());
+ auto dupFd = dup(executionResult.syncFence.get());
ASSERT_NE(dupFd, -1);
waitFor.emplace_back(dupFd);
// If a sync fence is returned, try start another run waiting for the sync fence.
ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming,
kNoDeadline, loopTimeoutDuration, kNoDuration,
- &syncFenceFd, &fencedCallback);
+ &executionResult);
ASSERT_TRUE(ret.isOk());
- waitForSyncFence(syncFenceFd.get());
+ waitForSyncFence(executionResult.syncFence.get());
}
if (result == ErrorStatus::NONE) {
- ASSERT_NE(fencedCallback, nullptr);
+ ASSERT_NE(executionResult.callback, nullptr);
Timing timingFenced;
- auto ret =
- fencedCallback->getExecutionInfo(&timing, &timingFenced, &executionStatus);
+ auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced,
+ &executionStatus);
ASSERT_TRUE(ret.isOk());
}
break;
diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
index a37a0ca..1929750 100644
--- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
@@ -198,8 +198,8 @@
static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
}
ndk::ScopedAStatus executeFenced(const Request&, const std::vector<ndk::ScopedFileDescriptor>&,
- bool, int64_t, int64_t, int64_t, ndk::ScopedFileDescriptor*,
- std::shared_ptr<IFencedExecutionCallback>*) override {
+ bool, int64_t, int64_t, int64_t,
+ FencedExecutionResult*) override {
return ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
}
@@ -893,25 +893,24 @@
ErrorStatus executeFenced(const std::shared_ptr<IPreparedModel>& preparedModel,
const Request& request) {
- ndk::ScopedFileDescriptor syncFence;
- std::shared_ptr<IFencedExecutionCallback> fencedCallback;
+ FencedExecutionResult executionResult;
const auto ret = preparedModel->executeFenced(request, {}, false, kNoDeadline,
kOmittedTimeoutDuration, kNoDuration,
- &syncFence, &fencedCallback);
+ &executionResult);
if (!ret.isOk()) {
EXPECT_EQ(ret.getExceptionCode(), EX_SERVICE_SPECIFIC);
return static_cast<ErrorStatus>(ret.getServiceSpecificError());
}
- if (syncFence.get() != -1) {
- waitForSyncFence(syncFence.get());
+ if (executionResult.syncFence.get() != -1) {
+ waitForSyncFence(executionResult.syncFence.get());
}
- EXPECT_NE(fencedCallback, nullptr);
+ EXPECT_NE(executionResult.callback, nullptr);
ErrorStatus executionStatus = ErrorStatus::GENERAL_FAILURE;
Timing time = kNoTiming;
Timing timeFenced = kNoTiming;
const auto retExecutionInfo =
- fencedCallback->getExecutionInfo(&time, &timeFenced, &executionStatus);
+ executionResult.callback->getExecutionInfo(&time, &timeFenced, &executionStatus);
EXPECT_TRUE(retExecutionInfo.isOk());
EXPECT_EQ(time, kNoTiming);
return executionStatus;
diff --git a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
index db8f429..3be4c1b 100644
--- a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
@@ -68,11 +68,10 @@
// fenced
{
SCOPED_TRACE(message + " [executeFenced]");
- ndk::ScopedFileDescriptor syncFence;
- std::shared_ptr<IFencedExecutionCallback> callback;
+ FencedExecutionResult executionResult;
const auto executeStatus = preparedModel->executeFenced(request, {}, false, kNoDeadline,
kOmittedTimeoutDuration,
- kNoDuration, &syncFence, &callback);
+ kNoDuration, &executionResult);
ASSERT_FALSE(executeStatus.isOk());
ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC);
ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()),
diff --git a/neuralnetworks/utils/adapter/Android.bp b/neuralnetworks/utils/adapter/Android.bp
index e8dc3e7..d073106 100644
--- a/neuralnetworks/utils/adapter/Android.bp
+++ b/neuralnetworks/utils/adapter/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
cc_library_static {
name: "neuralnetworks_utils_hal_adapter",
defaults: ["neuralnetworks_utils_defaults"],
diff --git a/power/stats/aidl/OWNERS b/power/stats/aidl/OWNERS
new file mode 100644
index 0000000..b290b49
--- /dev/null
+++ b/power/stats/aidl/OWNERS
@@ -0,0 +1,3 @@
+bsschwar@google.com
+krossmo@google.com
+tstrudel@google.com
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 3867842..9e92d93 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -26,46 +26,56 @@
cc_test {
name: "VtsHalRadioV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["radio_hidl_hal_cell_broadcast.cpp",
- "radio_hidl_hal_data.cpp",
- "radio_hidl_hal_icc.cpp",
- "radio_hidl_hal_ims.cpp",
- "radio_hidl_hal_misc.cpp",
- "radio_hidl_hal_sms.cpp",
- "radio_hidl_hal_stk.cpp",
- "radio_hidl_hal_test.cpp",
- "radio_hidl_hal_voice.cpp",
- "radio_indication.cpp",
- "radio_response.cpp",
- "VtsHalRadioV1_0TargetTest.cpp",
- "vts_test_util.cpp"],
+ srcs: [
+ "radio_hidl_hal_cell_broadcast.cpp",
+ "radio_hidl_hal_data.cpp",
+ "radio_hidl_hal_icc.cpp",
+ "radio_hidl_hal_ims.cpp",
+ "radio_hidl_hal_misc.cpp",
+ "radio_hidl_hal_sms.cpp",
+ "radio_hidl_hal_stk.cpp",
+ "radio_hidl_hal_test.cpp",
+ "radio_hidl_hal_voice.cpp",
+ "radio_indication.cpp",
+ "radio_response.cpp",
+ "VtsHalRadioV1_0TargetTest.cpp",
+ "vts_test_util.cpp",
+ ],
static_libs: [
"android.hardware.radio@1.0",
],
test_config: "vts_hal_radio_target_test.xml",
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
cc_test {
name: "VtsHalSapV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["sap_callback.cpp",
- "sap_hidl_hal_api.cpp",
- "sap_hidl_hal_test.cpp",
- "VtsHalSapV1_0TargetTest.cpp",
- "vts_test_util.cpp"],
+ srcs: [
+ "sap_callback.cpp",
+ "sap_hidl_hal_api.cpp",
+ "sap_hidl_hal_test.cpp",
+ "VtsHalSapV1_0TargetTest.cpp",
+ "vts_test_util.cpp",
+ ],
static_libs: [
"android.hardware.radio@1.0",
],
test_config: "vts_hal_sap_target_test.xml",
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
cc_library_static {
name: "RadioVtsTestUtilBase",
defaults: ["VtsHalTargetTestDefaults"],
- srcs : [
- "vts_test_util.cpp"
+ srcs: [
+ "vts_test_util.cpp",
],
shared_libs: [
"android.hardware.radio@1.0",
diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp
index c576fe8..3ada6ff 100644
--- a/radio/1.1/vts/functional/Android.bp
+++ b/radio/1.1/vts/functional/Android.bp
@@ -26,11 +26,13 @@
cc_test {
name: "VtsHalRadioV1_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["radio_hidl_hal_api.cpp",
- "radio_hidl_hal_test.cpp",
- "radio_indication.cpp",
- "radio_response.cpp",
- "VtsHalRadioV1_1TargetTest.cpp"],
+ srcs: [
+ "radio_hidl_hal_api.cpp",
+ "radio_hidl_hal_test.cpp",
+ "radio_indication.cpp",
+ "radio_response.cpp",
+ "VtsHalRadioV1_1TargetTest.cpp",
+ ],
static_libs: [
"RadioVtsTestUtilBase",
"android.hardware.radio@1.1",
@@ -39,5 +41,8 @@
header_libs: [
"radio.util.header@1.0",
],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/1.2/vts/functional/Android.bp b/radio/1.2/vts/functional/Android.bp
index cb42cc7..1447ade 100644
--- a/radio/1.2/vts/functional/Android.bp
+++ b/radio/1.2/vts/functional/Android.bp
@@ -43,5 +43,8 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/1.3/vts/functional/Android.bp b/radio/1.3/vts/functional/Android.bp
index 516e904..d96d391 100644
--- a/radio/1.3/vts/functional/Android.bp
+++ b/radio/1.3/vts/functional/Android.bp
@@ -41,5 +41,8 @@
"android.hardware.radio@1.0",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index 393716b..a830816 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -1847,9 +1847,9 @@
/**
* SS reference signal received quality, multipled by -1.
*
- * Reference: 3GPP TS 38.215.
+ * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10.
*
- * Range [3, 20], INT_MAX means invalid/unreported.
+ * Range [-20 dB, 43 dB], INT_MAX means invalid/unreported.
*/
int32_t ssRsrq;
diff --git a/radio/1.4/vts/functional/Android.bp b/radio/1.4/vts/functional/Android.bp
index 681e716..167dec8 100644
--- a/radio/1.4/vts/functional/Android.bp
+++ b/radio/1.4/vts/functional/Android.bp
@@ -44,5 +44,8 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"]
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index b061bd5..c1f3f03 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -107,9 +107,9 @@
SSRSRP = 6,
/**
* 5G SS reference signal received quality.
- * Range: -20 dB to -3 dB.
+ * Range: -43 dB to 20 dB.
* Used RAN: NGRAN
- * Reference: 3GPP TS 38.215.
+ * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10
*/
SSRSRQ = 7,
/**
diff --git a/radio/1.5/vts/functional/Android.bp b/radio/1.5/vts/functional/Android.bp
index c04edcf..4549d3c 100644
--- a/radio/1.5/vts/functional/Android.bp
+++ b/radio/1.5/vts/functional/Android.bp
@@ -45,5 +45,8 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"]
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index c83de29..411a09e 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -103,6 +103,12 @@
* - Support simultaneous data call contexts up to DataRegStateResult.maxDataCalls specified
* in the response of getDataRegistrationState.
*
+ * The differences relative to the 1.5 version of the API are:
+ * - The addition of new parameters pduSessionId, sliceInfo, trafficDescriptor, and
+ * matchAllRuleAllowed.
+ * - If an existing data call should be used for the request, that must be indicated in the
+ * response by setting SetupDataCallResult::cid to the context id of that call.
+ *
* @param serial Serial number of request.
* @param accessNetwork The access network to setup the data call. If the data connection cannot
* be established on the specified access network then it should be responded with an error.
@@ -122,7 +128,20 @@
* Reference: 3GPP TS 24.007 section 11.2.3.1b
* @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from
* EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice
- * passed from EPDG is rejected, then the data failure cause must be DataCallFailCause:SLICE_REJECTED.
+ * passed from EPDG is rejected, then the data failure cause must be
+ * DataCallFailCause:SLICE_REJECTED.
+ * @param trafficDescriptor TrafficDescriptor for which data connection needs to be
+ * established. It is used for URSP traffic matching as described in TS 24.526
+ * Section 4.2.2. It includes an optional DNN which, if present, must be used for traffic
+ * matching -- it does not specify the end point to be used for the data call. The end
+ * point is specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end
+ * point if one is not specified through URSP rules.
+ * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this
+ * request is allowed. If false, this request must not use the match-all URSP rule and if
+ * a non-match-all rule is not found (or if URSP rules are not available) it should return
+ * failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed as some
+ * requests need to have a hard failure if the intention cannot be met, for example, a
+ * zero-rating slice.
*
* Response function is IRadioResponse.setupDataCallResponse_1_6()
*
@@ -131,7 +150,8 @@
oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork,
DataProfileInfo dataProfileInfo, bool roamingAllowed,
DataRequestReason reason, vec<LinkAddress> addresses, vec<string> dnses,
- int32_t pduSessionId, OptionalSliceInfo sliceInfo);
+ int32_t pduSessionId, OptionalSliceInfo sliceInfo,
+ OptionalTrafficDescriptor trafficDescriptor, bool matchAllRuleAllowed);
/**
* Send an SMS message
@@ -496,4 +516,33 @@
* Response function is IRadioResponse.getCurrentCallsResponse_1_6()
*/
oneway getCurrentCalls_1_6(int32_t serial);
+
+ /**
+ * Request to get the current slicing configuration including URSP rules and
+ * NSSAIs (configured, allowed and rejected).
+ * URSP stands for UE route selection policy and is defined in 3GPP TS 24.526
+ * Section 4.2.
+ * An NSSAI is a collection of network slices. Each network slice is identified by
+ * an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI
+ * are defined in 3GPP TS 24.501.
+ *
+ * Response function is IRadioResponse.getSlicingConfigResponse()
+ */
+ oneway getSlicingConfig(int32_t serial);
+
+ /**
+ * Provide Carrier specific information to the modem that must be used to
+ * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier
+ * switch and everytime the framework receives a new certificate.
+ *
+ * @param serial Serial number of request.
+ * @param imsiEncryptionInfo ImsiEncryptionInfo as defined in types.hal.
+ *
+ * Response callback is
+ * IRadioResponse.setCarrierInfoForImsiEncryptionResponse()
+ *
+ * Note this API is the same as the 1.1 version except using the 1.6 ImsiEncryptionInfo
+ * as the input param.
+ */
+ oneway setCarrierInfoForImsiEncryption_1_6(int32_t serial, @1.6::ImsiEncryptionInfo imsiEncryptionInfo);
};
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index a1ad207..a4744e1 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -26,6 +26,7 @@
import @1.6::RadioResponseInfo;
import @1.6::SetupDataCallResult;
import @1.6::SignalStrength;
+import @1.6::SlicingConfig;
/**
* Interface declaring response functions to solicited radio requests.
@@ -417,4 +418,17 @@
* RadioError:CANCELLED
*/
oneway getCurrentCallsResponse_1_6(RadioResponseInfo info, vec<Call> calls);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param slicingConfig Current slicing configuration
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:MODEM_ERR
+ */
+ oneway getSlicingConfigResponse(RadioResponseInfo info,
+ SlicingConfig slicingConfig);
};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 875d40a..3e49cfd 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -27,6 +27,7 @@
import @1.1::GeranBands;
import @1.1::ScanStatus;
import @1.1::UtranBands;
+import @1.1::ImsiEncryptionInfo;
import @1.2::Call;
import @1.2::CellInfoCdma;
import @1.2::CellConnectionStatus;
@@ -273,7 +274,8 @@
/**
* Overwritten from @1.5::SetupDataCallResult in order to change the suggestedRetryTime
* to 64-bit value. In the future, this must be extended instead of overwritten.
- * Also added defaultQos, qosSessions, and handoverFailureMode in this version.
+ * Also added defaultQos, qosSessions, handoverFailureMode, pduSessionId, sliceInfo,
+ * and traffic descriptors in this version.
*/
struct SetupDataCallResult {
/** Data call fail cause. DataCallFailCause.NONE if no error. */
@@ -365,6 +367,13 @@
* AccessNetwork:NGRAN.
*/
OptionalSliceInfo sliceInfo;
+
+ /**
+ * TrafficDescriptors for which this data call must be used. It only includes
+ * the TDs for which a data call has been requested so far; it is not an
+ * exhaustive list.
+ */
+ vec<TrafficDescriptor> trafficDescriptors;
};
/**
@@ -696,8 +705,10 @@
RegState regState;
/**
- * Indicates the available voice radio technology, valid values as
- * defined by RadioTechnology.
+ * Indicates the available voice radio technology, valid values as defined by RadioTechnology,
+ * except LTE_CA, which is no longer a valid value on 1.5 or above. When the device is on
+ * carrier aggregation, vendor RIL service should properly report multiple PhysicalChannelConfig
+ * elements through IRadio::currentPhysicalChannelConfigs_1_6.
*/
RadioTechnology rat;
@@ -897,4 +908,229 @@
* Data call fail due to the slice not being allowed for the data call.
*/
SLICE_REJECTED = 0x8CC,
+
+ /**
+ * No matching rule available for the request, and match-all rule is not allowed for it.
+ */
+ MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD,
+
+ /**
+ * If connection failed for all matching URSP rules.
+ */
+ ALL_MATCHING_RULES_FAILED = 0x8CE,
+};
+
+/**
+ * This safe_union represents an optional DNN. DNN stands for Data Network Name
+ * and represents an APN as defined in 3GPP TS 23.003.
+ */
+safe_union OptionalDnn {
+ Monostate noinit;
+ string value;
+};
+
+/**
+ * This safe_union represents an optional OsAppId.
+ */
+safe_union OptionalOsAppId {
+ Monostate noinit;
+ OsAppId value;
+};
+
+/**
+ * This safe_union represents an optional TrafficDescriptor.
+ */
+safe_union OptionalTrafficDescriptor {
+ Monostate noinit;
+ TrafficDescriptor value;
+};
+
+/**
+ * This struct represents a traffic descriptor. A valid struct must have at least
+ * one of the optional values present. This is based on the definition of traffic
+ * descriptor in TS 24.526 Section 5.2.
+ */
+struct TrafficDescriptor {
+ /**
+ * DNN stands for Data Network Name and represents an APN as defined in
+ * 3GPP TS 23.003.
+ */
+ OptionalDnn dnn;
+ /**
+ * Indicates the OsId + OsAppId (used as category in Android).
+ */
+ OptionalOsAppId osAppId;
+};
+
+/**
+ * This struct represents the OsId + OsAppId as defined in TS 24.526 Section 5.2
+ */
+struct OsAppId {
+ /**
+ * Byte array representing OsId + OsAppId. The minimum length of the array is
+ * 18 and maximum length is 272 (16 bytes for OsId + 1 byte for OsAppId length
+ * + up to 255 bytes for OsAppId).
+ */
+ vec<uint8_t> osAppId;
+};
+
+/**
+ * This struct represents the current slicing configuration.
+ */
+struct SlicingConfig {
+ /**
+ * This vector contains the current URSP rules. Empty vector represents that no
+ * rules are configured.
+ */
+ vec<UrspRule> urspRules;
+ /**
+ * Struct containing all NSSAIs (list of slice info).
+ */
+ Nssais nssais;
+};
+
+/**
+ * This struct represents a single URSP rule as defined in 3GPP TS 24.526.
+ */
+struct UrspRule {
+ /**
+ * Precedence value in the range of 0 to 255. Higher value has lower
+ * precedence.
+ */
+ uint8_t precedence;
+ /**
+ * Used as a matcher for network requests.
+ */
+ vec<TrafficDescriptor> trafficDescriptors;
+ /**
+ * List of routes (connection parameters) that must be used for requests
+ * matching a trafficDescriptor.
+ */
+ vec<RouteSelectionDescriptor> routeSelectionDescriptor;
+};
+
+
+/**
+ * This struct represents a single route selection descriptor as defined in
+ * 3GPP TS 24.526.
+ */
+struct RouteSelectionDescriptor {
+ /**
+ * Precedence value in the range of 0 to 255. Higher value has lower
+ * precedence.
+ */
+ uint8_t precedence;
+ /**
+ * Parameters defining this RouteSelectionDescriptor. The length of the vector
+ * must be >= 1.
+ */
+ vec<RouteSelectionDescriptorParams> routeSelectionDescriptorParams;
+};
+
+/**
+ * This struct represents a route selection descriptor. A valid struct must have
+ * at least one of the vectors non-empty.
+ */
+struct RouteSelectionDescriptorParams {
+ /**
+ * Valid values are IP, IPV6 and IPV4V6.
+ */
+ OptionalPdpProtocolType sessionType;
+ OptionalSscMode sscMode;
+ /**
+ * There can be 0 or more SliceInfo specified in a route descriptor.
+ */
+ vec<SliceInfo> sliceInfo;
+ /**
+ * DNN stands for Data Network Name and represents an APN as defined in
+ * 3GPP TS 23.003. There can be 0 or more DNNs specified in a route
+ * descriptor.
+ */
+ vec<string> dnn;
+};
+
+/**
+ * This safe_union represents an optional PdpProtocolType.
+ */
+safe_union OptionalPdpProtocolType {
+ Monostate noinit;
+ PdpProtocolType value;
+};
+
+/**
+ * This safe_union represents an optional SscMode.
+ */
+safe_union OptionalSscMode {
+ Monostate noinit;
+ SscMode value;
+};
+
+/**
+ * This struct contains all NSSAIs (lists of slices).
+ */
+struct Nssais {
+ /**
+ * These are all the slices configured by the network. This includes allowed
+ * and rejected slices, as well as slices that are neither allowed nor rejected
+ * yet. Empty vector indicates that no slices are configured, and in that case
+ * allowed and rejected vectors must be empty as well.
+ */
+ vec<SliceInfo> configured;
+ /**
+ * These are all the slices that the UE is allowed to use. All these slices
+ * must be configured as well. Empty vector indicates that no slices are
+ * allowed yet.
+ */
+ vec<SliceInfo> allowed;
+ /**
+ * These are all the slices that the UE is not allowed to use. All these slices
+ * must be configured as well. Empty vector indicates that no slices are
+ * rejected yet.
+ */
+ vec<RejectedSliceInfo> rejected;
+ /**
+ * Default configured NSSAI
+ */
+ vec<SliceInfo> defaultConfigured;
+};
+
+/**
+ * This struct represents a network slice rejected by the network. It contains a
+ * rejectionCause corresponding to a rejected network slice.
+ */
+struct RejectedSliceInfo {
+ SliceInfo sliceInfo;
+ SliceRejectionCause rejectionCause;
+};
+
+enum SliceRejectionCause : int32_t {
+ NOT_AVAILABLE_IN_PLMN,
+ NOT_AVAILABLE_IN_REG_AREA,
+};
+
+/**
+ * Enum representing session and service continuity mode as defined in
+ * 3GPP TS 23.501.
+ */
+enum SscMode : int32_t {
+ MODE_1 = 1,
+ MODE_2 = 2,
+ MODE_3 = 3,
+};
+
+/**
+ * Public key type from carrier certificate.
+ */
+enum PublicKeyType : int32_t {
+ EPDG = 1, // Key type to be used for ePDG
+ WLAN = 2, // Key type to be used for WLAN
+};
+
+/**
+ * Carrier specific Information sent by the carrier,
+ * which will be used to encrypt the IMSI and IMPI.
+ */
+struct ImsiEncryptionInfo {
+ @1.1::ImsiEncryptionInfo base;
+ PublicKeyType keyType; // Public key type
};
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 44900b8..e82c01a 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -59,9 +59,15 @@
::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo;
memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo));
+ ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor;
+ memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor));
+
+ bool matchAllRuleAllowed = true;
+
Return<void> res =
radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed,
- reason, addresses, dnses, -1, optionalSliceInfo);
+ reason, addresses, dnses, -1, optionalSliceInfo,
+ optionalTrafficDescriptor, matchAllRuleAllowed);
ASSERT_OK(res);
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -82,6 +88,93 @@
}
}
+TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::AccessNetwork accessNetwork =
+ ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN;
+
+ android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileId::DEFAULT;
+ dataProfileInfo.apn = hidl_string("internet");
+ dataProfileInfo.protocol = PdpProtocolType::IP;
+ dataProfileInfo.roamingProtocol = PdpProtocolType::IP;
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = hidl_string("username");
+ dataProfileInfo.password = hidl_string("password");
+ dataProfileInfo.type = DataProfileInfoType::THREE_GPP;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtuV4 = 0;
+ dataProfileInfo.mtuV6 = 0;
+ dataProfileInfo.preferred = true;
+ dataProfileInfo.persistent = false;
+
+ bool roamingAllowed = false;
+
+ std::vector<::android::hardware::radio::V1_5::LinkAddress> addresses = {};
+ std::vector<hidl_string> dnses = {};
+
+ ::android::hardware::radio::V1_2::DataRequestReason reason =
+ ::android::hardware::radio::V1_2::DataRequestReason::NORMAL;
+
+ ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo;
+ memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo));
+
+ ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor;
+ memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor));
+
+ ::android::hardware::radio::V1_6::TrafficDescriptor trafficDescriptor;
+ ::android::hardware::radio::V1_6::OsAppId osAppId;
+ osAppId.osAppId = 1;
+ trafficDescriptor.osAppId.value(osAppId);
+ optionalTrafficDescriptor.value(trafficDescriptor);
+
+ bool matchAllRuleAllowed = true;
+
+ Return<void> res =
+ radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed,
+ reason, addresses, dnses, -1, optionalSliceInfo,
+ optionalTrafficDescriptor, matchAllRuleAllowed);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::SIM_ABSENT,
+ ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+ ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ EXPECT_EQ(optionalTrafficDescriptor.value().osAppId.value().osAppId,
+ radioRsp_v1_6->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId);
+ }
+}
+
+/*
+ * Test IRadio.getSlicingConfig() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, getSlicingConfig) {
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getSlicingConfig(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+ EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+}
+
/*
* Test IRadio_1_6.sendSms() for the response returned.
*/
@@ -583,3 +676,29 @@
EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
}
+
+/*
+ * Test IRadio.setCarrierInfoForImsiEncryption_1_6() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, setCarrierInfoForImsiEncryption_1_6) {
+ serial = GetRandomSerialNumber();
+ ::android::hardware::radio::V1_6::ImsiEncryptionInfo imsiInfo;
+ imsiInfo.base.mcc = "310";
+ imsiInfo.base.mnc = "004";
+ imsiInfo.base.carrierKey = (std::vector<uint8_t>){1, 2, 3, 4, 5, 6};
+ imsiInfo.base.keyIdentifier = "Test";
+ imsiInfo.base.expirationTime = 20180101;
+ imsiInfo.keyType = PublicKeyType::EPDG;
+
+ radio_v1_6->setCarrierInfoForImsiEncryption_1_6(serial, imsiInfo);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+
+ if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_6->rspInfo.error,
+ {::android::hardware::radio::V1_6::RadioError::NONE,
+ ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
+ }
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index b94cd96..f3eaed6 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -89,6 +89,7 @@
// Data
::android::hardware::radio::V1_4::DataRegStateResult dataRegResp;
+ ::android::hardware::radio::V1_6::SetupDataCallResult setupDataCallResult;
// SimLock status
::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp;
@@ -827,6 +828,10 @@
Return<void> getCurrentCallsResponse_1_6(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls);
+
+ Return<void> getSlicingConfigResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::SlicingConfig& slicingConfig);
};
/* Callback class for radio indication */
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index feb9e03..8c8d698 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -1053,11 +1053,13 @@
Return<void> RadioResponse_v1_6::setupDataCallResponse_1_6(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
- const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) {
+ const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse) {
rspInfo = info;
+ setupDataCallResult = dcResponse;
parent_v1_6.notify(info.serial);
return Void();
}
+
Return<void> RadioResponse_v1_6::setNrDualConnectivityStateResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
rspInfo = info;
@@ -1220,3 +1222,11 @@
parent_v1_6.notify(info.serial);
return Void();
}
+
+Return<void> RadioResponse_v1_6::getSlicingConfigResponse(
+ const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_6::SlicingConfig& /*slicingConfig*/) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
diff --git a/radio/config/1.0/vts/functional/Android.bp b/radio/config/1.0/vts/functional/Android.bp
index ef11d7e..36aecff 100644
--- a/radio/config/1.0/vts/functional/Android.bp
+++ b/radio/config/1.0/vts/functional/Android.bp
@@ -38,5 +38,8 @@
"android.hardware.radio.config@1.0",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/config/1.1/vts/functional/Android.bp b/radio/config/1.1/vts/functional/Android.bp
index 3635f83..9037b79 100644
--- a/radio/config/1.1/vts/functional/Android.bp
+++ b/radio/config/1.1/vts/functional/Android.bp
@@ -38,5 +38,8 @@
"android.hardware.radio.config@1.1",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/config/1.2/vts/functional/Android.bp b/radio/config/1.2/vts/functional/Android.bp
index e7cc155..1a15d3f 100644
--- a/radio/config/1.2/vts/functional/Android.bp
+++ b/radio/config/1.2/vts/functional/Android.bp
@@ -40,5 +40,8 @@
"android.hardware.radio.config@1.2",
],
header_libs: ["radio.util.header@1.0"],
- test_suites: ["general-tests", "vts"],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
}
diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal
index ba964bf..8915970 100644
--- a/radio/config/1.3/types.hal
+++ b/radio/config/1.3/types.hal
@@ -21,8 +21,14 @@
*/
struct HalDeviceCapabilities {
/**
- * True indicates that the modem is missing features within the current
- * version of the Radio HAL.
+ * True indicates that the modem does NOT support the following features:
+ * <ul>
+ * <li>Providing either
+ * android.hardware.radio@1.6::LinkCapacityEstimate:secondaryDownlinkCapacityKbps
+ * or android.hardware.radio@1.6::LinkCapacityEstimate:secondaryUplinkCapacityKbps
+ * when given from android.hardware.radio@1.6::RadioIndication:currentLinkCapacityEstimate
+ * </li>
+ * </ul>
*/
bool modemReducedFeatureSet1;
};
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
deleted file mode 100644
index 34f2749..0000000
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
+++ /dev/null
@@ -1,37 +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.
- *////////////////////////////////////////////////////////////////////////////////
-// 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 ByteArray {
- byte[] data;
-}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
index 3faba48..2eb6e35 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
@@ -115,6 +115,7 @@
MISSING_NOT_AFTER = -81,
MISSING_ISSUER_SUBJECT = -82,
INVALID_ISSUER_SUBJECT = -83,
+ BOOT_LEVEL_EXCEEDED = -84,
UNIMPLEMENTED = -100,
VERSION_MISMATCH = -101,
UNKNOWN_ERROR = -1000,
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 bd304f1..30fe6dc 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
@@ -36,7 +36,7 @@
long challenge;
long userId;
long authenticatorId;
- android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType;
+ android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType = android.hardware.security.keymint.HardwareAuthenticatorType.NONE;
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 d3c6910..7150c44 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
@@ -45,5 +45,6 @@
android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose purpose, in byte[] keyBlob, in android.hardware.security.keymint.KeyParameter[] params, in android.hardware.security.keymint.HardwareAuthToken authToken);
void deviceLocked(in boolean passwordOnly, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken);
void earlyBootEnded();
+ byte[] performOperation(in byte[] request);
const int AUTH_TOKEN_MAC_LENGTH = 32;
}
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 a9b9a05..80ed526 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
@@ -33,7 +33,8 @@
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.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 updateAad(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
+ byte[] update(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
+ byte[] finish(in @nullable byte[] input, in @nullable byte[] signature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken, in @nullable byte[] confirmationToken);
void abort();
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
index b430da9..994bd4c 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -33,6 +33,6 @@
package android.hardware.security.keymint;
@VintfStability
parcelable KeyCharacteristics {
- android.hardware.security.keymint.SecurityLevel securityLevel;
+ android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
android.hardware.security.keymint.KeyParameter[] authorizations;
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index d06312a..7747c59 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -34,7 +34,7 @@
@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
parcelable KeyMintHardwareInfo {
int versionNumber;
- android.hardware.security.keymint.SecurityLevel securityLevel;
+ android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
@utf8InCpp String keyMintName;
@utf8InCpp String keyMintAuthorName;
boolean timestampTokenRequired;
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
index f534952..21b083c 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
@@ -33,6 +33,6 @@
package android.hardware.security.keymint;
@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
parcelable KeyParameter {
- android.hardware.security.keymint.Tag tag;
+ android.hardware.security.keymint.Tag tag = android.hardware.security.keymint.Tag.INVALID;
android.hardware.security.keymint.KeyParameterValue value;
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
index 03982e3..2469d27 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
@@ -98,4 +98,5 @@
CERTIFICATE_SUBJECT = -1879047185,
CERTIFICATE_NOT_BEFORE = 1610613744,
CERTIFICATE_NOT_AFTER = 1610613745,
+ MAX_BOOT_LEVEL = 805307378,
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ByteArray.aidl b/security/keymint/aidl/android/hardware/security/keymint/ByteArray.aidl
deleted file mode 100644
index c3b402e..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/ByteArray.aidl
+++ /dev/null
@@ -1,26 +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;
-
-/**
- * This is used to contain a byte[], to make out parameters of byte arrays
- * more convenient for callers.
- */
-@VintfStability
-parcelable ByteArray {
- byte[] data;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
index 5765130..95b38f2 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
@@ -105,6 +105,7 @@
MISSING_NOT_AFTER = -81,
MISSING_ISSUER_SUBJECT = -82,
INVALID_ISSUER_SUBJECT = -83,
+ BOOT_LEVEL_EXCEEDED = -84,
UNIMPLEMENTED = -100,
VERSION_MISMATCH = -101,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
index 417a0b1..57150d5 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -16,17 +16,17 @@
package android.hardware.security.keymint;
-import android.hardware.security.secureclock.Timestamp;
import android.hardware.security.keymint.HardwareAuthenticatorType;
+import android.hardware.security.secureclock.Timestamp;
/**
* HardwareAuthToken is used to prove successful user authentication, to unlock the use of a key.
*
* HardwareAuthTokens are produced by other secure environment applications, notably GateKeeper and
- * biometric authenticators, in response to successful user authentication events. These tokens are passed to
- * begin(), update(), and finish() to prove that authentication occurred. See those methods for
- * more details. It is up to the caller to determine which of the generated auth tokens is
- * appropriate for a given key operation.
+ * biometric authenticators, in response to successful user authentication events. These tokens are
+ * passed to begin(), update(), and finish() to prove that authentication occurred. See those
+ * methods for more details. It is up to the caller to determine which of the generated auth tokens
+ * is appropriate for a given key operation.
*/
@VintfStability
@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
@@ -55,7 +55,7 @@
* authenticatorType describes the type of authentication that took place, e.g. password or
* fingerprint.
*/
- HardwareAuthenticatorType authenticatorType;
+ HardwareAuthenticatorType authenticatorType = HardwareAuthenticatorType.NONE;
/**
* timestamp indicates when the user authentication took place, in milliseconds since some
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 13e98af..384416e 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -18,7 +18,6 @@
import android.hardware.security.keymint.AttestationKey;
import android.hardware.security.keymint.BeginResult;
-import android.hardware.security.keymint.ByteArray;
import android.hardware.security.keymint.HardwareAuthToken;
import android.hardware.security.keymint.IKeyMintOperation;
import android.hardware.security.keymint.KeyCreationResult;
@@ -761,4 +760,18 @@
* an EARLY_BOOT_ONLY key after this method is called must fail with Error::INVALID_KEY_BLOB.
*/
void earlyBootEnded();
+
+ /**
+ * Called by the client to perform a KeyMint operation.
+ *
+ * This method is added primarily as a placeholder. Details will be fleshed before the KeyMint
+ * V1 interface is frozen. Until then, implementations must return ErrorCode::UNIMPLEMENTED.
+ *
+ * @param request is an encrypted buffer containing a description of the operation the client
+ * wishes to perform. Structure, content and encryption are TBD.
+ *
+ * @return an encrypted buffer containing the result of the operation. Structure, content and
+ * encryption are TBD.
+ */
+ byte[] performOperation(in byte[] request);
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index 8c49602..1c2511b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -16,15 +16,75 @@
package android.hardware.security.keymint;
-import android.hardware.security.keymint.ByteArray;
import android.hardware.security.keymint.HardwareAuthToken;
import android.hardware.security.keymint.KeyParameter;
-import android.hardware.security.keymint.KeyParameterArray;
import android.hardware.security.secureclock.TimeStampToken;
@VintfStability
interface IKeyMintOperation {
/**
+ * Provides additional authentication data (AAD) to a cryptographic operation begun with
+ * begin(), provided in the input argument. This method only applies to AEAD modes. This
+ * method may be called multiple times, supplying the AAD in chunks, but may not be called after
+ * update() is called. If updateAad() is called after update(), it must return
+ * ErrorCode::INVALID_TAG.
+ *
+ * If operation is in an invalid state (was aborted or had an error) update() must return
+ * ErrorCode::INVALID_OPERATION_HANDLE.
+ *
+ * If this method returns an error code other than ErrorCode::OK, the operation is aborted and
+ * the operation handle must be invalidated. Any future use of the handle, with this method,
+ * finish, or abort, must return ErrorCode::INVALID_OPERATION_HANDLE.
+ *
+ * == Authorization Enforcement ==
+ *
+ * Key authorization enforcement is performed primarily in begin(). The one exception is the
+ * case where the key has:
+ *
+ * o One or more Tag::USER_SECURE_IDs, and
+ *
+ * o Does not have a Tag::AUTH_TIMEOUT
+ *
+ * In this case, the key requires an authorization per operation, and the update method must
+ * receive a non-null and valid HardwareAuthToken. For the auth token to be valid, all of the
+ * following has to be true:
+ *
+ * o The HMAC field must validate correctly.
+ *
+ * o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
+ * the secure ID values in the token.
+ *
+ * o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
+ *
+ * o The challenge field in the auth token must contain the operationHandle
+ *
+ * If any of these conditions are not met, update() must return
+ * ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+ *
+ * The caller must provide the auth token on every call to updateAad(), update() and finish().
+ *
+ *
+ * For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
+ * decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
+ * be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
+ * it must process all but the tag length and buffer the possible tag data for processing during
+ * finish().
+ *
+ * @param input Additional Authentication Data to be processed.
+ *
+ * @param authToken Authentication token. Can be nullable if not provided.
+ *
+ * @param timeStampToken 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.
+ */
+ void updateAad(in byte[] input, in @nullable HardwareAuthToken authToken,
+ in @nullable TimeStampToken timeStampToken);
+
+ /**
* Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
* with begin().
*
@@ -96,53 +156,28 @@
*
* -- AES keys --
*
- * AES GCM mode supports "associated authentication data," provided via the Tag::ASSOCIATED_DATA
- * tag in the inParams argument. The associated data may be provided in repeated calls
- * (important if the data is too large to send in a single block) but must always precede data
- * to be encrypted or decrypted. An update call may receive both associated data and data to
- * encrypt/decrypt, but subsequent updates must not include associated data. If the caller
- * provides associated data to an update call after a call that includes data to
- * encrypt/decrypt, update() must return ErrorCode::INVALID_TAG.
- *
* For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
* decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
* be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
* it must process all but the tag length and buffer the possible tag data for processing during
* finish().
*
- * TODO: update() needs to be refactored b/168665179.
- *
- * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
- * specify Tag::ADDITIONAL_DATA. Note that additional data may be provided in multiple
- * calls to update(), but only until input data has been provided.
- *
* @param input Data to be processed. Note that update() may or may not consume all of the data
* provided. See return value.
*
- * @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.
+ * @param authToken Authentication token. Can be nullable if not provided.
+ *
+ * @param timeStampToken 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.
*
- * @return int Amount of data that was consumed by update(). If this is less than the
- * amount provided, the caller may provide the remainder in a subsequent call to
- * update() or finish(). Every call to update must consume at least one byte, unless
- * the input is empty, and implementations should consume as much data as reasonably
- * possible for each call.
- *
- * @return outParams returns the updated key parameters from the blob, if needed.
- * operation.
- *
- * @return out variable output The output data, if any.
+ * @return byte[] The output data, if any.
*/
- int update(in @nullable KeyParameterArray inParams,
- in @nullable byte[] input,
- in @nullable HardwareAuthToken inAuthToken,
- in @nullable TimeStampToken inTimeStampToken,
- out @nullable KeyParameterArray outParams,
- out @nullable ByteArray output);
+ byte[] update(in byte[] input, in @nullable HardwareAuthToken authToken,
+ in @nullable TimeStampToken timeStampToken);
/**
* Finalizes a cryptographic operation begun with begin() and invalidates operation.
@@ -229,8 +264,7 @@
*
* TODO: update() will need to be refactored into 2 function. b/168665179.
*
- * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
- * specify Tag::ADDITIONAL_DATA, but only if no input data was provided to update().
+ * @param inParams Additional parameters for the operation.
*
* @param input Data to be processed, per the parameters established in the call to begin().
* finish() must consume all provided data or return ErrorCode::INVALID_INPUT_LENGTH.
@@ -240,19 +274,21 @@
*
* @param authToken Authentication token. Can be nullable if not provided.
*
- * @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.
+ * @param timestampToken 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().
+ * @param confirmationToken is the confirmation token required by keys with
+ * Tag::TRUSTED_CONFIRMATION_REQUIRED.
*
* @return The output data, if any.
+ *
+ * @return outParams Any output parameters generated by finish().
*/
- byte[] finish(in @nullable KeyParameterArray inParams, in @nullable byte[] input,
- in @nullable byte[] inSignature,
- in @nullable HardwareAuthToken authToken,
- in @nullable TimeStampToken inTimeStampToken,
- out @nullable KeyParameterArray outParams);
+ byte[] finish(in @nullable byte[] input, in @nullable byte[] signature,
+ in @nullable HardwareAuthToken authToken,
+ in @nullable TimeStampToken timestampToken,
+ in @nullable byte[] confirmationToken);
/**
* Aborts a cryptographic operation begun with begin(), freeing all internal resources. If an
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
index edd4d8f..3a32e4d 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -31,6 +31,6 @@
*/
@VintfStability
parcelable KeyCharacteristics {
- SecurityLevel securityLevel;
+ SecurityLevel securityLevel = SecurityLevel.SOFTWARE;
KeyParameter[] authorizations;
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index 2fcaf4c..ae0d152 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -34,7 +34,7 @@
/* securityLevel is the security level of the IKeyMintDevice implementation accessed
* through this aidl package. */
- SecurityLevel securityLevel;
+ SecurityLevel securityLevel = SecurityLevel.SOFTWARE;
/* keyMintName is the name of the IKeyMintDevice implementation. */
@utf8InCpp String keyMintName;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl
index f3ed96b..bf6c9b2 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl
@@ -16,8 +16,8 @@
package android.hardware.security.keymint;
-import android.hardware.security.keymint.Tag;
import android.hardware.security.keymint.KeyParameterValue;
+import android.hardware.security.keymint.Tag;
/**
* Identifies the key authorization parameters to be used with keyMint. This is usually
@@ -26,6 +26,6 @@
@VintfStability
@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
parcelable KeyParameter {
- Tag tag;
+ Tag tag = Tag.INVALID;
KeyParameterValue value;
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterArray.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterArray.aidl
deleted file mode 100644
index acab435..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterArray.aidl
+++ /dev/null
@@ -1,31 +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.KeyParameter;
-
-/**
- * Identifies the key authorization parameters to be used with keyMint. This is usually
- * provided as an array of KeyParameters to IKeyMintDevice or Operation.
- */
-@VintfStability
-parcelable KeyParameterArray {
- /**
- * Identify list of key parameters corresponding to a particular key blob.
- */
- KeyParameter[] params;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
index c63859c..ecbde8c 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
@@ -44,13 +44,15 @@
/**
* The TRUSTED_ENVIRONMENT security level represents a KeyMint implementation that runs in an
- * Android process, or a tag enforced by such an implementation. An attacker who completely
- * compromises Android, including the Linux kernel, does not have the ability to subvert it. At
- * attacker who can find an exploit that gains them control of the trusted environment, or who
- * has access to the physical device and can mount a sophisticated hardware attack, may be able
- * to defeat it.
+ * isolated execution environment that is securely isolated from the code running on the kernel
+ * and above, and which satisfies the requirements specified in CDD 9.11.1 [C-1-2]. An attacker
+ * who completely compromises Android, including the Linux kernel, does not have the ability to
+ * subvert it. An attacker who can find an exploit that gains them control of the trusted
+ * environment, or who has access to the physical device and can mount a sophisticated hardware
+ * attack, may be able to defeat it.
*/
TRUSTED_ENVIRONMENT = 1,
+
/**
* The STRONGBOX security level represents a KeyMint implementation that runs in security
* hardware that satisfies the requirements specified in CDD 9.11.2. Roughly speaking, these
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 4f58cbe..aa9aa6f 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -883,11 +883,7 @@
STORAGE_KEY = (7 << 28) /* TagType:BOOL */ | 722,
/**
- * Tag::ASSOCIATED_DATA Provides "associated data" for AES-GCM encryption or decryption. This
- * tag is provided to update and specifies data that is not encrypted/decrypted, but is used in
- * computing the GCM tag.
- *
- * Must never appear KeyCharacteristics.
+ * TODO: Delete when keystore1 is deleted.
*/
ASSOCIATED_DATA = (9 << 28) /* TagType:BYTES */ | 1000,
@@ -964,4 +960,15 @@
* or importKey.
*/
CERTIFICATE_NOT_AFTER = (6 << 28) /* TagType:DATE */ | 1009,
+
+ /**
+ * Tag::MAX_BOOT_LEVEL specifies a maximum boot level at which a key should function.
+ *
+ * Over the course of the init process, the boot level will be raised to
+ * monotonically increasing integer values. Implementations MUST NOT allow the key
+ * to be used once the boot level advances beyond the value of this tag.
+ *
+ * Cannot be hardware enforced in this version.
+ */
+ MAX_BOOT_LEVEL = (3 << 28) /* TagType:UINT */ | 1010,
}
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
index f2651fb..2373b26 100644
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
+++ b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
@@ -259,8 +259,9 @@
}
static keymaster_key_param_t kKeyMintEcdsaP256Params[] = {
- Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC),
- Authorization(TAG_KEY_SIZE, 256), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
+ Authorization(TAG_PURPOSE, KM_PURPOSE_ATTEST_KEY),
+ Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC), Authorization(TAG_KEY_SIZE, 256),
+ Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
Authorization(TAG_EC_CURVE, KM_EC_CURVE_P_256), Authorization(TAG_NO_AUTH_REQUIRED),
// The certificate generated by KM will be discarded, these values don't matter.
Authorization(TAG_CERTIFICATE_NOT_BEFORE, 0), Authorization(TAG_CERTIFICATE_NOT_AFTER, 0)};
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index d61a081..3e87b6b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -386,122 +386,50 @@
return result;
}
-ErrorCode KeyMintAidlTestBase::Update(const AuthorizationSet& in_params, const string& input,
- AuthorizationSet* out_params, string* output,
- int32_t* input_consumed) {
+ErrorCode KeyMintAidlTestBase::UpdateAad(const string& input) {
+ return GetReturnErrorCode(op_->updateAad(vector<uint8_t>(input.begin(), input.end()),
+ {} /* hardwareAuthToken */,
+ {} /* verificationToken */));
+}
+
+ErrorCode KeyMintAidlTestBase::Update(const string& input, string* output) {
SCOPED_TRACE("Update");
Status result;
- EXPECT_NE(op_, nullptr);
- if (!op_) {
- return ErrorCode::UNEXPECTED_NULL_POINTER;
- }
+ if (!output) return ErrorCode::UNEXPECTED_NULL_POINTER;
- KeyParameterArray key_params;
- key_params.params = in_params.vector_data();
+ std::vector<uint8_t> o_put;
+ result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &o_put);
- KeyParameterArray in_keyParams;
- in_keyParams.params = in_params.vector_data();
-
- optional<KeyParameterArray> out_keyParams;
- optional<ByteArray> o_put;
- result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
- &out_keyParams, &o_put, input_consumed);
-
- if (result.isOk()) {
- if (o_put) {
- output->append(o_put->data.begin(), o_put->data.end());
- }
-
- if (out_keyParams) {
- out_params->push_back(AuthorizationSet(out_keyParams->params));
- }
- }
+ if (result.isOk()) output->append(o_put.begin(), o_put.end());
return GetReturnErrorCode(result);
}
-ErrorCode KeyMintAidlTestBase::Update(const string& input, string* out, int32_t* input_consumed) {
- SCOPED_TRACE("Update");
- AuthorizationSet out_params;
- ErrorCode result =
- Update(AuthorizationSet() /* in_params */, input, &out_params, out, input_consumed);
- EXPECT_TRUE(out_params.empty());
- return result;
-}
-
-ErrorCode KeyMintAidlTestBase::Finish(const AuthorizationSet& in_params, const string& input,
- const string& signature, AuthorizationSet* out_params,
+ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature,
string* output) {
SCOPED_TRACE("Finish");
Status result;
EXPECT_NE(op_, nullptr);
- if (!op_) {
- return ErrorCode::UNEXPECTED_NULL_POINTER;
- }
-
- KeyParameterArray key_params;
- key_params.params = in_params.vector_data();
-
- KeyParameterArray in_keyParams;
- in_keyParams.params = in_params.vector_data();
-
- optional<KeyParameterArray> out_keyParams;
- optional<vector<uint8_t>> o_put;
+ if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
vector<uint8_t> oPut;
- result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
- vector<uint8_t>(signature.begin(), signature.end()), {}, {},
- &out_keyParams, &oPut);
+ result = op_->finish(vector<uint8_t>(input.begin(), input.end()),
+ vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
+ {} /* timestampToken */, {} /* confirmationToken */, &oPut);
- if (result.isOk()) {
- if (out_keyParams) {
- out_params->push_back(AuthorizationSet(out_keyParams->params));
- }
+ if (result.isOk()) output->append(oPut.begin(), oPut.end());
- output->append(oPut.begin(), oPut.end());
- }
-
- op_.reset();
+ op_ = {};
return GetReturnErrorCode(result);
}
-ErrorCode KeyMintAidlTestBase::Finish(const string& message, string* output) {
- SCOPED_TRACE("Finish");
- AuthorizationSet out_params;
- string finish_output;
- ErrorCode result = Finish(AuthorizationSet() /* in_params */, message, "" /* signature */,
- &out_params, output);
- if (result != ErrorCode::OK) {
- return result;
- }
- EXPECT_EQ(0U, out_params.size());
- return result;
-}
-
-ErrorCode KeyMintAidlTestBase::Finish(const string& message, const string& signature,
- string* output) {
- SCOPED_TRACE("Finish");
- AuthorizationSet out_params;
- ErrorCode result =
- Finish(AuthorizationSet() /* in_params */, message, signature, &out_params, output);
-
- if (result != ErrorCode::OK) {
- return result;
- }
-
- EXPECT_EQ(0U, out_params.size());
- return result;
-}
-
ErrorCode KeyMintAidlTestBase::Abort(const std::shared_ptr<IKeyMintOperation>& op) {
SCOPED_TRACE("Abort");
EXPECT_NE(op, nullptr);
- if (!op) {
- return ErrorCode::UNEXPECTED_NULL_POINTER;
- }
+ if (!op) return ErrorCode::UNEXPECTED_NULL_POINTER;
Status retval = op->abort();
EXPECT_TRUE(retval.isOk());
@@ -512,9 +440,7 @@
SCOPED_TRACE("Abort");
EXPECT_NE(op_, nullptr);
- if (!op_) {
- return ErrorCode::UNEXPECTED_NULL_POINTER;
- }
+ if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
Status retval = op_->abort();
return static_cast<ErrorCode>(retval.getServiceSpecificError());
@@ -530,30 +456,13 @@
auto KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
const string& message, const AuthorizationSet& in_params)
- -> std::tuple<ErrorCode, string, AuthorizationSet /* out_params */> {
+ -> std::tuple<ErrorCode, string> {
AuthorizationSet begin_out_params;
ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
- AuthorizationSet out_params(std::move(begin_out_params));
- if (result != ErrorCode::OK) {
- return {result, {}, out_params};
- }
+ if (result != ErrorCode::OK) return {result, {}};
string output;
- int32_t consumed = 0;
- AuthorizationSet update_params;
- AuthorizationSet update_out_params;
- result = Update(update_params, message, &update_out_params, &output, &consumed);
- out_params.push_back(update_out_params);
- if (result != ErrorCode::OK) {
- return {result, output, out_params};
- }
-
- string unused;
- AuthorizationSet finish_params;
- AuthorizationSet finish_out_params;
- result = Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output);
- out_params.push_back(finish_out_params);
- return {result, output, out_params};
+ return {Finish(message, &output), output};
}
string KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
@@ -561,30 +470,14 @@
AuthorizationSet* out_params) {
SCOPED_TRACE("ProcessMessage");
AuthorizationSet begin_out_params;
- ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
+ ErrorCode result = Begin(operation, key_blob, in_params, out_params);
EXPECT_EQ(ErrorCode::OK, result);
if (result != ErrorCode::OK) {
return "";
}
string output;
- int32_t consumed = 0;
- AuthorizationSet update_params;
- AuthorizationSet update_out_params;
- result = Update(update_params, message, &update_out_params, &output, &consumed);
- EXPECT_EQ(ErrorCode::OK, result);
- if (result != ErrorCode::OK) {
- return "";
- }
-
- string unused;
- AuthorizationSet finish_params;
- AuthorizationSet finish_out_params;
- EXPECT_EQ(ErrorCode::OK,
- Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output));
-
- out_params->push_back(begin_out_params);
- out_params->push_back(finish_out_params);
+ EXPECT_EQ(ErrorCode::OK, Finish(message, &output));
return output;
}
@@ -674,21 +567,9 @@
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::VERIFY, key_blob, params, &begin_out_params));
string output;
- AuthorizationSet update_params;
- AuthorizationSet update_out_params;
- int32_t consumed;
- ASSERT_EQ(ErrorCode::OK,
- Update(update_params, message, &update_out_params, &output, &consumed));
+ EXPECT_EQ(ErrorCode::OK, Finish(message, signature, &output));
EXPECT_TRUE(output.empty());
- EXPECT_GT(consumed, 0U);
-
- string unused;
- AuthorizationSet finish_params;
- AuthorizationSet finish_out_params;
- EXPECT_EQ(ErrorCode::OK, Finish(finish_params, message.substr(consumed), signature,
- &finish_out_params, &output));
- op_.reset();
- EXPECT_TRUE(output.empty());
+ op_ = {};
}
void KeyMintAidlTestBase::VerifyMessage(const string& message, const string& signature,
@@ -955,14 +836,14 @@
}
ErrorCode KeyMintAidlTestBase::UseAesKey(const vector<uint8_t>& aesKeyBlob) {
- auto [result, ciphertext, out_params] = ProcessMessage(
+ auto [result, ciphertext] = ProcessMessage(
aesKeyBlob, KeyPurpose::ENCRYPT, "1234567890123456",
AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE));
return result;
}
ErrorCode KeyMintAidlTestBase::UseHmacKey(const vector<uint8_t>& hmacKeyBlob) {
- auto [result, mac, out_params] = ProcessMessage(
+ auto [result, mac] = ProcessMessage(
hmacKeyBlob, KeyPurpose::SIGN, "1234567890123456",
AuthorizationSetBuilder().Authorization(TAG_MAC_LENGTH, 128).Digest(Digest::SHA_2_256));
return result;
@@ -970,16 +851,15 @@
ErrorCode KeyMintAidlTestBase::UseRsaKey(const vector<uint8_t>& rsaKeyBlob) {
std::string message(2048 / 8, 'a');
- auto [result, signature, out_params] = ProcessMessage(
+ auto [result, signature] = ProcessMessage(
rsaKeyBlob, KeyPurpose::SIGN, message,
AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
return result;
}
ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob) {
- auto [result, signature, out_params] =
- ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
- AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
+ auto [result, signature] = ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
+ AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
return result;
}
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 452d2b6..0aef81b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -112,15 +112,14 @@
AuthorizationSet* out_params);
ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);
- ErrorCode Update(const AuthorizationSet& in_params, const string& input,
- AuthorizationSet* out_params, string* output, int32_t* input_consumed);
- ErrorCode Update(const string& input, string* out, int32_t* input_consumed);
+ ErrorCode UpdateAad(const string& input);
+ ErrorCode Update(const string& input, string* output);
- ErrorCode Finish(const AuthorizationSet& in_params, const string& input,
- const string& signature, AuthorizationSet* out_params, string* output);
- ErrorCode Finish(const string& message, string* output);
ErrorCode Finish(const string& message, const string& signature, string* output);
- ErrorCode Finish(string* output) { return Finish(string(), output); }
+ ErrorCode Finish(const string& message, string* output) {
+ return Finish(message, {} /* signature */, output);
+ }
+ ErrorCode Finish(string* output) { return Finish({} /* message */, output); }
ErrorCode Abort();
ErrorCode Abort(const shared_ptr<IKeyMintOperation>& op);
@@ -129,9 +128,9 @@
string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
const string& message, const AuthorizationSet& in_params,
AuthorizationSet* out_params);
- std::tuple<ErrorCode, std::string /* processedMessage */, AuthorizationSet /* out_params */>
- ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
- const std::string& message, const AuthorizationSet& in_params);
+ std::tuple<ErrorCode, std::string /* processedMessage */> ProcessMessage(
+ const vector<uint8_t>& key_blob, KeyPurpose operation, const std::string& message,
+ const AuthorizationSet& in_params);
string SignMessage(const vector<uint8_t>& key_blob, const string& message,
const AuthorizationSet& params);
string SignMessage(const string& message, const AuthorizationSet& params);
@@ -262,7 +261,7 @@
ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);
- private:
+ protected:
std::shared_ptr<IKeyMintDevice> keymint_;
uint32_t os_version_;
uint32_t os_patch_level_;
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 71aae90..7ecfa37 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -2751,39 +2751,22 @@
for (int increment = 1; increment <= 240; ++increment) {
for (auto block_mode : block_modes) {
string message(240, 'a');
- auto params = AuthorizationSetBuilder()
- .BlockMode(block_mode)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;
+ auto params =
+ AuthorizationSetBuilder().BlockMode(block_mode).Padding(PaddingMode::NONE);
+ if (block_mode == BlockMode::GCM) {
+ params.Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;
+ }
AuthorizationSet output_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));
string ciphertext;
- int32_t input_consumed;
string to_send;
for (size_t i = 0; i < message.size(); i += increment) {
- to_send.append(message.substr(i, increment));
- EXPECT_EQ(ErrorCode::OK, Update(to_send, &ciphertext, &input_consumed));
- EXPECT_EQ(to_send.length(), input_consumed);
- to_send = to_send.substr(input_consumed);
- EXPECT_EQ(0U, to_send.length());
-
- switch (block_mode) {
- case BlockMode::ECB:
- case BlockMode::CBC:
- // Implementations must take as many blocks as possible, leaving less
- // than a block.
- EXPECT_LE(to_send.length(), 16U);
- break;
- case BlockMode::GCM:
- case BlockMode::CTR:
- // Implementations must always take all the data.
- EXPECT_EQ(0U, to_send.length());
- break;
- }
+ EXPECT_EQ(ErrorCode::OK, Update(message.substr(i, increment), &ciphertext));
}
- EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext)) << "Error sending " << to_send;
+ EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext))
+ << "Error sending " << to_send << " with block mode " << block_mode;
switch (block_mode) {
case BlockMode::GCM:
@@ -2818,9 +2801,7 @@
string plaintext;
for (size_t i = 0; i < ciphertext.size(); i += increment) {
- to_send.append(ciphertext.substr(i, increment));
- EXPECT_EQ(ErrorCode::OK, Update(to_send, &plaintext, &input_consumed));
- to_send = to_send.substr(input_consumed);
+ EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
}
ErrorCode error = Finish(to_send, &plaintext);
ASSERT_EQ(ErrorCode::OK, error) << "Decryption failed for block mode " << block_mode
@@ -3077,17 +3058,13 @@
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
- auto update_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
// Encrypt
AuthorizationSet begin_out_params;
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params))
<< "Begin encrypt";
string ciphertext;
- AuthorizationSet update_out_params;
- ASSERT_EQ(ErrorCode::OK, Finish(update_params, message, "", &update_out_params, &ciphertext));
-
+ ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
+ ASSERT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
ASSERT_EQ(ciphertext.length(), message.length() + 16);
// Grab nonce
@@ -3095,12 +3072,9 @@
// Decrypt.
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt";
+ ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
string plaintext;
- int32_t input_consumed;
- ASSERT_EQ(ErrorCode::OK,
- Update(update_params, ciphertext, &update_out_params, &plaintext, &input_consumed));
- EXPECT_EQ(ciphertext.size(), input_consumed);
- EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext));
+ EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
EXPECT_EQ(message.length(), plaintext.length());
EXPECT_EQ(message, plaintext);
}
@@ -3127,17 +3101,15 @@
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
- auto update_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
// Encrypt
AuthorizationSet begin_out_params;
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params))
<< "Begin encrypt";
string ciphertext;
AuthorizationSet update_out_params;
+ ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
sleep(5);
- ASSERT_EQ(ErrorCode::OK, Finish(update_params, message, "", &update_out_params, &ciphertext));
+ ASSERT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
ASSERT_EQ(ciphertext.length(), message.length() + 16);
@@ -3147,11 +3119,9 @@
// Decrypt.
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt";
string plaintext;
- int32_t input_consumed;
+ ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
sleep(5);
- ASSERT_EQ(ErrorCode::OK,
- Update(update_params, ciphertext, &update_out_params, &plaintext, &input_consumed));
- EXPECT_EQ(ciphertext.size(), input_consumed);
+ ASSERT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
sleep(5);
EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext));
EXPECT_EQ(message.length(), plaintext.length());
@@ -3230,9 +3200,6 @@
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
- auto finish_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
@@ -3241,8 +3208,8 @@
AuthorizationSet finish_out_params;
string ciphertext;
- EXPECT_EQ(ErrorCode::OK,
- Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
+ ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
+ EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
params = AuthorizationSetBuilder()
.Authorizations(begin_out_params)
@@ -3326,16 +3293,13 @@
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
- auto finish_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
string ciphertext;
AuthorizationSet finish_out_params;
- EXPECT_EQ(ErrorCode::OK, Finish(finish_params, "" /* input */, "" /* signature */,
- &finish_out_params, &ciphertext));
+ ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
+ EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
EXPECT_TRUE(finish_out_params.empty());
// Grab nonce
@@ -3343,9 +3307,9 @@
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+ ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
string plaintext;
- EXPECT_EQ(ErrorCode::OK, Finish(finish_params, ciphertext, "" /* signature */,
- &finish_out_params, &plaintext));
+ EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
EXPECT_TRUE(finish_out_params.empty());
@@ -3374,43 +3338,26 @@
.Authorization(TAG_MAC_LENGTH, tag_bits);
AuthorizationSet begin_out_params;
- auto update_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3);
-
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
// No data, AAD only.
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
string ciphertext;
- int32_t input_consumed;
- AuthorizationSet update_out_params;
- EXPECT_EQ(ErrorCode::OK, Update(update_params, "" /* input */, &update_out_params, &ciphertext,
- &input_consumed));
- EXPECT_EQ(0U, input_consumed);
- EXPECT_EQ(0U, ciphertext.size());
- EXPECT_TRUE(update_out_params.empty());
+ EXPECT_EQ(ErrorCode::OK, Update(message, &ciphertext));
+ EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
- // AAD and data.
- EXPECT_EQ(ErrorCode::OK,
- Update(update_params, message, &update_out_params, &ciphertext, &input_consumed));
- EXPECT_EQ(message.size(), input_consumed);
- EXPECT_TRUE(update_out_params.empty());
-
- EXPECT_EQ(ErrorCode::OK, Finish("" /* input */, &ciphertext));
// Expect 128-bit (16-byte) tag appended to ciphertext.
- EXPECT_EQ(message.size() + (tag_bits >> 3), ciphertext.size());
+ EXPECT_EQ(message.size() + (tag_bits / 8), ciphertext.size());
// Grab nonce.
begin_params.push_back(begin_out_params);
// Decrypt
- update_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foofoo", (size_t)6);
-
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("foofoo"));
string plaintext;
- EXPECT_EQ(ErrorCode::OK, Finish(update_params, ciphertext, "" /* signature */,
- &update_out_params, &plaintext));
- EXPECT_TRUE(update_out_params.empty());
+ EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
EXPECT_EQ(message, plaintext);
}
@@ -3434,32 +3381,14 @@
.Authorization(TAG_MAC_LENGTH, 128);
AuthorizationSet begin_out_params;
- auto update_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3);
-
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
- // No data, AAD only.
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
string ciphertext;
- int32_t input_consumed;
- AuthorizationSet update_out_params;
- EXPECT_EQ(ErrorCode::OK, Update(update_params, "" /* input */, &update_out_params, &ciphertext,
- &input_consumed));
- EXPECT_EQ(0U, input_consumed);
- EXPECT_EQ(0U, ciphertext.size());
- EXPECT_TRUE(update_out_params.empty());
+ EXPECT_EQ(ErrorCode::OK, Update(message, &ciphertext));
+ EXPECT_EQ(ErrorCode::INVALID_TAG, UpdateAad("foo"));
- // AAD and data.
- EXPECT_EQ(ErrorCode::OK,
- Update(update_params, message, &update_out_params, &ciphertext, &input_consumed));
- EXPECT_EQ(message.size(), input_consumed);
- EXPECT_TRUE(update_out_params.empty());
-
- // More AAD
- EXPECT_EQ(ErrorCode::INVALID_TAG,
- Update(update_params, "", &update_out_params, &ciphertext, &input_consumed));
-
- op_.reset();
+ op_ = {};
}
/*
@@ -3481,28 +3410,21 @@
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
- auto finish_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6);
-
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
string ciphertext;
- AuthorizationSet finish_out_params;
- EXPECT_EQ(ErrorCode::OK,
- Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
+ EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
// Grab nonce
begin_params.push_back(begin_out_params);
- finish_params = AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA,
- "barfoo" /* Wrong AAD */, (size_t)6);
-
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("barfoo"));
string plaintext;
- EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
- &finish_out_params, &plaintext));
+ EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
}
/*
@@ -3524,25 +3446,22 @@
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
- auto finish_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6);
-
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
string ciphertext;
AuthorizationSet finish_out_params;
- EXPECT_EQ(ErrorCode::OK,
- Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
+ EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
// Wrong nonce
begin_params.push_back(TAG_NONCE, AidlBuf("123456789012"));
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
string plaintext;
- EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
- &finish_out_params, &plaintext));
+ EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
// With wrong nonce, should have gotten garbage plaintext (or none).
EXPECT_NE(message, plaintext);
@@ -3569,17 +3488,12 @@
.Padding(PaddingMode::NONE)
.Authorization(TAG_MAC_LENGTH, 128);
- auto finish_params =
- AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
// Encrypt
AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
string ciphertext;
- AuthorizationSet finish_out_params;
- EXPECT_EQ(ErrorCode::OK,
- Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
- EXPECT_TRUE(finish_out_params.empty());
+ EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
// Corrupt tag
++(*ciphertext.rbegin());
@@ -3589,10 +3503,9 @@
// Decrypt.
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+ EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
string plaintext;
- EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
- &finish_out_params, &plaintext));
- EXPECT_TRUE(finish_out_params.empty());
+ EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
}
/*
@@ -3704,9 +3617,7 @@
begin_params.push_back(TAG_PADDING, PaddingMode::PKCS7);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
string plaintext;
- int32_t input_consumed;
- EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
- EXPECT_EQ(ciphertext.size(), input_consumed);
+ EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
}
@@ -4020,9 +3931,7 @@
.Authorization(TAG_NONCE, iv);
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
string plaintext;
- int32_t input_consumed;
- EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
- EXPECT_EQ(ciphertext.size(), input_consumed);
+ EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
}
@@ -4046,10 +3955,8 @@
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, input_params, &output_params));
string ciphertext;
- int32_t input_consumed;
for (size_t i = 0; i < message.size(); i += increment)
- EXPECT_EQ(ErrorCode::OK,
- Update(message.substr(i, increment), &ciphertext, &input_consumed));
+ EXPECT_EQ(ErrorCode::OK, Update(message.substr(i, increment), &ciphertext));
EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
EXPECT_EQ(message.size(), ciphertext.size());
@@ -4062,8 +3969,7 @@
EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, input_params, &output_params));
string plaintext;
for (size_t i = 0; i < ciphertext.size(); i += increment)
- EXPECT_EQ(ErrorCode::OK,
- Update(ciphertext.substr(i, increment), &plaintext, &input_consumed));
+ EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
EXPECT_EQ(ErrorCode::OK, Finish(&plaintext));
EXPECT_EQ(ciphertext.size(), plaintext.size());
EXPECT_EQ(message, plaintext);
@@ -4727,7 +4633,7 @@
INSTANTIATE_KEYMINT_AIDL_TEST(KeyAgreementTest);
-typedef KeyMintAidlTestBase EarlyBootKeyTest;
+using EarlyBootKeyTest = KeyMintAidlTestBase;
TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) {
auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
@@ -4784,9 +4690,10 @@
CheckedDeleteKey(&rsaKeyData.blob);
CheckedDeleteKey(&ecdsaKeyData.blob);
}
+
INSTANTIATE_KEYMINT_AIDL_TEST(EarlyBootKeyTest);
-typedef KeyMintAidlTestBase UnlockedDeviceRequiredTest;
+using UnlockedDeviceRequiredTest = KeyMintAidlTestBase;
// This may be a problematic test. It can't be run repeatedly without unlocking the device in
// between runs... and on most test devices there are no enrolled credentials so it can't be
@@ -4818,8 +4725,19 @@
CheckedDeleteKey(&rsaKeyData.blob);
CheckedDeleteKey(&ecdsaKeyData.blob);
}
+
INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
+using PerformOperationTest = KeyMintAidlTestBase;
+
+TEST_P(PerformOperationTest, RequireUnimplemented) {
+ vector<uint8_t> response;
+ auto result = keymint_->performOperation({} /* request */, &response);
+ ASSERT_EQ(GetReturnErrorCode(result), ErrorCode::UNIMPLEMENTED);
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(PerformOperationTest);
+
} // namespace aidl::android::hardware::security::keymint::test
int main(int argc, char** argv) {
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 45f9df6..db53a8f 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -80,7 +80,7 @@
/**
* Generate and validate a production-mode key. MAC tag can't be verified.
*/
-TEST_P(GenerateKeyTests, DISABLED_generateEcdsaP256Key_prodMode) {
+TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
MacedPublicKey macedPubKey;
bytevec privateKeyBlob;
bool testMode = false;
@@ -133,7 +133,7 @@
/**
* Generate and validate a test-mode key.
*/
-TEST_P(GenerateKeyTests, DISABLED_generateEcdsaP256Key_testMode) {
+TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) {
MacedPublicKey macedPubKey;
bytevec privateKeyBlob;
bool testMode = true;
@@ -224,7 +224,7 @@
* Generate an empty certificate request in test mode, and decrypt and verify the structure and
* content.
*/
-TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_testMode) {
+TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
bool testMode = true;
bytevec keysToSignMac;
ProtectedData protectedData;
@@ -294,7 +294,7 @@
* TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
* able to decrypt.
*/
-TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
+TEST_P(CertificateRequestTest, EmptyRequest_prodMode) {
bool testMode = false;
bytevec keysToSignMac;
ProtectedData protectedData;
@@ -309,7 +309,7 @@
/**
* Generate a non-empty certificate request in test mode. Decrypt, parse and validate the contents.
*/
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_testMode) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
bool testMode = true;
generateKeys(testMode, 4 /* numKeys */);
@@ -379,7 +379,7 @@
* TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
* able to decrypt.
*/
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_prodMode) {
bool testMode = false;
generateKeys(testMode, 4 /* numKeys */);
@@ -396,7 +396,7 @@
* Generate a non-empty certificate request in test mode, with prod keys. Must fail with
* STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
*/
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodKeyInTestCert) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
generateKeys(false /* testMode */, 2 /* numKeys */);
bytevec keysToSignMac;
@@ -414,7 +414,7 @@
* Generate a non-empty certificate request in prod mode, with test keys. Must fail with
* STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
*/
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_testKeyInProdCert) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
generateKeys(true /* testMode */, 2 /* numKeys */);
bytevec keysToSignMac;
diff --git a/security/keymint/aidl/vts/performance/Android.bp b/security/keymint/aidl/vts/performance/Android.bp
index 03240c3..79ed0d5 100644
--- a/security/keymint/aidl/vts/performance/Android.bp
+++ b/security/keymint/aidl/vts/performance/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
cc_benchmark {
name: "VtsAidlKeyMintBenchmarkTest",
defaults: [
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index f87ca78..6c795f5 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -206,41 +206,15 @@
return std::move(builder);
}
- optional<string> Process(const string& message, const AuthorizationSet& /*in_params*/,
- AuthorizationSet* out_params, const string& signature = "") {
- static const int HIDL_BUFFER_LIMIT = 1 << 14; // 16KB
+ optional<string> Process(const string& message, const string& signature = "") {
ErrorCode result;
- // Update
- AuthorizationSet update_params;
- AuthorizationSet update_out_params;
string output;
- string aidl_output;
- int32_t input_consumed = 0;
- int32_t aidl_input_consumed = 0;
- while (message.length() - input_consumed > 0) {
- result = Update(update_params, message.substr(input_consumed, HIDL_BUFFER_LIMIT),
- &update_out_params, &aidl_output, &aidl_input_consumed);
- if (result != ErrorCode::OK) {
- error_ = result;
- return {};
- }
- output.append(aidl_output);
- input_consumed += aidl_input_consumed;
- aidl_output.clear();
- }
-
- // Finish
- AuthorizationSet finish_params;
- AuthorizationSet finish_out_params;
- result = Finish(finish_params, message.substr(input_consumed), signature,
- &finish_out_params, &aidl_output);
+ result = Finish(message, signature, &output);
if (result != ErrorCode::OK) {
error_ = result;
return {};
}
- output.append(aidl_output);
- out_params->push_back(finish_out_params);
return output;
}
@@ -296,66 +270,36 @@
name_.assign(info.keyMintName.begin(), info.keyMintName.end());
}
- ErrorCode Finish(const AuthorizationSet& in_params, const string& input,
- const string& signature, AuthorizationSet* out_params, string* output) {
- Status result;
+ ErrorCode Finish(const string& input, const string& signature, string* output) {
if (!op_) {
std::cerr << "Finish: Operation is nullptr" << std::endl;
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
- KeyParameterArray key_params;
- key_params.params = in_params.vector_data();
-
- KeyParameterArray in_keyParams;
- in_keyParams.params = in_params.vector_data();
-
- std::optional<KeyParameterArray> out_keyParams;
- std::optional<vector<uint8_t>> o_put;
vector<uint8_t> oPut;
- result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
- vector<uint8_t>(signature.begin(), signature.end()), {}, {},
- &out_keyParams, &oPut);
+ Status result =
+ op_->finish(vector<uint8_t>(input.begin(), input.end()),
+ vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
+ {} /* timestampToken */, {} /* confirmationToken */, &oPut);
- if (result.isOk()) {
- if (out_keyParams) {
- out_params->push_back(AuthorizationSet(out_keyParams->params));
- }
- output->append(oPut.begin(), oPut.end());
- }
+ if (result.isOk()) output->append(oPut.begin(), oPut.end());
+
op_.reset();
return GetReturnErrorCode(result);
}
- ErrorCode Update(const AuthorizationSet& in_params, const string& input,
- AuthorizationSet* out_params, string* output, int32_t* input_consumed) {
+ ErrorCode Update(const string& input, string* output) {
Status result;
if (!op_) {
std::cerr << "Update: Operation is nullptr" << std::endl;
return ErrorCode::UNEXPECTED_NULL_POINTER;
}
- KeyParameterArray key_params;
- key_params.params = in_params.vector_data();
+ std::vector<uint8_t> o_put;
+ result = op_->update(vector<uint8_t>(input.begin(), input.end()), {} /* authToken */,
+ {} /* timestampToken */, &o_put);
- KeyParameterArray in_keyParams;
- in_keyParams.params = in_params.vector_data();
-
- std::optional<KeyParameterArray> out_keyParams;
- std::optional<ByteArray> o_put;
- result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
- &out_keyParams, &o_put, input_consumed);
-
- if (result.isOk()) {
- if (o_put) {
- output->append(o_put->data.begin(), o_put->data.end());
- }
-
- if (out_keyParams) {
- out_params->push_back(AuthorizationSet(out_keyParams->params));
- }
- }
-
+ if (result.isOk() && output) *output = {o_put.begin(), o_put.end()};
return GetReturnErrorCode(result);
}
@@ -493,7 +437,7 @@
}
state.ResumeTiming();
out_params.Clear();
- if (!keymintTest->Process(message, in_params, &out_params)) {
+ if (!keymintTest->Process(message)) {
state.SkipWithError(("Sign error, " + std::to_string(keymintTest->getError())).c_str());
break;
}
@@ -516,7 +460,7 @@
("Error beginning sign, " + std::to_string(keymintTest->getError())).c_str());
return;
}
- std::optional<string> signature = keymintTest->Process(message, in_params, &out_params);
+ std::optional<string> signature = keymintTest->Process(message);
if (!signature) {
state.SkipWithError(("Sign error, " + std::to_string(keymintTest->getError())).c_str());
return;
@@ -534,7 +478,7 @@
return;
}
state.ResumeTiming();
- if (!keymintTest->Process(message, in_params, &out_params, *signature)) {
+ if (!keymintTest->Process(message, *signature)) {
state.SkipWithError(
("Verify error, " + std::to_string(keymintTest->getError())).c_str());
break;
@@ -612,7 +556,7 @@
}
out_params.Clear();
state.ResumeTiming();
- if (!keymintTest->Process(message, in_params, &out_params)) {
+ if (!keymintTest->Process(message)) {
state.SkipWithError(
("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
break;
@@ -636,7 +580,7 @@
("Encryption begin error, " + std::to_string(keymintTest->getError())).c_str());
return;
}
- auto encryptedMessage = keymintTest->Process(message, in_params, &out_params);
+ auto encryptedMessage = keymintTest->Process(message);
if (!encryptedMessage) {
state.SkipWithError(
("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
@@ -653,7 +597,7 @@
return;
}
state.ResumeTiming();
- if (!keymintTest->Process(*encryptedMessage, in_params, &out_params)) {
+ if (!keymintTest->Process(*encryptedMessage)) {
state.SkipWithError(
("Decryption error, " + std::to_string(keymintTest->getError())).c_str());
break;
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 479a11d..ae21125 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -130,6 +130,7 @@
DECLARE_TYPED_TAG(CERTIFICATE_SUBJECT);
DECLARE_TYPED_TAG(CERTIFICATE_NOT_BEFORE);
DECLARE_TYPED_TAG(CERTIFICATE_NOT_AFTER);
+DECLARE_TYPED_TAG(MAX_BOOT_LEVEL);
#undef DECLARE_TYPED_TAG