Merge "Update sensor properties: (1) Add software information (eg, matching and PAD algorithm versions) (2) Remove firmware version from hardware information" into sc-dev
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 af2ae9c..926a791 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -128,6 +128,7 @@
defaults: ["VtsHalAudioTargetTest_defaults"],
srcs: [
"6.0/AudioPrimaryHidlHalTest.cpp",
+ "6.0/Generators.cpp",
],
static_libs: [
"libaudiofoundation",
@@ -154,6 +155,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"],
@@ -174,3 +176,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/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/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 17b61e1..b2f8bf6 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -221,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/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/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/biometrics/common/aidl/OWNERS b/biometrics/common/aidl/OWNERS
new file mode 100644
index 0000000..36d7261
--- /dev/null
+++ b/biometrics/common/aidl/OWNERS
@@ -0,0 +1,2 @@
+ilyamaty@google.com
+kchyn@google.com
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 31d9a90..a8e73fc 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -44,4 +44,5 @@
START = 7,
TOO_DARK = 8,
TOO_BRIGHT = 9,
+ IMMOBILE = 10,
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 3709a64..bf11daa 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -75,5 +75,12 @@
* the image was too bright to be used for matching.
*/
TOO_BRIGHT,
+
+ /**
+ * This message may be sent during enrollment if the same area of the finger has already
+ * been captured during this enrollment session. In general, enrolling multiple areas of the
+ * same finger can help against false rejections.
+ */
+ IMMOBILE,
}
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/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 27e74f1..16fb85c 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -549,7 +549,6 @@
}
}
}
- free_camera_metadata(metadata);
}
mCameraInfoMap.removeItem(cameraId);
diff --git a/camera/device/3.7/Android.bp b/camera/device/3.7/Android.bp
new file mode 100644
index 0000000..42782f2
--- /dev/null
+++ b/camera/device/3.7/Android.bp
@@ -0,0 +1,22 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.camera.device@3.7",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "ICameraDevice.hal",
+ "ICameraDeviceSession.hal",
+ ],
+ interfaces: [
+ "android.hardware.camera.common@1.0",
+ "android.hardware.camera.device@3.2",
+ "android.hardware.camera.device@3.3",
+ "android.hardware.camera.device@3.4",
+ "android.hardware.camera.device@3.5",
+ "android.hardware.camera.device@3.6",
+ "android.hardware.graphics.common@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/camera/device/3.7/ICameraDevice.hal b/camera/device/3.7/ICameraDevice.hal
new file mode 100644
index 0000000..9bc2083
--- /dev/null
+++ b/camera/device/3.7/ICameraDevice.hal
@@ -0,0 +1,43 @@
+/*
+ * 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.camera.device@3.7;
+
+import android.hardware.camera.common@1.0::Status;
+import @3.6::ICameraDevice;
+
+/**
+ * Camera device interface
+ *
+ * Supports the android.hardware.Camera API, and the android.hardware.camera2
+ * API at LIMITED or better hardware level.
+ *
+ * ICameraDevice.open() must return @3.2::ICameraDeviceSession,
+ * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or
+ * @3.7::ICameraDeviceSession.
+ */
+interface ICameraDevice extends @3.6::ICameraDevice {
+ /**
+ * isStreamCombinationSupported_3_7:
+ *
+ * Identical to @3.5::ICameraDevice.isStreamCombinationSupported, except
+ * that it takes a @3.7::StreamConfiguration parameter, which could contain
+ * information about multi-resolution input and output streams.
+ *
+ */
+ isStreamCombinationSupported_3_7(StreamConfiguration streams)
+ generates (Status status, bool queryStatus);
+};
diff --git a/camera/device/3.7/ICameraDeviceSession.hal b/camera/device/3.7/ICameraDeviceSession.hal
new file mode 100644
index 0000000..fb5c7fa
--- /dev/null
+++ b/camera/device/3.7/ICameraDeviceSession.hal
@@ -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.
+ */
+
+package android.hardware.camera.device@3.7;
+
+import android.hardware.camera.common@1.0::Status;
+import @3.2::BufferCache;
+import @3.5::StreamConfiguration;
+import @3.6::ICameraDeviceSession;
+import @3.6::HalStreamConfiguration;
+
+/**
+ * Camera device active session interface.
+ *
+ * Obtained via ICameraDevice::open(), this interface contains the methods to
+ * configure and request captures from an active camera device.
+ */
+interface ICameraDeviceSession extends @3.6::ICameraDeviceSession {
+ /**
+ * configureStreams_3_7:
+ *
+ * Identical to @3.6::ICameraDeviceSession.configureStreams_3_6, except that:
+ *
+ * - The requestedConfiguration allows the camera framework to configure
+ * stream groups.
+ * - For requested configurations of streams within the same group, the
+ * corresponding halConfiguration must have the same usage flags and
+ * maxBuffers.
+ * - Within a CaptureRequest, the application is guaranteed not to request
+ * more than one streams within the same stream group. When one of the
+ * stream within a stream group is requested, the camera HAL can either
+ * produce output on that stream, or any other stream within the same
+ * stream group.
+ * - The requestedConfiguration allows the camera framework to indicate that
+ * input images of different sizes may be submitted within capture
+ * requests.
+ *
+ * @return status Status code for the operation, one of:
+ * OK:
+ * On successful stream configuration.
+ * INTERNAL_ERROR:
+ * If there has been a fatal error and the device is no longer
+ * operational. Only close() can be called successfully by the
+ * framework after this error is returned.
+ * ILLEGAL_ARGUMENT:
+ * If the requested stream configuration is invalid. Some examples
+ * of invalid stream configurations include:
+ * - Including more than 1 INPUT stream
+ * - Not including any OUTPUT streams
+ * - Including streams with unsupported formats, or an unsupported
+ * size for that format.
+ * - Including too many output streams of a certain format.
+ * - Unsupported rotation configuration
+ * - Stream sizes/formats don't satisfy the
+ * StreamConfigurationMode requirements
+ * for non-NORMAL mode, or the requested operation_mode is not
+ * supported by the HAL.
+ * - Unsupported usage flag
+ * - Unsupported stream groupIds, or unsupported multi-resolution
+ * input stream.
+ * The camera service cannot filter out all possible illegal stream
+ * configurations, since some devices may support more simultaneous
+ * streams or larger stream resolutions than the minimum required
+ * for a given camera device hardware level. The HAL must return an
+ * ILLEGAL_ARGUMENT for any unsupported stream set, and then be
+ * ready to accept a future valid stream configuration in a later
+ * configureStreams call.
+ * @return halConfiguration The stream parameters desired by the HAL for
+ * each stream, including maximum buffers, the usage flags, and the
+ * override format.
+ */
+ configureStreams_3_7(StreamConfiguration requestedConfiguration)
+ generates (Status status, @3.6::HalStreamConfiguration halConfiguration);
+
+ /**
+ * processCaptureRequest_3_7:
+ *
+ * Identical to @3.4::ICameraDeviceSession.processCaptureRequest, except that:
+ *
+ * - The capture request can include width and height of the input buffer for
+ * a reprocessing request.
+ *
+ * @return status Status code for the operation, one of:
+ * OK:
+ * On a successful start to processing the capture request
+ * ILLEGAL_ARGUMENT:
+ * If the input is malformed (the settings are empty when not
+ * allowed, the physical camera settings are invalid, there are 0
+ * output buffers, etc) and capture processing
+ * cannot start. Failures during request processing must be
+ * handled by calling ICameraDeviceCallback::notify(). In case of
+ * this error, the framework retains responsibility for the
+ * stream buffers' fences and the buffer handles; the HAL must not
+ * close the fences or return these buffers with
+ * ICameraDeviceCallback::processCaptureResult().
+ * In case of multi-resolution input image, this error must be returned
+ * if the caller passes in a CaptureRequest with an invalid
+ * [inputWith, inputHeight].
+ * INTERNAL_ERROR:
+ * If the camera device has encountered a serious error. After this
+ * error is returned, only the close() method can be successfully
+ * called by the framework.
+ * @return numRequestProcessed Number of requests successfully processed by
+ * camera HAL. When status is OK, this must be equal to the size of
+ * requests. When the call fails, this number is the number of requests
+ * that HAL processed successfully before HAL runs into an error.
+ *
+ */
+ processCaptureRequest_3_7(vec<CaptureRequest> requests, vec<BufferCache> cachesToRemove)
+ generates (Status status, uint32_t numRequestProcessed);
+};
diff --git a/camera/device/3.7/types.hal b/camera/device/3.7/types.hal
new file mode 100644
index 0000000..9450c2f
--- /dev/null
+++ b/camera/device/3.7/types.hal
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera.device@3.7;
+
+import @3.2::CameraMetadata;
+import @3.2::StreamConfigurationMode;
+import @3.4::CaptureRequest;
+import @3.4::Stream;
+
+/**
+ * Stream:
+ *
+ * A descriptor for a single camera input or output stream. A stream is defined
+ * by the framework by its buffer resolution and format, and additionally by the
+ * HAL with the gralloc usage flags and the maximum in-flight buffer count.
+ *
+ * This version extends the @3.4 Stream with the multi-resolution output surface
+ * group Id field.
+ */
+struct Stream {
+ /**
+ * The definition of Stream from the prior version.
+ */
+ @3.4::Stream v3_4;
+
+ /**
+ * The surface group id used for multi-resolution output streams.
+ *
+ * This works simliar to the surfaceGroupId of OutputConfiguration in the
+ * public API, with the exception that this is for multi-resolution image
+ * reader and is used by the camera HAL to choose a target stream within
+ * the same group to which images are written. All streams in the same group
+ * will have the same image format, data space, and usage flag.
+ *
+ * The framework must only call processCaptureRequest on at most one of the
+ * streams within a surface group. Depending on current active physical
+ * camera backing the logical multi-camera, or the pixel mode the camera is
+ * running in, the HAL can choose to request and return a buffer from any
+ * stream within the same group. -1 means that this stream is an input
+ * stream, or is an output stream which doesn't belong to any group.
+ *
+ * Streams with the same non-negative group id must have the same format and
+ * usage flag.
+ */
+ int32_t groupId;
+};
+
+/**
+ * StreamConfiguration:
+ *
+ * Identical to @3.5::StreamConfiguration, except that the streams
+ * vector contains @3.7::Stream.
+ */
+struct StreamConfiguration {
+ /**
+ * An array of camera stream pointers, defining the input/output
+ * configuration for the camera HAL device.
+ */
+ vec<Stream> streams;
+
+ /**
+ * The definition of operation mode from prior version.
+ *
+ */
+ @3.2::StreamConfigurationMode operationMode;
+
+ /**
+ * The definition of session parameters from prior version.
+ */
+ @3.2::CameraMetadata sessionParams;
+
+ /**
+ * The definition of stream configuration counter from prior version.
+ */
+ uint32_t streamConfigCounter;
+
+ /**
+ * If an input stream is configured, whether the input stream is expected to
+ * receive variable resolution images.
+ *
+ * This flag can only be set to true if the camera device supports
+ * multi-resolution input streams by advertising input stream configurations in
+ * physicalCameraMultiResolutionStreamConfigurations in its physical cameras'
+ * characteristics.
+ *
+ * When this flag is set to true, the input stream's width and height can be
+ * any one of the supported multi-resolution input stream sizes.
+ */
+ bool multiResolutionInputImage;
+};
+
+/**
+ * CaptureRequest:
+ *
+ * This version extends 3.4::CaptureRequest with the input buffer's width and
+ * height.
+ */
+struct CaptureRequest {
+ /**
+ * The definition of CaptureRequest from the prior version.
+ */
+ @3.4::CaptureRequest v3_4;
+
+ /**
+ * The width and height of the input buffer for this capture request.
+ *
+ * These fields will be [0, 0] if no input buffer exists in the capture
+ * request.
+ *
+ * If the stream configuration contains an input stream and has the
+ * multiResolutionInputImage flag set to true, the camera client may submit a
+ * reprocessing request with input buffer size different than the
+ * configured input stream size. In that case, the inputWith and inputHeight
+ * fields will be the actual size of the input image.
+ *
+ * If the stream configuration contains an input stream and the
+ * multiResolutionInputImage flag is false, the inputWidth and inputHeight must
+ * match the input stream size.
+ */
+ uint32_t inputWidth;
+ uint32_t inputHeight;
+};
diff --git a/camera/metadata/3.6/types.hal b/camera/metadata/3.6/types.hal
index fb95736..3472ae9 100644
--- a/camera/metadata/3.6/types.hal
+++ b/camera/metadata/3.6/types.hal
@@ -42,6 +42,14 @@
*/
ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE = android.hardware.camera.metadata@3.5::CameraMetadataTag:ANDROID_SCALER_END_3_5,
+ /** android.scaler.physicalCameraMultiResolutionStreamConfigurations [static, enum[], ndk_public]
+ *
+ * <p>The available multi-resolution stream configurations that this
+ * physical camera device supports
+ * (i.e. format, width, height, output/input stream).</p>
+ */
+ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS,
+
ANDROID_SCALER_END_3_6,
};
@@ -49,3 +57,11 @@
/*
* Enumeration definitions for the various entries that need them
*/
+
+/** android.scaler.physicalCameraMultiResolutionStreamConfigurations enumeration values
+ * @see ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS
+ */
+enum CameraMetadataEnumAndroidScalerPhysicalCameraMultiResolutionStreamConfigurations : uint32_t {
+ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT,
+ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT,
+};
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 691d772..8886ee1 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -48,10 +48,12 @@
"android.hardware.camera.device@3.4",
"android.hardware.camera.device@3.5",
"android.hardware.camera.device@3.6",
+ "android.hardware.camera.device@3.7",
"android.hardware.camera.metadata@3.4",
"android.hardware.camera.provider@2.4",
"android.hardware.camera.provider@2.5",
"android.hardware.camera.provider@2.6",
+ "android.hardware.camera.provider@2.7",
"android.hardware.graphics.common@1.0",
"android.hidl.allocator@1.0",
"libgrallocusage",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index d621344..b2fd402 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -40,11 +40,14 @@
#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.6/ICameraDevice.h>
#include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.7/ICameraDevice.h>
+#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
#include <android/hardware/camera/metadata/3.4/types.h>
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
#include <android/hardware/camera/provider/2.6/ICameraProvider.h>
#include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h>
+#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
#include <cutils/properties.h>
@@ -189,12 +192,14 @@
namespace {
// "device@<version>/legacy/<id>"
const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+ const int CAMERA_DEVICE_API_VERSION_3_7 = 0x307;
const int CAMERA_DEVICE_API_VERSION_3_6 = 0x306;
const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+ const char *kHAL3_7 = "3.7";
const char *kHAL3_6 = "3.6";
const char *kHAL3_5 = "3.5";
const char *kHAL3_4 = "3.4";
@@ -231,7 +236,9 @@
return -1;
}
- if (version.compare(kHAL3_6) == 0) {
+ if (version.compare(kHAL3_7) == 0) {
+ return CAMERA_DEVICE_API_VERSION_3_7;
+ } else if (version.compare(kHAL3_6) == 0) {
return CAMERA_DEVICE_API_VERSION_3_6;
} else if (version.compare(kHAL3_5) == 0) {
return CAMERA_DEVICE_API_VERSION_3_5;
@@ -756,7 +763,8 @@
sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
- sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/);
+ sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/,
+ sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/);
void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion,
sp<device::V3_5::ICameraDevice> *device3_5/*out*/);
void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
@@ -1883,6 +1891,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -1926,6 +1935,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2666,6 +2676,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2752,6 +2763,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2832,6 +2844,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2959,6 +2972,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -3025,6 +3039,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -3056,9 +3071,13 @@
sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
sp<device::V3_5::ICameraDeviceSession> sessionV3_5;
sp<device::V3_6::ICameraDeviceSession> sessionV3_6;
+ sp<device::V3_7::ICameraDeviceSession> sessionV3_7;
castSession(session, deviceVersion, &sessionV3_3,
- &sessionV3_4, &sessionV3_5, &sessionV3_6);
- if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
+ &sessionV3_4, &sessionV3_5, &sessionV3_6,
+ &sessionV3_7);
+ if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) {
+ ASSERT_TRUE(sessionV3_7.get() != nullptr);
+ } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
ASSERT_TRUE(sessionV3_6.get() != nullptr);
} else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
ASSERT_TRUE(sessionV3_5.get() != nullptr);
@@ -3122,6 +3141,7 @@
for (const auto& name : cameraDeviceNames) {
int deviceVersion = getCameraDeviceVersion(name, mProviderType);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7:
case CAMERA_DEVICE_API_VERSION_3_6:
case CAMERA_DEVICE_API_VERSION_3_5:
case CAMERA_DEVICE_API_VERSION_3_4:
@@ -3221,11 +3241,13 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider,
&session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
outputStreams.clear();
@@ -3307,6 +3329,7 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
@@ -3344,7 +3367,7 @@
openEmptyDeviceSession(name, mProvider2_6, &cti.session /*out*/,
&cti.staticMeta /*out*/, &cti.cameraDevice /*out*/);
castSession(cti.session, deviceVersion, &cti.session3_3, &cti.session3_4,
- &cti.session3_5, &cti.session3_6);
+ &cti.session3_5, &cti.session3_6, &cti.session3_7);
castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5);
outputStreams.clear();
@@ -3462,11 +3485,13 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
outputStreams.clear();
@@ -3660,11 +3685,13 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
Status rc = isZSLModeAvailable(staticMeta);
@@ -3828,8 +3855,10 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
ASSERT_NE(session3_4, nullptr);
} else {
@@ -3951,11 +3980,13 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
// Check if camera support depth only
@@ -4069,11 +4100,13 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
Status rc = isConstrainedModeAvailable(staticMeta);
@@ -4281,11 +4314,13 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
sp<device::V3_2::ICameraDevice> cameraDevice;
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
&cameraDevice /*out*/);
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
// Check if camera support depth only
@@ -6103,7 +6138,9 @@
sp<device::V3_3::ICameraDeviceSession> session3_3;
sp<device::V3_6::ICameraDeviceSession> session3_6;
- castSession(session, deviceVersion, &session3_3, session3_4, session3_5, &session3_6);
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
+ castSession(session, deviceVersion, &session3_3, session3_4, session3_5,
+ &session3_6, &session3_7);
ASSERT_NE(nullptr, (*session3_4).get());
*useHalBufManager = false;
@@ -6144,7 +6181,7 @@
});
ASSERT_TRUE(ret.isOk());
- ASSERT_TRUE(!allowUnsupport || deviceVersion == CAMERA_DEVICE_API_VERSION_3_5);
+ ASSERT_TRUE(!allowUnsupport || deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
if (allowUnsupport) {
sp<device::V3_5::ICameraDevice> cameraDevice3_5;
castDevice(device3_x, deviceVersion, &cameraDevice3_5);
@@ -6446,7 +6483,9 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
- castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
+ castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
*useHalBufManager = false;
status = find_camera_metadata_ro_entry(staticMeta,
@@ -6583,13 +6622,21 @@
sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
- sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/) {
+ sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/,
+ sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/) {
ASSERT_NE(nullptr, session3_3);
ASSERT_NE(nullptr, session3_4);
ASSERT_NE(nullptr, session3_5);
ASSERT_NE(nullptr, session3_6);
+ ASSERT_NE(nullptr, session3_7);
switch (deviceVersion) {
+ case CAMERA_DEVICE_API_VERSION_3_7: {
+ auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session);
+ ASSERT_TRUE(castResult.isOk());
+ *session3_7 = castResult;
+ }
+ [[fallthrough]];
case CAMERA_DEVICE_API_VERSION_3_6: {
auto castResult = device::V3_6::ICameraDeviceSession::castFrom(session);
ASSERT_TRUE(castResult.isOk());
@@ -7233,7 +7280,9 @@
sp<device::V3_4::ICameraDeviceSession> session3_4;
sp<device::V3_5::ICameraDeviceSession> session3_5;
sp<device::V3_6::ICameraDeviceSession> session3_6;
- castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+ sp<device::V3_7::ICameraDeviceSession> session3_7;
+ castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+ &session3_6, &session3_7);
ASSERT_NE(nullptr, session3_5.get());
hidl_vec<int32_t> streamIds(1);
diff --git a/camera/provider/2.7/Android.bp b/camera/provider/2.7/Android.bp
new file mode 100644
index 0000000..094dd9d
--- /dev/null
+++ b/camera/provider/2.7/Android.bp
@@ -0,0 +1,26 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.camera.provider@2.7",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ "ICameraProvider.hal",
+ ],
+ interfaces: [
+ "android.hardware.camera.common@1.0",
+ "android.hardware.camera.device@1.0",
+ "android.hardware.camera.device@3.2",
+ "android.hardware.camera.device@3.3",
+ "android.hardware.camera.device@3.4",
+ "android.hardware.camera.device@3.5",
+ "android.hardware.camera.device@3.6",
+ "android.hardware.camera.device@3.7",
+ "android.hardware.camera.provider@2.4",
+ "android.hardware.camera.provider@2.5",
+ "android.hardware.camera.provider@2.6",
+ "android.hardware.graphics.common@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+}
diff --git a/camera/provider/2.7/ICameraProvider.hal b/camera/provider/2.7/ICameraProvider.hal
new file mode 100644
index 0000000..c9d52ee
--- /dev/null
+++ b/camera/provider/2.7/ICameraProvider.hal
@@ -0,0 +1,51 @@
+/*
+ * 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.camera.provider@2.7;
+
+import @2.6::ICameraProvider;
+import android.hardware.camera.common@1.0::Status;
+
+/**
+ * Camera provider HAL
+ *
+ * Adds support for the isConcurrentStreamCombinationSupported() with
+ * ICameraDevice@3.7::StreamConfiguration.
+ */
+interface ICameraProvider extends @2.6::ICameraProvider {
+ /**
+ * isConcurrentStreamCombinationSupported_2_7:
+ *
+ * Identical to @2.6::isConcurrentStreamCombinationSupported except that
+ * this function takes a vector of @3.7::StreamConfiguration.
+ *
+ * @param configs a vector of camera ids and their corresponding stream
+ * configurations that need to be queried for support.
+ *
+ * @return status Status code for the operation, one of:
+ * OK:
+ * On successful stream combination query.
+ * METHOD_NOT_SUPPORTED:
+ * The camera provider does not support stream combination query.
+ * INTERNAL_ERROR:
+ * The stream combination query cannot complete due to internal
+ * error.
+ * @return true in case the stream combination is supported, false otherwise.
+ *
+ */
+ isConcurrentStreamCombinationSupported_2_7(vec<CameraIdAndStreamCombination> configs)
+ generates (Status status, bool queryStatus);
+};
diff --git a/camera/provider/2.7/types.hal b/camera/provider/2.7/types.hal
new file mode 100644
index 0000000..363e894
--- /dev/null
+++ b/camera/provider/2.7/types.hal
@@ -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.
+ */
+
+package android.hardware.camera.provider@2.7;
+
+import android.hardware.camera.device@3.7::StreamConfiguration;
+
+/**
+ * CameraIdAndStreamCombination:
+ *
+ * This is identical to @2.6::CameraIdAndStreamCombination except that
+ * streamConfiguration is of version @3.7.
+ */
+struct CameraIdAndStreamCombination {
+ string cameraId;
+ @3.7::StreamConfiguration streamConfiguration;
+};
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/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 6562f22..1f9cdb9 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -165,7 +165,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.camera.provider</name>
- <version>2.4-6</version>
+ <version>2.4-7</version>
<interface>
<name>ICameraProvider</name>
<regex-instance>[^/]+/[0-9]+</regex-instance>
diff --git a/current.txt b/current.txt
index dfe5d9d..af50841 100644
--- a/current.txt
+++ b/current.txt
@@ -787,7 +787,13 @@
0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types
38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types
954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types
+cfaab0e45c5d7b3595032d649da29ed712e920f956c13671efd35602fa81c923 android.hardware.radio@1.0::IRadio
+89d78fa49b09e2f31812bb63e1bfac2bf318a9561473c6b0ed6904ce18377d54 android.hardware.radio@1.0::IRadioIndication
+bc3c8c233085fca3879dc74b490b9e5bc1063258470d3b4c12f7a74bf215cbbd android.hardware.radio@1.0::IRadioResponse
+86fb079a600b2301a752249dfbfc53983a795d752f11aabcb68315a189f6c9a2 android.hardware.radio@1.1::IRadio
+00366b2f88f9ec2458014972938270c8413d4ab303218e37bf3add2b8e6b829a android.hardware.radio@1.1::IRadioResponse
+2b5afef68e3e2ff1dab63e4f2ee57337ef2635ec812f49080cadfce966d33b52 android.hardware.radio@1.2::IRadio
# HALs released in Android S
# NOTE: waiting to freeze HALs until later in the release
-# NOTE: new HALs are recommended to be in AIDL
\ No newline at end of file
+# NOTE: new HALs are recommended to be in AIDL
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 b7ec72e..5f81394 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -2562,7 +2562,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/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/radio/1.0/IRadio.hal b/radio/1.0/IRadio.hal
index 236dbf5..66cd4f0 100644
--- a/radio/1.0/IRadio.hal
+++ b/radio/1.0/IRadio.hal
@@ -385,7 +385,10 @@
* Note this is for backward compatibility with the old radio modem. The modem
* must not use this param for any other reason.
*
- * Response function is IRadioResponse.setupDataCallResponse()
+ * Response function is IRadioResponse.setupDataCallResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setupDataCall_1_2() instead.
*/
oneway setupDataCall(int32_t serial, RadioTechnology radioTechnology,
DataProfileInfo dataProfileInfo, bool modemCognitive, bool roamingAllowed,
@@ -546,7 +549,10 @@
* false => No specific reason specified
* true => Radio shutdown requested
*
- * Response function is IRadioResponse.deactivateDataCallResponse()
+ * Response function is IRadioResponse.deactivateDataCallResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.2 or higher, use @1.2::IRadio.deactivateDataCall_1_2() instead.
*/
oneway deactivateDataCall(int32_t serial, int32_t cid,
bool reasonRadioShutDown);
@@ -1456,7 +1462,10 @@
* @param reportInterval desired reporting interval (ms).
* @param pullMode LCE service mode. true: PULL; false: PUSH.
*
- * Response callback is IRadioResponse.startLceServiceResponse()
+ * Response callback is IRadioResponse.startLceServiceResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
*/
oneway startLceService(int32_t serial, int32_t reportInterval, bool pullMode);
@@ -1466,7 +1475,10 @@
*
* @param serial Serial number of request.
*
- * Response callback is IRadioResponse.stopLceServiceResponse()
+ * Response callback is IRadioResponse.stopLceServiceResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
*/
oneway stopLceService(int32_t serial);
@@ -1475,7 +1487,10 @@
*
* @param serial Serial number of request.
*
- * Response callback is IRadioResponse.pullLceDataResponse()
+ * Response callback is IRadioResponse.pullLceDataResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
*/
oneway pullLceData(int32_t serial);
@@ -1546,7 +1561,10 @@
* @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the
* indications are enabled. See IndicationFilter for the definition of each bit.
*
- * Response callback is IRadioResponse.setIndicationFilterResponse()
+ * Response callback is IRadioResponse.setIndicationFilterResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setIndicationFilter_1_2() instead.
*/
oneway setIndicationFilter(int32_t serial, bitfield<IndicationFilter> indicationFilter);
@@ -1560,7 +1578,10 @@
* @param serial Serial number of request
* @param powerUp True if powering up the sim card
*
- * Response callback is IRadioResponse.setSimCardPowerResponse()
+ * Response callback is IRadioResponse.setSimCardPowerResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.1::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.1 or higher, use @1.1::IRadio.setSimCardPower_1_1() instead.
*/
oneway setSimCardPower(int32_t serial, bool powerUp);
diff --git a/radio/1.0/IRadioIndication.hal b/radio/1.0/IRadioIndication.hal
index eb07226..eb6c8ef 100644
--- a/radio/1.0/IRadioIndication.hal
+++ b/radio/1.0/IRadioIndication.hal
@@ -427,6 +427,9 @@
*
* @param type Type of radio indication
* @param lce LceData information
+ *
+ * DEPRECATED in @1.2 and above, use
+ * @1.2::IRadioIndication.currentLinkCapacityEstimate() instead.
*/
oneway lceData(RadioIndicationType type, LceDataInfo lce);
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index c1b16b7..00cec9f 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -590,10 +590,10 @@
* RadioError:NONE must be returned on both success and failure of setup with the
* DataCallResponse.status containing the actual status
* For all other errors the DataCallResponse is ignored.
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW
* RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
@@ -856,12 +856,12 @@
* @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INVALID_CALL_ID
* RadioError:INVALID_STATE
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
@@ -2420,11 +2420,11 @@
* @param statusInfo LceStatusInfo indicating LCE status
*
* Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:LCE_NOT_SUPPORTED
* RadioError:INTERNAL_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
@@ -2436,6 +2436,7 @@
* @param statusInfo LceStatusInfo indicating LCE status
*
* Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:LCE_NOT_SUPPORTED
@@ -2443,7 +2444,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
oneway stopLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
@@ -2453,6 +2453,7 @@
* @param lceInfo LceDataInfo indicating LCE data as defined in types.hal
*
* Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:LCE_NOT_SUPPORTED
@@ -2460,7 +2461,6 @@
* RadioError:NO_MEMORY
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:SIM_ABSENT
*/
oneway pullLceDataResponse(RadioResponseInfo info, LceDataInfo lceInfo);
@@ -2534,13 +2534,13 @@
* @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:NONE
* RadioError:INVALID_ARGUMENTS
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:NO_MEMORY
* RadioError:INTERNAL_ERR
* RadioError:SYSTEM_ERR
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:NO_RESOURCES
* RadioError:CANCELLED
*/
@@ -2550,9 +2550,9 @@
* @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.1 or higher is supported.
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
- * RadioError:REQUEST_NOT_SUPPORTED
* RadioError:INVALID_ARGUMENTS
* RadioError:INTERNAL_ERR
* RadioError:NO_MEMORY
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/IRadio.hal b/radio/1.1/IRadio.hal
index 22d27d4..de2135a 100644
--- a/radio/1.1/IRadio.hal
+++ b/radio/1.1/IRadio.hal
@@ -77,7 +77,10 @@
* @param serial Serial number of request.
* @param request Defines the radio networks/bands/channels which need to be scanned.
*
- * Response function is IRadioResponse.startNetworkScanResponse()
+ * Response function is IRadioResponse.startNetworkScanResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.2 or higher, use @1.2::IRadio.startNetworkScan_1_2() instead.
*/
oneway startNetworkScan(int32_t serial, NetworkScanRequest request);
diff --git a/radio/1.1/IRadioResponse.hal b/radio/1.1/IRadioResponse.hal
index 759602b..7dc1bc6 100644
--- a/radio/1.1/IRadioResponse.hal
+++ b/radio/1.1/IRadioResponse.hal
@@ -51,6 +51,7 @@
* @param info Response info struct containing response type, serial no. and error
*
* Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
* RadioError:NONE
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:OPERATION_NOT_ALLOWED
@@ -59,7 +60,6 @@
* RadioError:NO_MEMORY
* RadioError:MODEM_ERR
* RadioError:INVALID_ARGUMENTS
- * RadioError:REQUEST_NOT_SUPPORTED
*/
oneway startNetworkScanResponse(RadioResponseInfo info);
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/IRadio.hal b/radio/1.2/IRadio.hal
index 87b0add..6d48ca0 100644
--- a/radio/1.2/IRadio.hal
+++ b/radio/1.2/IRadio.hal
@@ -37,7 +37,10 @@
* @param serial Serial number of request.
* @param request Defines the radio networks/bands/channels which need to be scanned.
*
- * Response function is IRadioResponse.startNetworkScanResponse()
+ * Response function is IRadioResponse.startNetworkScanResponse() which may return
+ * RadioError:REQUEST_NOT_SUPPORTED if @1.4::IRadio or higher is supported.
+ *
+ * DEPRECATED in @1.4 or higher, use @1.4::IRadio.startNetworkScan_1_4() instead.
*/
oneway startNetworkScan_1_2(int32_t serial, NetworkScanRequest request);
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/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/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/types.hal b/radio/1.6/types.hal
index 20f14dc..6400c63 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -707,8 +707,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;
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/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/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/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
diff --git a/tv/tuner/1.0/vts/functional/FilterTests.cpp b/tv/tuner/1.0/vts/functional/FilterTests.cpp
index 240aa9f..1a09290 100644
--- a/tv/tuner/1.0/vts/functional/FilterTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FilterTests.cpp
@@ -78,24 +78,20 @@
DemuxFilterEvent filterEvent = mFilterEvent;
ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId);
// todo separate filter handlers
- for (int i = 0; i < filterEvent.events.size(); i++) {
- switch (mFilterEventType) {
- case FilterEventType::SECTION:
- mDataLength = filterEvent.events[i].section().dataLength;
+ for (auto event : filterEvent.events) {
+ switch (event.getDiscriminator()) {
+ case DemuxFilterEvent::Event::hidl_discriminator::section:
+ mDataLength = event.section().dataLength;
break;
- case FilterEventType::PES:
- mDataLength = filterEvent.events[i].pes().dataLength;
+ case DemuxFilterEvent::Event::hidl_discriminator::pes:
+ mDataLength = event.pes().dataLength;
break;
- case FilterEventType::MEDIA:
- return dumpAvData(filterEvent.events[i].media());
- case FilterEventType::RECORD:
- return readRecordData(filterEvent.events[i].tsRecord());
- case FilterEventType::MMTPRECORD:
- break;
- case FilterEventType::DOWNLOAD:
- break;
+ case DemuxFilterEvent::Event::hidl_discriminator::media:
+ return dumpAvData(event.media());
+ case DemuxFilterEvent::Event::hidl_discriminator::tsRecord:
+ return readRecordData(event.tsRecord());
default:
- break;
+ continue;
}
// EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not
// match";
@@ -150,11 +146,6 @@
mFilter = filter;
status = result;
});
-
- if (status == Result::SUCCESS) {
- mFilterCallback->setFilterEventType(getFilterEventType(type));
- }
-
return AssertionResult(status == Result::SUCCESS);
}
diff --git a/tv/tuner/1.0/vts/functional/FilterTests.h b/tv/tuner/1.0/vts/functional/FilterTests.h
index c61fa18..7bc4832 100644
--- a/tv/tuner/1.0/vts/functional/FilterTests.h
+++ b/tv/tuner/1.0/vts/functional/FilterTests.h
@@ -66,17 +66,6 @@
using namespace std;
-enum FilterEventType : uint8_t {
- UNDEFINED,
- SECTION,
- MEDIA,
- PES,
- RECORD,
- MMTPRECORD,
- DOWNLOAD,
- TEMI,
-};
-
using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
using MQDesc = MQDescriptorSync<uint8_t>;
@@ -104,7 +93,6 @@
void setFilterId(uint32_t filterId) { mFilterId = filterId; }
void setFilterInterface(sp<IFilter> filter) { mFilter = filter; }
- void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
void testFilterDataOutput();
@@ -130,7 +118,6 @@
uint32_t mFilterId;
sp<IFilter> mFilter;
- FilterEventType mFilterEventType;
std::unique_ptr<FilterMQ> mFilterMQ;
EventFlag* mFilterMQEventFlag;
DemuxFilterEvent mFilterEvent;
@@ -168,53 +155,6 @@
AssertionResult closeFilter(uint32_t filterId);
AssertionResult closeTimeFilter();
- FilterEventType getFilterEventType(DemuxFilterType type) {
- FilterEventType eventType = FilterEventType::UNDEFINED;
- switch (type.mainType) {
- case DemuxFilterMainType::TS:
- switch (type.subType.tsFilterType()) {
- case DemuxTsFilterType::UNDEFINED:
- break;
- case DemuxTsFilterType::SECTION:
- eventType = FilterEventType::SECTION;
- break;
- case DemuxTsFilterType::PES:
- eventType = FilterEventType::PES;
- break;
- case DemuxTsFilterType::TS:
- break;
- case DemuxTsFilterType::AUDIO:
- case DemuxTsFilterType::VIDEO:
- eventType = FilterEventType::MEDIA;
- break;
- case DemuxTsFilterType::PCR:
- break;
- case DemuxTsFilterType::RECORD:
- eventType = FilterEventType::RECORD;
- break;
- case DemuxTsFilterType::TEMI:
- eventType = FilterEventType::TEMI;
- break;
- }
- break;
- case DemuxFilterMainType::MMTP:
- /*mmtpSettings*/
- break;
- case DemuxFilterMainType::IP:
- /*ipSettings*/
- break;
- case DemuxFilterMainType::TLV:
- /*tlvSettings*/
- break;
- case DemuxFilterMainType::ALP:
- /*alpSettings*/
- break;
- default:
- break;
- }
- return eventType;
- }
-
protected:
static AssertionResult failure() { return ::testing::AssertionFailure(); }
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index 884b507..aec1fd0 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -145,26 +145,36 @@
case DemuxFilterMainType::TS:
mCallback->onFilterEvent(createMediaEvent());
mCallback->onFilterEvent(createTsRecordEvent());
- mCallback_1_1->onFilterEvent_1_1(createTsRecordEvent(), createTsRecordEventExt());
mCallback->onFilterEvent(createTemiEvent());
+ // clients could still pass 1.0 callback
+ if (mCallback_1_1 != NULL) {
+ mCallback_1_1->onFilterEvent_1_1(createTsRecordEvent(), createTsRecordEventExt());
+ }
break;
case DemuxFilterMainType::MMTP:
mCallback->onFilterEvent(createDownloadEvent());
mCallback->onFilterEvent(createMmtpRecordEvent());
- mCallback_1_1->onFilterEvent_1_1(createMmtpRecordEvent(), createMmtpRecordEventExt());
+ if (mCallback_1_1 != NULL) {
+ mCallback_1_1->onFilterEvent_1_1(createMmtpRecordEvent(),
+ createMmtpRecordEventExt());
+ }
break;
case DemuxFilterMainType::IP:
mCallback->onFilterEvent(createSectionEvent());
mCallback->onFilterEvent(createIpPayloadEvent());
break;
case DemuxFilterMainType::TLV: {
- DemuxFilterEvent emptyFilterEvent;
- mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createMonitorEvent());
+ if (mCallback_1_1 != NULL) {
+ DemuxFilterEvent emptyFilterEvent;
+ mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createMonitorEvent());
+ }
break;
}
case DemuxFilterMainType::ALP: {
- DemuxFilterEvent emptyFilterEvent;
- mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createRestartEvent());
+ if (mCallback_1_1 != NULL) {
+ DemuxFilterEvent emptyFilterEvent;
+ mCallback_1_1->onFilterEvent_1_1(emptyFilterEvent, createRestartEvent());
+ }
break;
}
default:
@@ -967,7 +977,6 @@
.dataLength = 3,
.offset = 4,
.isSecureMemory = true,
- .avDataId = 5,
.mpuSequenceNumber = 6,
.isPesPrivateData = true,
});
@@ -988,9 +997,16 @@
native_handle_t* nativeHandle = createNativeHandle(av_fd);
if (nativeHandle == NULL) {
+ ::close(av_fd);
+ ALOGE("[Filter] Failed to create native_handle %d", errno);
return event;
}
+ // Create a dataId and add a <dataId, av_fd> pair into the dataId2Avfd map
+ uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
+ mDataId2Avfd[dataId] = dup(av_fd);
+ event.events[0].media().avDataId = dataId;
+
hidl_handle handle;
handle.setTo(nativeHandle, /*shouldOwn=*/true);
event.events[0].media().avMemory = std::move(handle);
diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp
index 0f6784b..e3fbdad 100644
--- a/tv/tuner/1.1/default/Frontend.cpp
+++ b/tv/tuner/1.1/default/Frontend.cpp
@@ -88,18 +88,6 @@
Return<Result> Frontend::scan(const FrontendSettings& settings, FrontendScanType type) {
ALOGV("%s", __FUNCTION__);
-
- if (mType == FrontendType::ATSC) {
- FrontendScanMessage msg;
- msg.isLocked(true);
- mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
- mIsLocked = true;
- return Result::SUCCESS;
- }
- if (mType != FrontendType::DVBT) {
- return Result::UNAVAILABLE;
- }
-
FrontendScanMessage msg;
if (mIsLocked) {
@@ -108,15 +96,96 @@
return Result::SUCCESS;
}
- uint32_t frequency = settings.dvbt().frequency;
+ uint32_t frequency;
+ switch (settings.getDiscriminator()) {
+ case FrontendSettings::hidl_discriminator::analog:
+ frequency = settings.analog().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::atsc:
+ frequency = settings.atsc().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::atsc3:
+ frequency = settings.atsc3().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::dvbs:
+ frequency = settings.dvbs().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::dvbc:
+ frequency = settings.dvbc().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::dvbt:
+ frequency = settings.dvbt().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::isdbs:
+ frequency = settings.isdbs().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::isdbs3:
+ frequency = settings.isdbs3().frequency;
+ break;
+ case FrontendSettings::hidl_discriminator::isdbt:
+ frequency = settings.isdbt().frequency;
+ break;
+ }
+
if (type == FrontendScanType::SCAN_BLIND) {
frequency += 100;
}
+
msg.frequencies({frequency});
mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg);
- msg.isLocked(true);
- mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
- mIsLocked = true;
+
+ msg.progressPercent(20);
+ mCallback->onScanMessage(FrontendScanMessageType::PROGRESS_PERCENT, msg);
+
+ msg.symbolRates({30});
+ mCallback->onScanMessage(FrontendScanMessageType::SYMBOL_RATE, msg);
+
+ if (mType == FrontendType::DVBT) {
+ msg.hierarchy(FrontendDvbtHierarchy::HIERARCHY_NON_NATIVE);
+ mCallback->onScanMessage(FrontendScanMessageType::HIERARCHY, msg);
+ }
+
+ if (mType == FrontendType::ANALOG) {
+ msg.analogType(FrontendAnalogType::PAL);
+ mCallback->onScanMessage(FrontendScanMessageType::ANALOG_TYPE, msg);
+ }
+
+ msg.plpIds({3});
+ mCallback->onScanMessage(FrontendScanMessageType::PLP_IDS, msg);
+
+ msg.groupIds({2});
+ mCallback->onScanMessage(FrontendScanMessageType::GROUP_IDS, msg);
+
+ msg.inputStreamIds({1});
+ mCallback->onScanMessage(FrontendScanMessageType::INPUT_STREAM_IDS, msg);
+
+ FrontendScanMessage::Standard s;
+ switch (mType) {
+ case FrontendType::DVBT:
+ s.tStd(FrontendDvbtStandard::AUTO);
+ msg.std(s);
+ mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
+ break;
+ case FrontendType::DVBS:
+ s.sStd(FrontendDvbsStandard::AUTO);
+ msg.std(s);
+ mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
+ break;
+ case FrontendType::ANALOG:
+ s.sifStd(FrontendAnalogSifStandard::AUTO);
+ msg.std(s);
+ mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
+ break;
+ default:
+ break;
+ }
+
+ FrontendScanAtsc3PlpInfo info{
+ .plpId = 1,
+ .bLlsFlag = false,
+ };
+ msg.atsc3PlpInfos({info});
+ mCallback->onScanMessage(FrontendScanMessageType::ATSC3_PLP_INFO, msg);
sp<V1_1::IFrontendCallback> frontendCallback_v1_1 =
V1_1::IFrontendCallback::castFrom(mCallback);
@@ -129,15 +198,20 @@
frontendCallback_v1_1->onScanMessageExt1_1(
V1_1::FrontendScanMessageTypeExt1_1::HIGH_PRIORITY, msg);
} else {
- ALOGD("[Filter] Couldn't cast to V1_1 IFrontendCallback");
+ ALOGD("[Frontend] Couldn't cast to V1_1 IFrontendCallback");
}
+ msg.isLocked(true);
+ mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
+ mIsLocked = true;
+
return Result::SUCCESS;
}
Return<Result> Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type,
- const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) {
+ const V1_1::FrontendSettingsExt1_1& settingsExt1_1) {
ALOGV("%s", __FUNCTION__);
+ ALOGD("[Frontend] scan_1_1 end frequency %d", settingsExt1_1.endFrequency);
return scan(settings, type);
}
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index 9bad971..4363407 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -16,7 +16,7 @@
stability: "vintf",
backend: {
java: {
- platform_apis: true,
+ sdk_version: "module_current",
},
ndk: {
vndk: {
diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal
index 3a5560b..e1c0d32 100644
--- a/wifi/1.5/types.hal
+++ b/wifi/1.5/types.hal
@@ -142,23 +142,23 @@
* Data packet min contention time (usec). It includes both the internal contention time
* among different access categories within the chipset and the contention time for the medium.
*/
- uint64_t contentionTimeMinInUsec;
+ uint32_t contentionTimeMinInUsec;
/**
* Data packet max contention time (usec). It includes both the internal contention time
* among different access categories within the chipset and the contention time for the medium.
*/
- uint64_t contentionTimeMaxInUsec;
+ uint32_t contentionTimeMaxInUsec;
/**
* Data packet average contention time (usec). It includes both the internal contention time
* among different access categories within the chipset and the contention time for the medium.
*/
- uint64_t contentionTimeAvgInUsec;
+ uint32_t contentionTimeAvgInUsec;
/**
* Number of data packets used for contention statistics.
*/
- uint64_t contentionNumSamples;
+ uint32_t contentionNumSamples;
};
/**
diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal
index aec61c4..c39de6e 100644
--- a/wifi/supplicant/1.4/types.hal
+++ b/wifi/supplicant/1.4/types.hal
@@ -104,6 +104,7 @@
*/
enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask {
/**
+ * WPA3 SAE Public-Key.
*/
SAE_PK = 1 << 2,
};