Merge "Add AIDL version check for injectNiSuplMessageData()" into udc-dev
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 7830501..7622d9a 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -192,6 +192,19 @@
* device address is specified for a point-to-multipoint external device
* connection.
*
+ * Since not all modules have a DSP that could perform sample rate and
+ * format conversions, behavior related to mix port configurations may vary.
+ * For modules with a DSP, mix ports can be pre-configured and have a fixed
+ * set of audio profiles supported by the DSP. For modules without a DSP,
+ * audio profiles of mix ports may change after connecting an external
+ * device. The typical case is that the mix port has an empty set of
+ * profiles when no external devices are connected, and after external
+ * device connection it receives the same set of profiles as the device
+ * ports that they can be routed to. The client will re-query current port
+ * configurations using 'getAudioPorts'. All mix ports that can be routed to
+ * the connected device port must have a non-empty set of audio profiles
+ * after successful connection of an external device.
+ *
* Handling of a disconnect is done in a reverse order:
* 1. Reset port configuration using the 'resetAudioPortConfig' method.
* 2. Release the connected device port by calling the 'disconnectExternalDevice'
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 2cf862c..305c924 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -99,6 +99,12 @@
return 0;
}
+constexpr bool isDefaultAudioFormat(
+ const ::aidl::android::media::audio::common::AudioFormatDescription& desc) {
+ return desc.type == ::aidl::android::media::audio::common::AudioFormatType::DEFAULT &&
+ desc.pcm == ::aidl::android::media::audio::common::PcmType::DEFAULT;
+}
+
constexpr bool isTelephonyDeviceType(
::aidl::android::media::audio::common::AudioDeviceType device) {
return device == ::aidl::android::media::audio::common::AudioDeviceType::IN_TELEPHONY_RX ||
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 984b9a1..6b417a4 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -143,6 +143,21 @@
}
}
+std::ostream& operator<<(std::ostream& os, Module::Type t) {
+ switch (t) {
+ case Module::Type::DEFAULT:
+ os << "default";
+ break;
+ case Module::Type::R_SUBMIX:
+ os << "r_submix";
+ break;
+ case Module::Type::USB:
+ os << "usb";
+ break;
+ }
+ return os;
+}
+
void Module::cleanUpPatch(int32_t patchId) {
erase_all_values(mPatches, std::set<int32_t>{patchId});
}
@@ -352,16 +367,17 @@
ndk::ScopedAStatus Module::setModuleDebug(
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) {
- LOG(DEBUG) << __func__ << ": old flags:" << mDebug.toString()
+ LOG(DEBUG) << __func__ << ": " << mType << ": old flags:" << mDebug.toString()
<< ", new flags: " << in_debug.toString();
if (mDebug.simulateDeviceConnections != in_debug.simulateDeviceConnections &&
!mConnectedDevicePorts.empty()) {
- LOG(ERROR) << __func__ << ": attempting to change device connections simulation "
- << "while having external devices connected";
+ LOG(ERROR) << __func__ << ": " << mType
+ << ": attempting to change device connections simulation while having external "
+ << "devices connected";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
if (in_debug.streamTransientStateDelayMs < 0) {
- LOG(ERROR) << __func__ << ": streamTransientStateDelayMs is negative: "
+ LOG(ERROR) << __func__ << ": " << mType << ": streamTransientStateDelayMs is negative: "
<< in_debug.streamTransientStateDelayMs;
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -440,38 +456,45 @@
LOG(DEBUG) << __func__ << ": device port " << connectedPort.id << " device set to "
<< connectedDevicePort.device.toString();
// Check if there is already a connected port with for the same external device.
- for (auto connectedPortId : mConnectedDevicePorts) {
- auto connectedPortIt = findById<AudioPort>(ports, connectedPortId);
+ for (auto connectedPortPair : mConnectedDevicePorts) {
+ auto connectedPortIt = findById<AudioPort>(ports, connectedPortPair.first);
if (connectedPortIt->ext.get<AudioPortExt::Tag::device>().device ==
connectedDevicePort.device) {
LOG(ERROR) << __func__ << ": device " << connectedDevicePort.device.toString()
- << " is already connected at the device port id " << connectedPortId;
+ << " is already connected at the device port id "
+ << connectedPortPair.first;
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
}
}
if (!mDebug.simulateDeviceConnections) {
- // In a real HAL here we would attempt querying the profiles from the device.
- LOG(ERROR) << __func__ << ": failed to query supported device profiles";
- // TODO: Check the return value when it is ready for actual devices.
- populateConnectedDevicePort(&connectedPort);
+ if (ndk::ScopedAStatus status = populateConnectedDevicePort(&connectedPort);
+ !status.isOk()) {
+ return status;
+ }
+ } else {
+ auto& connectedProfiles = getConfig().connectedProfiles;
+ if (auto connectedProfilesIt = connectedProfiles.find(templateId);
+ connectedProfilesIt != connectedProfiles.end()) {
+ connectedPort.profiles = connectedProfilesIt->second;
+ }
+ }
+ if (connectedPort.profiles.empty()) {
+ LOG(ERROR) << "Profiles of a connected port still empty after connecting external device "
+ << connectedPort.toString();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
connectedPort.id = ++getConfig().nextPortId;
- mConnectedDevicePorts.insert(connectedPort.id);
+ auto [connectedPortsIt, _] =
+ mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::vector<int32_t>()));
LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
<< "connected port ID " << connectedPort.id;
- auto& connectedProfiles = getConfig().connectedProfiles;
- if (auto connectedProfilesIt = connectedProfiles.find(templateId);
- connectedProfilesIt != connectedProfiles.end()) {
- connectedPort.profiles = connectedProfilesIt->second;
- }
ports.push_back(connectedPort);
onExternalDeviceConnectionChanged(connectedPort, true /*connected*/);
- *_aidl_return = std::move(connectedPort);
+ std::vector<int32_t> routablePortIds;
std::vector<AudioRoute> newRoutes;
auto& routes = getConfig().routes;
for (auto& r : routes) {
@@ -481,15 +504,30 @@
newRoute.sinkPortId = connectedPort.id;
newRoute.isExclusive = r.isExclusive;
newRoutes.push_back(std::move(newRoute));
+ routablePortIds.insert(routablePortIds.end(), r.sourcePortIds.begin(),
+ r.sourcePortIds.end());
} else {
auto& srcs = r.sourcePortIds;
if (std::find(srcs.begin(), srcs.end(), templateId) != srcs.end()) {
srcs.push_back(connectedPort.id);
+ routablePortIds.push_back(r.sinkPortId);
}
}
}
routes.insert(routes.end(), newRoutes.begin(), newRoutes.end());
+ // Note: this is a simplistic approach assuming that a mix port can only be populated
+ // from a single device port. Implementing support for stuffing dynamic profiles with a superset
+ // of all profiles from all routable dynamic device ports would be more involved.
+ for (const auto mixPortId : routablePortIds) {
+ auto portsIt = findById<AudioPort>(ports, mixPortId);
+ if (portsIt != ports.end() && portsIt->profiles.empty()) {
+ portsIt->profiles = connectedPort.profiles;
+ connectedPortsIt->second.push_back(portsIt->id);
+ }
+ }
+ *_aidl_return = std::move(connectedPort);
+
return ndk::ScopedAStatus::ok();
}
@@ -504,7 +542,8 @@
LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- if (mConnectedDevicePorts.count(in_portId) == 0) {
+ auto connectedPortsIt = mConnectedDevicePorts.find(in_portId);
+ if (connectedPortsIt == mConnectedDevicePorts.end()) {
LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port";
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
@@ -525,7 +564,6 @@
}
onExternalDeviceConnectionChanged(*portIt, false /*connected*/);
ports.erase(portIt);
- mConnectedDevicePorts.erase(in_portId);
LOG(DEBUG) << __func__ << ": connected device port " << in_portId << " released";
auto& routes = getConfig().routes;
@@ -540,6 +578,14 @@
}
}
+ for (const auto mixPortId : connectedPortsIt->second) {
+ auto mixPortIt = findById<AudioPort>(ports, mixPortId);
+ if (mixPortIt != ports.end()) {
+ mixPortIt->profiles = {};
+ }
+ }
+ mConnectedDevicePorts.erase(connectedPortsIt);
+
return ndk::ScopedAStatus::ok();
}
diff --git a/audio/aidl/default/include/core-impl/Configuration.h b/audio/aidl/default/include/core-impl/Configuration.h
index 4dd0133..70320e4 100644
--- a/audio/aidl/default/include/core-impl/Configuration.h
+++ b/audio/aidl/default/include/core-impl/Configuration.h
@@ -33,7 +33,8 @@
std::vector<::aidl::android::media::audio::common::AudioPort> ports;
std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs;
std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs;
- // Port id -> List of profiles to use when the device port state is set to 'connected'.
+ // Port id -> List of profiles to use when the device port state is set to 'connected'
+ // in connection simulation mode.
std::map<int32_t, std::vector<::aidl::android::media::audio::common::AudioProfile>>
connectedProfiles;
std::vector<AudioRoute> routes;
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 2cbda7d..83ecfaa 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -177,8 +177,10 @@
ChildInterface<IBluetooth> mBluetooth;
ChildInterface<IBluetoothA2dp> mBluetoothA2dp;
ChildInterface<IBluetoothLe> mBluetoothLe;
- // ids of ports created at runtime via 'connectExternalDevice'.
- std::set<int32_t> mConnectedDevicePorts;
+ // ids of device ports created at runtime via 'connectExternalDevice'.
+ // Also stores ids of mix ports with dynamic profiles which got populated from the connected
+ // port.
+ std::map<int32_t, std::vector<int32_t>> mConnectedDevicePorts;
Streams mStreams;
// Maps port ids and port config ids to patch ids.
// Multimap because both ports and configs can be used by multiple patches.
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 18aa6f0..852255d 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -84,6 +84,7 @@
cc_test {
name: "VtsHalDynamicsProcessingTargetTest",
defaults: ["VtsHalAudioTargetTestDefaults"],
+ static_libs: ["libaudioaidlranges"],
srcs: ["VtsHalDynamicsProcessingTest.cpp"],
}
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index b720305..825b865 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -129,7 +129,9 @@
using Tag = AudioDeviceAddress::Tag;
if (std::string_view connection = description.connection;
connection == AudioDeviceDescription::CONNECTION_BT_A2DP ||
- connection == AudioDeviceDescription::CONNECTION_BT_LE ||
+ // Note: BT LE Broadcast uses a "group id".
+ (description.type != AudioDeviceType::OUT_BROADCAST &&
+ connection == AudioDeviceDescription::CONNECTION_BT_LE) ||
connection == AudioDeviceDescription::CONNECTION_BT_SCO ||
connection == AudioDeviceDescription::CONNECTION_WIRELESS) {
return Tag::mac;
@@ -1778,6 +1780,42 @@
}
}
+// Note: This test relies on simulation of external device connections by the HAL module.
+TEST_P(AudioCoreModule, ExternalDeviceMixPortConfigs) {
+ // After an external device has been connected, all mix ports that can be routed
+ // to the device port for the connected device must have non-empty profiles.
+ ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
+ std::vector<AudioPort> externalDevicePorts = moduleConfig->getExternalDevicePorts();
+ if (externalDevicePorts.empty()) {
+ GTEST_SKIP() << "No external devices in the module.";
+ }
+ for (const auto& port : externalDevicePorts) {
+ WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
+ ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
+ std::vector<AudioRoute> routes;
+ ASSERT_IS_OK(module->getAudioRoutesForAudioPort(portConnected.getId(), &routes));
+ std::vector<AudioPort> allPorts;
+ ASSERT_IS_OK(module->getAudioPorts(&allPorts));
+ for (const auto& r : routes) {
+ if (r.sinkPortId == portConnected.getId()) {
+ for (const auto& srcPortId : r.sourcePortIds) {
+ const auto srcPortIt = findById(allPorts, srcPortId);
+ ASSERT_NE(allPorts.end(), srcPortIt) << "port ID " << srcPortId;
+ EXPECT_NE(0UL, srcPortIt->profiles.size())
+ << " source port " << srcPortIt->toString() << " must have its profiles"
+ << " populated following external device connection";
+ }
+ } else {
+ const auto sinkPortIt = findById(allPorts, r.sinkPortId);
+ ASSERT_NE(allPorts.end(), sinkPortIt) << "port ID " << r.sinkPortId;
+ EXPECT_NE(0UL, sinkPortIt->profiles.size())
+ << " source port " << sinkPortIt->toString() << " must have its"
+ << " profiles populated following external device connection";
+ }
+ }
+ }
+}
+
TEST_P(AudioCoreModule, MasterMute) {
bool isSupported = false;
EXPECT_NO_FATAL_FAILURE(TestAccessors<bool>(module.get(), &IModule::getMasterMute,
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml b/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
new file mode 100644
index 0000000..dfc1039
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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 VtsHalAudioCoreTargetTest.">
+ <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 class="com.android.tradefed.targetprep.StopServicesSetup"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="setprop vts.native_server.on 1"/>
+ <option name="teardown-command" value="setprop vts.native_server.on 0"/>
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalAudioCoreTargetTest" />
+ <option name="native-test-timeout" value="10m" />
+ </test>
+</configuration>
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index c62a24e..033e3b5 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -25,8 +25,10 @@
#include <Utils.h>
#include "EffectHelper.h"
+#include "EffectRangeSpecific.h"
using namespace android;
+using namespace aidl::android::hardware::audio::effect::DynamicsProcessingRanges;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::DynamicsProcessing;
@@ -95,6 +97,19 @@
template <typename T>
bool isAidlVectorEqual(const std::vector<T>& source, const std::vector<T>& target);
+ template <typename T>
+ bool isChannelConfigValid(const std::vector<T>& cfgs) {
+ auto& channelCount = mChannelCount;
+ return std::all_of(cfgs.cbegin(), cfgs.cend(), [channelCount](const T& cfg) {
+ return (cfg.channel >= 0 && cfg.channel < channelCount);
+ });
+ }
+
+ template <typename T>
+ bool isBandConfigValid(const std::vector<T>& cfgs, int bandCount);
+
+ bool isParamValid(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dp);
+
// get set params and validate
void SetAndGetDynamicsProcessingParameters();
@@ -133,9 +148,11 @@
static const std::set<DynamicsProcessing::StageEnablement> kStageEnablementTestSet;
static const std::set<std::vector<DynamicsProcessing::InputGain>> kInputGainTestSet;
+ protected:
+ int mChannelCount;
+
private:
int32_t mChannelLayout;
- int mChannelCount;
std::vector<std::pair<DynamicsProcessing::Tag, DynamicsProcessing>> mTags;
void CleanUp() {
mTags.clear();
@@ -152,6 +169,8 @@
{.inUse = true, .bandCount = DynamicsProcessingTestHelper::kBandCount},
{.inUse = true, .bandCount = 0},
{.inUse = true, .bandCount = -1},
+ {.inUse = false, .bandCount = 0},
+ {.inUse = false, .bandCount = -1},
{.inUse = false, .bandCount = DynamicsProcessingTestHelper::kBandCount}};
// test value set for DynamicsProcessing::ChannelConfig
@@ -161,9 +180,7 @@
{.channel = 0, .enable = true},
{.channel = 1, .enable = false},
{.channel = 2, .enable = true}},
-
{{.channel = -1, .enable = false}, {.channel = 2, .enable = true}},
-
{{.channel = 0, .enable = true}, {.channel = 1, .enable = true}}};
// test value set for DynamicsProcessing::InputGain
@@ -172,10 +189,65 @@
{{.channel = 0, .gainDb = 10.f},
{.channel = 1, .gainDb = 0.f},
{.channel = 2, .gainDb = -10.f}},
-
{{.channel = -1, .gainDb = -10.f}, {.channel = -2, .gainDb = 10.f}},
+ {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}},
+ {{.channel = 0, .gainDb = 10.f}, {.channel = 1, .gainDb = -10.f}}};
- {{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}}};
+template <typename T>
+bool DynamicsProcessingTestHelper::isBandConfigValid(const std::vector<T>& cfgs, int bandCount) {
+ std::vector<float> freqs(cfgs.size(), -1);
+ for (auto cfg : cfgs) {
+ if (cfg.channel < 0 || cfg.channel >= mChannelCount) return false;
+ if (cfg.band < 0 || cfg.band >= bandCount) return false;
+ freqs[cfg.band] = cfg.cutoffFrequencyHz;
+ }
+ if (std::count(freqs.begin(), freqs.end(), -1)) return false;
+ return std::is_sorted(freqs.begin(), freqs.end());
+}
+
+bool DynamicsProcessingTestHelper::isParamValid(const DynamicsProcessing::Tag& tag,
+ const DynamicsProcessing& dp) {
+ switch (tag) {
+ case DynamicsProcessing::preEq: {
+ if (!mEngineConfigApplied.preEqStage.inUse) return false;
+ return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>());
+ }
+ case DynamicsProcessing::postEq: {
+ if (!mEngineConfigApplied.postEqStage.inUse) return false;
+ return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>());
+ }
+ case DynamicsProcessing::mbc: {
+ if (!mEngineConfigApplied.mbcStage.inUse) return false;
+ return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>());
+ }
+ case DynamicsProcessing::preEqBand: {
+ if (!mEngineConfigApplied.preEqStage.inUse) return false;
+ return isBandConfigValid(dp.get<DynamicsProcessing::preEqBand>(),
+ mEngineConfigApplied.preEqStage.bandCount);
+ }
+ case DynamicsProcessing::postEqBand: {
+ if (!mEngineConfigApplied.postEqStage.inUse) return false;
+ return isBandConfigValid(dp.get<DynamicsProcessing::postEqBand>(),
+ mEngineConfigApplied.postEqStage.bandCount);
+ }
+ case DynamicsProcessing::mbcBand: {
+ if (!mEngineConfigApplied.mbcStage.inUse) return false;
+ return isBandConfigValid(dp.get<DynamicsProcessing::mbcBand>(),
+ mEngineConfigApplied.mbcStage.bandCount);
+ }
+ case DynamicsProcessing::limiter: {
+ if (!mEngineConfigApplied.limiterInUse) return false;
+ return isChannelConfigValid(dp.get<DynamicsProcessing::limiter>());
+ }
+ case DynamicsProcessing::inputGain: {
+ return isChannelConfigValid(dp.get<DynamicsProcessing::inputGain>());
+ }
+ default: {
+ return true;
+ }
+ }
+ return true;
+}
bool DynamicsProcessingTestHelper::isParamEqual(const DynamicsProcessing::Tag& tag,
const DynamicsProcessing& dpRef,
@@ -270,8 +342,8 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid =
- isParameterValid<DynamicsProcessing, Range::dynamicsProcessing>(dp, desc);
+ bool valid = isParamInRange(dp, desc.capability.range.get<Range::dynamicsProcessing>());
+ if (valid) valid = isParamValid(tag, dp);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -429,10 +501,11 @@
::testing::Combine(
testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
- testing::Values(DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
- DynamicsProcessing::ResolutionPreference::
- FAVOR_FREQUENCY_RESOLUTION), // variant
- testing::Values(-10.f, 0.f, 10.f), // processing duration
+ testing::Values(
+ DynamicsProcessing::ResolutionPreference::FAVOR_TIME_RESOLUTION,
+ DynamicsProcessing::ResolutionPreference::FAVOR_FREQUENCY_RESOLUTION,
+ static_cast<DynamicsProcessing::ResolutionPreference>(-1)), // variant
+ testing::Values(-10.f, 0.f, 10.f), // processing duration
testing::ValuesIn(
DynamicsProcessingTestHelper::kStageEnablementTestSet), // preEQ/postEQ/mbc
testing::Bool()), // limiter enable
@@ -515,12 +588,12 @@
LIMITER_MAX_NUM,
};
using LimiterConfigTestAdditional = std::array<float, LIMITER_MAX_NUM>;
-// attachTime, releaseTime, ratio, thresh, postGain
+// attackTime, releaseTime, ratio, thresh, postGain
static constexpr std::array<LimiterConfigTestAdditional, 4> kLimiterConfigTestAdditionalParam = {
{{-1, -60, -2.5, -2, -3.14},
{-1, 60, -2.5, 2, -3.14},
{1, -60, 2.5, -2, 3.14},
- {1, 60, 2.5, 2, 3.14}}};
+ {1, 60, 2.5, -2, 3.14}}};
using LimiterConfigTestParams =
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool, int32_t, bool,
@@ -669,15 +742,13 @@
enum EqBandConfigTestParamName {
EQ_BAND_INSTANCE_NAME,
EQ_BAND_CHANNEL,
- EQ_BAND_CHANNEL_ENABLE,
EQ_BAND_ENABLE,
EQ_BAND_CUT_OFF_FREQ,
EQ_BAND_GAIN,
EQ_BAND_STAGE_IN_USE
};
using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
- std::vector<DynamicsProcessing::ChannelConfig>, bool,
- std::vector<std::pair<int, float>>, float, bool>;
+ bool, std::vector<std::pair<int, float>>, float, bool>;
void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
const EqBandConfigTestParams& params) {
@@ -698,8 +769,7 @@
public:
DynamicsProcessingTestEqBandConfig()
: DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())),
- mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())),
- mChannelConfig(std::get<EQ_BAND_CHANNEL_ENABLE>(GetParam())) {
+ mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())) {
fillEqBandConfig(mCfgs, GetParam());
}
@@ -709,14 +779,18 @@
std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
const bool mStageInUse;
- const std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
};
TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
mEngineConfigPreset.preEqStage.inUse = mStageInUse;
mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
- EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mChannelConfig));
+ std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+ for (int i = 0; i < mChannelCount; i++) {
+ cfgs[i].channel = i;
+ cfgs[i].enable = true;
+ }
+ EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(cfgs));
EXPECT_NO_FATAL_FAILURE(addPreEqBandConfigs(mCfgs));
SetAndGetDynamicsProcessingParameters();
}
@@ -725,7 +799,12 @@
mEngineConfigPreset.postEqStage.inUse = mStageInUse;
mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
- EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mChannelConfig));
+ std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+ for (int i = 0; i < mChannelCount; i++) {
+ cfgs[i].channel = i;
+ cfgs[i].enable = true;
+ }
+ EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(cfgs));
EXPECT_NO_FATAL_FAILURE(addPostEqBandConfigs(mCfgs));
SetAndGetDynamicsProcessingParameters();
}
@@ -776,28 +855,23 @@
INSTANTIATE_TEST_SUITE_P(
DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
- ::testing::Combine(
- testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
- testing::Values(-1, 0, 10), // channel ID
- testing::ValuesIn(
- DynamicsProcessingTestHelper::kChannelConfigTestSet), // channel enable
- testing::Bool(), // band enable
- testing::ValuesIn(kBands), // cut off frequencies
- testing::Values(-3.14f, 3.14f), // gain
- testing::Bool()), // stage in use
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+ testing::Values(-1, 0, 10), // channel ID
+ testing::Bool(), // band enable
+ testing::ValuesIn(kBands), // cut off frequencies
+ testing::Values(-3.14f, 3.14f), // gain
+ testing::Values(true)), // stage in use
[](const auto& info) {
auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
std::vector<DynamicsProcessing::EqBandConfig> cfgs;
fillEqBandConfig(cfgs, info.param);
- std::string enable =
- ::android::internal::ToString(std::get<EQ_BAND_CHANNEL_ENABLE>(info.param));
std::string bands = ::android::internal::ToString(cfgs);
std::string stageInUse = std::to_string(std::get<EQ_BAND_STAGE_IN_USE>(info.param));
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
descriptor.common.name + "_UUID_" +
- descriptor.common.id.uuid.toString() + "_" + enable + "_bands_" +
- bands + "_stageInUse_" + stageInUse;
+ descriptor.common.id.uuid.toString() + "_bands_" + bands +
+ "_stageInUse_" + stageInUse;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
@@ -811,7 +885,6 @@
enum MbcBandConfigParamName {
MBC_BAND_INSTANCE_NAME,
MBC_BAND_CHANNEL,
- MBC_BAND_CHANNEL_CONFIG,
MBC_BAND_ENABLE,
MBC_BAND_CUTOFF_FREQ,
MBC_BAND_STAGE_IN_USE,
@@ -831,16 +904,15 @@
};
using TestParamsMbcBandConfigAdditional = std::array<float, MBC_ADD_MAX_NUM>;
-// attachTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
+// attackTime, releaseTime, ratio, thresh, kneeWidth, noise, expander, preGain, postGain
static constexpr std::array<TestParamsMbcBandConfigAdditional, 4> kMbcBandConfigAdditionalParam = {
{{-3, -10, -2, -2, -5, -90, -2.5, -2, -2},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{-3, 10, -2, 2, -5, 90, -2.5, 2, -2},
- {3, 10, 2, 2, 5, 90, 2.5, 2, 2}}};
+ {3, 10, 2, -2, -5, 90, 2.5, 2, 2}}};
using TestParamsMbcBandConfig =
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
- std::vector<DynamicsProcessing::ChannelConfig>, bool,
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool,
std::vector<std::pair<int, float>>, bool, TestParamsMbcBandConfigAdditional>;
void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
@@ -873,8 +945,7 @@
public:
DynamicsProcessingTestMbcBandConfig()
: DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())),
- mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())),
- mChannelConfig(std::get<MBC_BAND_CHANNEL_CONFIG>(GetParam())) {
+ mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())) {
fillMbcBandConfig(mCfgs, GetParam());
}
@@ -884,42 +955,41 @@
std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
const bool mStageInUse;
- const std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
};
TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
mEngineConfigPreset.mbcStage.inUse = mStageInUse;
mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
- EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mChannelConfig));
+ std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
+ for (int i = 0; i < mChannelCount; i++) {
+ cfgs[i].channel = i;
+ cfgs[i].enable = true;
+ }
+ EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(cfgs));
EXPECT_NO_FATAL_FAILURE(addMbcBandConfigs(mCfgs));
SetAndGetDynamicsProcessingParameters();
}
INSTANTIATE_TEST_SUITE_P(
DynamicsProcessingTest, DynamicsProcessingTestMbcBandConfig,
- ::testing::Combine(
- testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
- testing::Values(-1, 0, 10), // channel count
- testing::ValuesIn(
- DynamicsProcessingTestHelper::kChannelConfigTestSet), // channel config
- testing::Bool(), // enable
- testing::ValuesIn(kBands), // cut off frequencies
- testing::Bool(), // stage in use
- testing::ValuesIn(kMbcBandConfigAdditionalParam)), // Additional
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+ testing::Values(-1, 0, 10), // channel count
+ testing::Bool(), // enable
+ testing::ValuesIn(kBands), // cut off frequencies
+ testing::Bool(), // stage in use
+ testing::ValuesIn(kMbcBandConfigAdditionalParam)), // Additional
[](const auto& info) {
auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
fillMbcBandConfig(cfgs, info.param);
- std::string enable =
- ::android::internal::ToString(std::get<MBC_BAND_CHANNEL_CONFIG>(info.param));
std::string mbcBands = ::android::internal::ToString(cfgs);
std::string stageInUse = std::to_string(std::get<MBC_BAND_STAGE_IN_USE>(info.param));
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
descriptor.common.name + "_UUID_" +
- descriptor.common.id.uuid.toString() + "_enable_" + enable +
- "_bands_" + mbcBands + "_stageInUse_" + stageInUse;
+ descriptor.common.id.uuid.toString() + "_bands_" + mbcBands +
+ "_stageInUse_" + stageInUse;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
index 78f5b52..4308d52 100644
--- a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
@@ -48,5 +48,13 @@
"android-media-fuzzing-reports@google.com",
],
componentid: 533764,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of android.hardware.automotive.audiocontrol@1.0-service binary",
+ vector: "local_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/automotive/can/1.0/default/tests/fuzzer/Android.bp b/automotive/can/1.0/default/tests/fuzzer/Android.bp
index 52b43b0..de0b96f 100644
--- a/automotive/can/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/can/1.0/default/tests/fuzzer/Android.bp
@@ -50,5 +50,13 @@
"android-media-fuzzing-reports@google.com",
],
componentid: 533764,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of android.hardware.automotive.can@1.0-service",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/automotive/evs/aidl/impl/Android.bp b/automotive/evs/aidl/impl/Android.bp
index 0b51a0c..fa44ebb 100644
--- a/automotive/evs/aidl/impl/Android.bp
+++ b/automotive/evs/aidl/impl/Android.bp
@@ -22,7 +22,7 @@
name: "EvsHalDefaults",
defaults: ["android.hardware.graphics.common-ndk_static"],
static_libs: [
- "android.hardware.automotive.evs-V1-ndk",
+ "android.hardware.automotive.evs-V2-ndk",
"android.hardware.common-V2-ndk",
],
shared_libs: [
diff --git a/automotive/evs/aidl/impl/default/Android.bp b/automotive/evs/aidl/impl/default/Android.bp
index bf6c0be..70c523b 100644
--- a/automotive/evs/aidl/impl/default/Android.bp
+++ b/automotive/evs/aidl/impl/default/Android.bp
@@ -38,7 +38,7 @@
],
srcs: [
":libgui_frame_event_aidl",
- "src/*.cpp"
+ "src/*.cpp",
],
shared_libs: [
"android.hardware.graphics.bufferqueue@1.0",
@@ -61,7 +61,7 @@
],
static_libs: [
"android.frameworks.automotive.display-V1-ndk",
- "android.hardware.automotive.evs-V1-ndk",
+ "android.hardware.automotive.evs-V2-ndk",
"android.hardware.common-V2-ndk",
"libaidlcommonsupport",
"libcutils",
diff --git a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
index b11dd3e..259c266 100644
--- a/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
+++ b/automotive/evs/aidl/impl/default/include/EvsEnumerator.h
@@ -52,6 +52,7 @@
ndk::ScopedAStatus closeDisplay(const std::shared_ptr<evs::IEvsDisplay>& obj) override;
ndk::ScopedAStatus getDisplayIdList(std::vector<uint8_t>* list) override;
ndk::ScopedAStatus getDisplayState(evs::DisplayState* state) override;
+ ndk::ScopedAStatus getDisplayStateById(int32_t displayId, evs::DisplayState* state) override;
ndk::ScopedAStatus registerStatusCallback(
const std::shared_ptr<evs::IEvsEnumeratorStatusCallback>& callback) override;
ndk::ScopedAStatus openUltrasonicsArray(
@@ -101,6 +102,8 @@
bool checkPermission();
void closeCamera_impl(const std::shared_ptr<evs::IEvsCamera>& pCamera,
const std::string& cameraId);
+ ndk::ScopedAStatus getDisplayStateImpl(std::optional<int32_t> displayId,
+ evs::DisplayState* state);
static bool qualifyCaptureDevice(const char* deviceName);
static CameraRecord* findCameraById(const std::string& cameraId);
diff --git a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
index 6e2405d..5178958 100644
--- a/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsEnumerator.cpp
@@ -357,24 +357,32 @@
ScopedAStatus EvsEnumerator::getDisplayState(DisplayState* state) {
LOG(DEBUG) << __FUNCTION__;
+ return getDisplayStateImpl(std::nullopt, state);
+}
+
+ScopedAStatus EvsEnumerator::getDisplayStateById(int32_t displayId, DisplayState* state) {
+ LOG(DEBUG) << __FUNCTION__;
+ return getDisplayStateImpl(displayId, state);
+}
+
+ScopedAStatus EvsEnumerator::getDisplayStateImpl(std::optional<int32_t> displayId,
+ DisplayState* state) {
if (!checkPermission()) {
*state = DisplayState::DEAD;
return ScopedAStatus::fromServiceSpecificError(
static_cast<int>(EvsResult::PERMISSION_DENIED));
}
- // TODO(b/262779341): For now we can just return the state of the 1st display. Need to update
- // the API later.
-
const auto& all_displays = mutableActiveDisplays().getAllDisplays();
- // Do we still have a display object we think should be active?
- if (all_displays.empty()) {
+ const auto display_search = displayId ? all_displays.find(*displayId) : all_displays.begin();
+
+ if (display_search == all_displays.end()) {
*state = DisplayState::NOT_OPEN;
return ScopedAStatus::fromServiceSpecificError(static_cast<int>(EvsResult::OWNERSHIP_LOST));
}
- std::shared_ptr<IEvsDisplay> pActiveDisplay = all_displays.begin()->second.displayWeak.lock();
+ std::shared_ptr<IEvsDisplay> pActiveDisplay = display_search->second.displayWeak.lock();
if (pActiveDisplay) {
return pActiveDisplay->getDisplayState(state);
} else {
diff --git a/automotive/evs/aidl/vts/Android.bp b/automotive/evs/aidl/vts/Android.bp
index 5aa9501..e50c913 100644
--- a/automotive/evs/aidl/vts/Android.bp
+++ b/automotive/evs/aidl/vts/Android.bp
@@ -14,18 +14,17 @@
// limitations under the License.
//
-package{
+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"],
+ default_applicable_licenses: ["hardware_interfaces_license"],
}
cc_test {
-name:
- "VtsHalEvsTargetTest",
+ name: "VtsHalEvsTargetTest",
srcs: [
"*.cpp",
],
@@ -42,7 +41,7 @@
],
static_libs: [
"android.hardware.automotive.evs@common-default-lib",
- "android.hardware.automotive.evs-V1-ndk",
+ "android.hardware.automotive.evs-V2-ndk",
"android.hardware.common-V2-ndk",
"libaidlcommonsupport",
],
diff --git a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
index 2706c49..a6d99ad 100644
--- a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
+++ b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
@@ -51,6 +51,7 @@
#include <ui/GraphicBufferAllocator.h>
#include <utils/Timers.h>
+#include <chrono>
#include <deque>
#include <thread>
#include <unordered_set>
@@ -2197,6 +2198,203 @@
}
}
+/*
+ * DisplayOpen:
+ * Test both clean shut down and "aggressive open" device stealing behavior.
+ */
+TEST_P(EvsAidlTest, DisplayOpen) {
+ LOG(INFO) << "Starting DisplayOpen test";
+
+ // Request available display IDs.
+ std::vector<uint8_t> displayIds;
+ ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
+ EXPECT_GT(displayIds.size(), 0);
+
+ for (const auto displayId : displayIds) {
+ std::shared_ptr<IEvsDisplay> pDisplay;
+
+ // Request exclusive access to each EVS display, then let it go.
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+
+ {
+ // Ask the display what its name is.
+ DisplayDesc desc;
+ ASSERT_TRUE(pDisplay->getDisplayInfo(&desc).isOk());
+ LOG(DEBUG) << "Found display " << desc.id;
+ }
+
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+
+ // Ensure we can reopen the display after it has been closed.
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+
+ // Open the display while its already open -- ownership should be transferred.
+ std::shared_ptr<IEvsDisplay> pDisplay2;
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay2).isOk());
+ ASSERT_NE(pDisplay2, nullptr);
+
+ {
+ // Ensure the old display properly reports its assassination.
+ DisplayState badState;
+ EXPECT_TRUE(pDisplay->getDisplayState(&badState).isOk());
+ EXPECT_EQ(badState, DisplayState::DEAD);
+ }
+
+ // Close only the newest display instance -- the other should already be a zombie.
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay2).isOk());
+
+ // Finally, validate that we can open the display after the provoked failure above.
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+ ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
+ }
+}
+
+/*
+ * DisplayStates:
+ * Validate that display states transition as expected and can be queried from either the display
+ * object itself or the owning enumerator.
+ */
+TEST_P(EvsAidlTest, DisplayStates) {
+ using std::literals::chrono_literals::operator""ms;
+
+ LOG(INFO) << "Starting DisplayStates test";
+
+ // Request available display IDs.
+ std::vector<uint8_t> displayIds;
+ ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
+ EXPECT_GT(displayIds.size(), 0);
+
+ for (const auto displayId : displayIds) {
+ // Ensure the display starts in the expected state.
+ {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+
+ // Scope to limit the lifetime of the pDisplay pointer, and thus the IEvsDisplay object.
+ {
+ // Request exclusive access to the EVS display.
+ std::shared_ptr<IEvsDisplay> pDisplay;
+ ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
+ ASSERT_NE(pDisplay, nullptr);
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Activate the display.
+ EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+ }
+ {
+ DisplayState state;
+ EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Get the output buffer we'd use to display the imagery.
+ BufferDesc tgtBuffer;
+ ASSERT_TRUE(pDisplay->getTargetBuffer(&tgtBuffer).isOk());
+
+ // Send the target buffer back for display (we didn't actually fill anything).
+ EXPECT_TRUE(pDisplay->returnTargetBufferForDisplay(tgtBuffer).isOk());
+
+ // Sleep for a tenth of a second to ensure the driver has time to get the image
+ // displayed.
+ std::this_thread::sleep_for(100ms);
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE);
+ }
+ {
+ DisplayState state;
+ EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::VISIBLE);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Turn off the display.
+ EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());
+ std::this_thread::sleep_for(100ms);
+ {
+ DisplayState state;
+ EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ }
+ {
+ DisplayState state;
+ EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ if (displayIdToQuery == displayId) {
+ EXPECT_TRUE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
+ } else {
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+
+ // Close the display.
+ mEnumerator->closeDisplay(pDisplay);
+ }
+
+ // Now that the display pointer has gone out of scope, causing the IEvsDisplay interface
+ // object to be destroyed, we should be back to the "not open" state.
+ // NOTE: If we want this to pass without the sleep above, we'd have to add the
+ // (now recommended) closeDisplay() call instead of relying on the smarter pointer
+ // going out of scope. I've not done that because I want to verify that the deletion
+ // of the object does actually clean up (eventually).
+ {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
+ }
+ for (const auto displayIdToQuery : displayIds) {
+ DisplayState state;
+ EXPECT_FALSE(mEnumerator->getDisplayStateById(displayIdToQuery, &state).isOk());
+ }
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EvsAidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, EvsAidlTest,
diff --git a/automotive/sv/1.0/default/tests/fuzzer/Android.bp b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
index 394c532..696bfad 100644
--- a/automotive/sv/1.0/default/tests/fuzzer/Android.bp
+++ b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
@@ -47,5 +47,13 @@
"android-media-fuzzing-reports@google.com",
],
componentid: 533764,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of android.hardware.automotive.sv@1.0-service",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 33e211c..586a98e 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -292,5 +292,13 @@
"android-media-fuzzing-reports@google.com",
],
componentid: 533764,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of android.hardware.automotive.vehicle@2.0-manager-lib",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index d75b046..5b0a505 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -57,46 +57,25 @@
};
/**
- * Vehicle Areas
+ * List of different supported area types for vehicle properties.
* Used to construct property IDs in the VehicleProperty enum.
*
- * Some properties may be associated with particular vehicle areas. For
- * example, VehicleProperty:DOOR_LOCK property must be associated with
- * particular door, thus this property must be marked with
- * VehicleArea:DOOR flag.
+ * Some properties may be associated with particular areas in the vehicle. For example,
+ * VehicleProperty#DOOR_LOCK property must be associated with a particular door, thus this property
+ * must be of the VehicleArea#DOOR area type.
*
- * Other properties may not be associated with particular vehicle area.
- * These kinds of properties must have VehicleArea:GLOBAL flag.
+ * Other properties may not be associated with a particular area in the vehicle. These kinds of
+ * properties must be of the VehicleArea#GLOBAL area type.
*
- * [Definition] Area: An area represents a unique element of an AreaType.
- * For instance, if AreaType is WINDOW, then an area may be FRONT_WINDSHIELD.
- *
- * [Definition] AreaID: An AreaID is a combination of one or more areas,
- * and is represented using a bitmask of Area enums. Different AreaTypes may
- * not be mixed in a single AreaID. For instance, a window area cannot be
- * combined with a seat area in an AreaID.
- *
- * Rules for mapping a zoned property to AreaIDs:
- * - A property must be mapped to an array of AreaIDs that are impacted when
- * the property value changes.
- * - Each element in the array must represent an AreaID, in which the
- * property value can only be changed together in all the areas within
- * the AreaID and never independently. That is, when the property value
- * changes in one of the areas in an AreaID in the array, then it must
- * automatically change in all other areas in the AreaID.
- * - The property value must be independently controllable in any two
- * different AreaIDs in the array.
- * - An area must only appear once in the array of AreaIDs. That is, an
- * area must only be part of a single AreaID in the array.
- *
- * [Definition] Global Property: A property that applies to the entire car
- * and is not associated with a specific area. For example, FUEL_LEVEL,
- * HVAC_STEERING_WHEEL_HEAT.
- *
- * Rules for mapping a global property to AreaIDs:
- * - A global property must not be mapped to AreaIDs.
-*/
+ * Note: This is not the same as areaId used in VehicleAreaConfig. E.g. for a global property, the
+ * property ID is of the VehicleArea#GLOBAL area type, however, the area ID must be 0.
+ */
+// A better name would be VehicleAreaType
enum VehicleArea : int32_t {
+ /**
+ * A global property is a property that applies to the entire vehicle and is not associated with
+ * a specific area. For example, FUEL_LEVEL, HVAC_STEERING_WHEEL_HEAT are global properties.
+ */
GLOBAL = 0x01000000,
/** WINDOW maps to enum VehicleAreaWindow */
WINDOW = 0x03000000,
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index abd9540..20c046d 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -20,7 +20,7 @@
@JavaDerive(equals=true, toString=true)
parcelable VehicleAreaConfig {
/**
- * Area id is ignored for VehiclePropertyGroup:GLOBAL properties.
+ * Area id is always 0 for VehicleArea#GLOBAL properties.
*/
int areaId;
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 1b48f0b..61b9369 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -37,7 +37,25 @@
VehiclePropertyChangeMode changeMode = VehiclePropertyChangeMode.STATIC;
/**
- * Contains per-area configuration.
+ * Contains per-areaId configuration.
+ *
+ * [Definition] area: An area represents a unique element of a VehicleArea. For instance, if the
+ * VehicleArea is WINDOW, then an example area is FRONT_WINDSHIELD.
+ *
+ * [Definition] area ID: An area ID is a combination of one or more areas, and is created by
+ * bitwise "OR"ing the areas together. Areas from different VehicleArea values may not be
+ * mixed in a single area ID. For example, a VehicleAreaWindow area cannot be combined with a
+ * VehicleAreaSeat area in an area ID.
+ *
+ * For VehicleArea#GLOBAL properties, they must map only to a single area ID of 0.
+ *
+ * Rules for mapping a non VehicleArea#GLOBAL property to area IDs:
+ * - A property must be mapped to a set of area IDs that are impacted when the property value
+ * changes.
+ * - An area cannot be part of multiple area IDs, it must only be part of a single area ID.
+ * - When the property value changes in one of the areas in an area ID, then it must
+ * automatically change in all other areas in the area ID.
+ * - The property value must be independently controllable in any two different area IDs.
*/
VehicleAreaConfig[] areaConfigs;
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
index dab0349..6f7f783 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -16,9 +16,28 @@
package android.hardware.automotive.vehicle;
+/**
+ * List of different supported area types for vehicle properties.
+ * Used to construct property IDs in the VehicleProperty enum.
+ *
+ * Some properties may be associated with particular areas in the vehicle. For example,
+ * VehicleProperty#DOOR_LOCK property must be associated with a particular door, thus this property
+ * must be of the VehicleArea#DOOR area type.
+ *
+ * Other properties may not be associated with a particular area in the vehicle. These kinds of
+ * properties must be of the VehicleArea#GLOBAL area type.
+ *
+ * Note: This is not the same as areaId used in VehicleAreaConfig. E.g. for a global property, the
+ * property ID is of the VehicleArea#GLOBAL area type, however, the area ID must be 0.
+ */
@VintfStability
@Backing(type="int")
+// A better name would be VehicleAreaType
enum VehicleArea {
+ /**
+ * A global property is a property that applies to the entire vehicle and is not associated with
+ * a specific area. For example, FUEL_LEVEL, HVAC_STEERING_WHEEL_HEAT are global properties.
+ */
GLOBAL = 0x01000000,
/** WINDOW maps to enum VehicleAreaWindow */
WINDOW = 0x03000000,
diff --git a/bluetooth/aidl/TEST_MAPPING b/bluetooth/aidl/TEST_MAPPING
index 342a1e4..f059c04 100644
--- a/bluetooth/aidl/TEST_MAPPING
+++ b/bluetooth/aidl/TEST_MAPPING
@@ -1,7 +1,13 @@
{
"presubmit" : [
{
- "name" : "VtsHalBluetoothTargetTest"
+ "name" : "VtsHalBluetoothTargetTest",
+ "options": [
+ {
+ // TODO(b/275847929)
+ "exclude-filter": "VtsHalBluetoothTargetTest.PerInstance/BluetoothAidlTest#Cdd_C_12_1_Bluetooth5Requirements/0_android_hardware_bluetooth_IBluetoothHci_default"
+ }
+ ]
}
]
}
diff --git a/bluetooth/aidl/vts/Android.bp b/bluetooth/aidl/vts/Android.bp
index 414f707..5fc0b2e 100644
--- a/bluetooth/aidl/vts/Android.bp
+++ b/bluetooth/aidl/vts/Android.bp
@@ -13,7 +13,17 @@
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
- srcs: ["VtsHalBluetoothTargetTest.cpp"],
+ srcs: [
+ "VtsHalBluetoothTargetTest.cpp",
+ ":BluetoothPacketSources",
+ ":BluetoothHciPacketSources",
+ ],
+ generated_headers: [
+ "BluetoothGeneratedPackets_h",
+ ],
+ include_dirs: [
+ "packages/modules/Bluetooth/system/gd",
+ ],
shared_libs: [
"libbase",
"libbinder_ndk",
@@ -45,4 +55,8 @@
tidy_flags: [
"--header-filter=^.*tools\\/rootcanal\\/(model|include|net|desktop)\\/(.(?!\\.pb\\.h))*$",
],
+ tidy_disabled_srcs: [
+ ":BluetoothPacketSources",
+ ":BluetoothHciPacketSources",
+ ],
}
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 3704c3d..529e092 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -24,27 +24,50 @@
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <future>
-#include <mutex>
#include <queue>
#include <thread>
+#include <utility>
#include <vector>
+// TODO: Remove custom logging defines from PDL packets.
+#undef LOG_INFO
+#undef LOG_DEBUG
+#undef LOG_TAG
+#define LOG_TAG "VtsHalBluetooth"
+#include "hci/hci_packets.h"
+#include "packet/raw_builder.h"
+
using aidl::android::hardware::bluetooth::IBluetoothHci;
using aidl::android::hardware::bluetooth::IBluetoothHciCallbacks;
using aidl::android::hardware::bluetooth::Status;
using ndk::ScopedAStatus;
using ndk::SpAIBinder;
-// Bluetooth Core Specification 3.0 + HS
-static constexpr uint8_t kHciMinimumHciVersion = 5;
-// Bluetooth Core Specification 3.0 + HS
-static constexpr uint8_t kHciMinimumLmpVersion = 5;
+using ::bluetooth::hci::CommandBuilder;
+using ::bluetooth::hci::CommandCompleteView;
+using ::bluetooth::hci::CommandView;
+using ::bluetooth::hci::ErrorCode;
+using ::bluetooth::hci::EventView;
+using ::bluetooth::hci::LeReadLocalSupportedFeaturesBuilder;
+using ::bluetooth::hci::LeReadLocalSupportedFeaturesCompleteView;
+using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsBuilder;
+using ::bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteView;
+using ::bluetooth::hci::LeReadResolvingListSizeBuilder;
+using ::bluetooth::hci::LeReadResolvingListSizeCompleteView;
+using ::bluetooth::hci::LLFeaturesBits;
+using ::bluetooth::hci::OpCode;
+using ::bluetooth::hci::OpCodeText;
+using ::bluetooth::hci::PacketView;
+using ::bluetooth::hci::ReadLocalVersionInformationBuilder;
+using ::bluetooth::hci::ReadLocalVersionInformationCompleteView;
+
+static constexpr uint8_t kMinLeAdvSetForBt5 = 16;
+static constexpr uint8_t kMinLeResolvingListForBt5 = 8;
static constexpr size_t kNumHciCommandsBandwidth = 100;
static constexpr size_t kNumScoPacketsBandwidth = 100;
@@ -55,65 +78,14 @@
static constexpr std::chrono::milliseconds kWaitForAclDataTimeout(1000);
static constexpr std::chrono::milliseconds kInterfaceCloseDelayMs(200);
-static constexpr uint8_t kCommandHciShouldBeUnknown[] = {
- 0xff, 0x3B, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
-static constexpr uint8_t kCommandHciReadLocalVersionInformation[] = {0x01, 0x10,
- 0x00};
-static constexpr uint8_t kCommandHciReadBufferSize[] = {0x05, 0x10, 0x00};
-static constexpr uint8_t kCommandHciWriteLoopbackModeLocal[] = {0x02, 0x18,
- 0x01, 0x01};
-static constexpr uint8_t kCommandHciReset[] = {0x03, 0x0c, 0x00};
-static constexpr uint8_t kCommandHciSynchronousFlowControlEnable[] = {
- 0x2f, 0x0c, 0x01, 0x01};
-static constexpr uint8_t kCommandHciWriteLocalName[] = {0x13, 0x0c, 0xf8};
-static constexpr uint8_t kHciStatusSuccess = 0x00;
-static constexpr uint8_t kHciStatusUnknownHciCommand = 0x01;
-
-static constexpr uint8_t kEventConnectionComplete = 0x03;
-static constexpr uint8_t kEventCommandComplete = 0x0e;
-static constexpr uint8_t kEventCommandStatus = 0x0f;
-static constexpr uint8_t kEventNumberOfCompletedPackets = 0x13;
-static constexpr uint8_t kEventLoopbackCommand = 0x19;
-
-static constexpr size_t kEventCodeByte = 0;
-static constexpr size_t kEventLengthByte = 1;
-static constexpr size_t kEventFirstPayloadByte = 2;
-static constexpr size_t kEventCommandStatusStatusByte = 2;
-static constexpr size_t kEventCommandStatusOpcodeLsByte = 4; // Bytes 4 and 5
-static constexpr size_t kEventCommandCompleteOpcodeLsByte = 3; // Bytes 3 and 4
-static constexpr size_t kEventCommandCompleteStatusByte = 5;
-static constexpr size_t kEventCommandCompleteFirstParamByte = 6;
-static constexpr size_t kEventLocalHciVersionByte =
- kEventCommandCompleteFirstParamByte;
-static constexpr size_t kEventLocalLmpVersionByte =
- kEventLocalHciVersionByte + 3;
-
-static constexpr size_t kEventConnectionCompleteParamLength = 11;
-static constexpr size_t kEventConnectionCompleteType = 11;
-static constexpr size_t kEventConnectionCompleteTypeSco = 0;
-static constexpr size_t kEventConnectionCompleteTypeAcl = 1;
-static constexpr size_t kEventConnectionCompleteHandleLsByte = 3;
-
-static constexpr size_t kEventNumberOfCompletedPacketsNumHandles = 2;
-
-static constexpr size_t kAclBroadcastFlagOffset = 6;
-static constexpr uint8_t kAclBroadcastFlagPointToPoint = 0x0;
-static constexpr uint8_t kAclBroadcastPointToPoint =
- (kAclBroadcastFlagPointToPoint << kAclBroadcastFlagOffset);
-
-static constexpr uint8_t kAclPacketBoundaryFlagOffset = 4;
-static constexpr uint8_t kAclPacketBoundaryFlagFirstAutoFlushable = 0x2;
-static constexpr uint8_t kAclPacketBoundaryFirstAutoFlushable =
- kAclPacketBoundaryFlagFirstAutoFlushable << kAclPacketBoundaryFlagOffset;
-
// To discard Qualcomm ACL debugging
static constexpr uint16_t kAclHandleQcaDebugMessage = 0xedc;
class ThroughputLogger {
public:
- ThroughputLogger(std::string task)
+ explicit ThroughputLogger(std::string task)
: total_bytes_(0),
- task_(task),
+ task_(std::move(task)),
start_time_(std::chrono::steady_clock::now()) {}
~ThroughputLogger() {
@@ -142,7 +114,7 @@
// The main test class for Bluetooth HAL.
class BluetoothAidlTest : public ::testing::TestWithParam<std::string> {
public:
- virtual void SetUp() override {
+ void SetUp() override {
// currently test passthrough mode only
hci = IBluetoothHci::fromBinder(
SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
@@ -158,7 +130,7 @@
ASSERT_NE(bluetooth_hci_death_recipient, nullptr);
ASSERT_EQ(STATUS_OK,
AIBinder_linkToDeath(hci->asBinder().get(),
- bluetooth_hci_death_recipient, 0));
+ bluetooth_hci_death_recipient, nullptr));
hci_cb = ndk::SharedRefBase::make<BluetoothHciCallbacks>(*this);
ASSERT_NE(hci_cb, nullptr);
@@ -179,7 +151,7 @@
ASSERT_TRUE(future.get());
}
- virtual void TearDown() override {
+ void TearDown() override {
ALOGI("TearDown");
// Should not be checked in production code
ASSERT_TRUE(hci->close().isOk());
@@ -205,8 +177,14 @@
void handle_no_ops();
void discard_qca_debugging();
void wait_for_event(bool timeout_is_error);
- void wait_for_command_complete_event(std::vector<uint8_t> cmd);
+ void wait_for_command_complete_event(OpCode opCode,
+ std::vector<uint8_t>& complete_event);
+ // Wait until a command complete is received.
+ // Command complete will be consumed after this method
+ void wait_and_validate_command_complete_event(OpCode opCode);
int wait_for_completed_packets_event(uint16_t handle);
+ void send_and_wait_for_cmd_complete(std::unique_ptr<CommandBuilder> cmd,
+ std::vector<uint8_t>& cmd_complete);
// A simple test implementation of BluetoothHciCallbacks.
class BluetoothHciCallbacks
@@ -214,36 +192,41 @@
BluetoothAidlTest& parent_;
public:
- BluetoothHciCallbacks(BluetoothAidlTest& parent) : parent_(parent){};
+ explicit BluetoothHciCallbacks(BluetoothAidlTest& parent)
+ : parent_(parent){};
- virtual ~BluetoothHciCallbacks() = default;
+ ~BluetoothHciCallbacks() override = default;
- ndk::ScopedAStatus initializationComplete(Status status) {
+ ndk::ScopedAStatus initializationComplete(Status status) override {
parent_.initialized_promise.set_value(status == Status::SUCCESS);
ALOGV("%s (status = %d)", __func__, static_cast<int>(status));
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& event) {
+ ndk::ScopedAStatus hciEventReceived(
+ const std::vector<uint8_t>& event) override {
parent_.event_cb_count++;
parent_.event_queue.push(event);
- ALOGV("Event received (length = %d)", static_cast<int>(event.size()));
+ ALOGI("Event received (length = %d)", static_cast<int>(event.size()));
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& data) {
+ ndk::ScopedAStatus aclDataReceived(
+ const std::vector<uint8_t>& data) override {
parent_.acl_cb_count++;
parent_.acl_queue.push(data);
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& data) {
+ ndk::ScopedAStatus scoDataReceived(
+ const std::vector<uint8_t>& data) override {
parent_.sco_cb_count++;
parent_.sco_queue.push(data);
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& data) {
+ ndk::ScopedAStatus isoDataReceived(
+ const std::vector<uint8_t>& data) override {
parent_.iso_cb_count++;
parent_.iso_queue.push(data);
return ScopedAStatus::ok();
@@ -253,7 +236,8 @@
template <class T>
class WaitQueue {
public:
- WaitQueue(){};
+ WaitQueue() = default;
+ ;
virtual ~WaitQueue() = default;
@@ -283,6 +267,14 @@
return true;
};
+ void pop() {
+ std::lock_guard<std::mutex> lock(m_);
+ if (q_.empty()) {
+ return;
+ }
+ q_.pop();
+ };
+
bool front(T& v) {
std::lock_guard<std::mutex> lock(m_);
if (q_.empty()) {
@@ -329,22 +321,22 @@
std::shared_ptr<IBluetoothHci> hci;
std::shared_ptr<BluetoothHciCallbacks> hci_cb;
- AIBinder_DeathRecipient* bluetooth_hci_death_recipient;
+ AIBinder_DeathRecipient* bluetooth_hci_death_recipient{};
WaitQueue<std::vector<uint8_t>> event_queue;
WaitQueue<std::vector<uint8_t>> acl_queue;
WaitQueue<std::vector<uint8_t>> sco_queue;
WaitQueue<std::vector<uint8_t>> iso_queue;
std::promise<bool> initialized_promise;
- int event_cb_count;
- int sco_cb_count;
- int acl_cb_count;
- int iso_cb_count;
+ int event_cb_count{};
+ int sco_cb_count{};
+ int acl_cb_count{};
+ int iso_cb_count{};
- int max_acl_data_packet_length;
- int max_sco_data_packet_length;
- int max_acl_data_packets;
- int max_sco_data_packets;
+ int max_acl_data_packet_length{};
+ int max_sco_data_packet_length{};
+ int max_acl_data_packets{};
+ int max_sco_data_packets{};
std::vector<uint16_t> sco_connection_handles;
std::vector<uint16_t> acl_connection_handles;
@@ -355,17 +347,20 @@
while (!event_queue.empty()) {
std::vector<uint8_t> event;
event_queue.front(event);
- ASSERT_GE(event.size(),
- static_cast<size_t>(kEventCommandCompleteStatusByte));
- bool event_is_no_op =
- (event[kEventCodeByte] == kEventCommandComplete) &&
- (event[kEventCommandCompleteOpcodeLsByte] == 0x00) &&
- (event[kEventCommandCompleteOpcodeLsByte + 1] == 0x00);
- event_is_no_op |= (event[kEventCodeByte] == kEventCommandStatus) &&
- (event[kEventCommandStatusOpcodeLsByte] == 0x00) &&
- (event[kEventCommandStatusOpcodeLsByte + 1] == 0x00);
- if (event_is_no_op) {
- event_queue.pop(event);
+ auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
+ ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event))));
+ auto status_view = ::bluetooth::hci::CommandCompleteView::Create(
+ ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event))));
+ bool is_complete_no_op =
+ complete_view.IsValid() &&
+ complete_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
+ bool is_status_no_op =
+ status_view.IsValid() &&
+ status_view.GetCommandOpCode() == ::bluetooth::hci::OpCode::NONE;
+ if (is_complete_no_op || is_status_no_op) {
+ event_queue.pop();
} else {
break;
}
@@ -377,12 +372,12 @@
while (!acl_queue.empty()) {
std::vector<uint8_t> acl_packet;
acl_queue.front(acl_packet);
- uint16_t connection_handle = acl_packet[1] & 0xF;
- connection_handle <<= 8;
- connection_handle |= acl_packet[0];
- bool packet_is_no_op = connection_handle == kAclHandleQcaDebugMessage;
- if (packet_is_no_op) {
- acl_queue.pop(acl_packet);
+ auto acl_view =
+ ::bluetooth::hci::AclView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(acl_packet)));
+ EXPECT_TRUE(acl_view.IsValid());
+ if (acl_view.GetHandle() == kAclHandleQcaDebugMessage) {
+ acl_queue.pop();
} else {
break;
}
@@ -407,48 +402,49 @@
}
}
-// Wait until a command complete is received.
void BluetoothAidlTest::wait_for_command_complete_event(
- std::vector<uint8_t> cmd) {
+ OpCode opCode, std::vector<uint8_t>& complete_event) {
ASSERT_NO_FATAL_FAILURE(wait_for_event());
- std::vector<uint8_t> event;
ASSERT_FALSE(event_queue.empty());
- ASSERT_TRUE(event_queue.pop(event));
+ ASSERT_TRUE(event_queue.pop(complete_event));
+ auto complete_view = ::bluetooth::hci::CommandCompleteView::Create(
+ ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(complete_event))));
+ ASSERT_TRUE(complete_view.IsValid());
+ ASSERT_EQ(complete_view.GetCommandOpCode(), opCode);
+ ASSERT_EQ(complete_view.GetPayload()[0],
+ static_cast<uint8_t>(::bluetooth::hci::ErrorCode::SUCCESS));
+}
- ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
- ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
- ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
- ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
- ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
+void BluetoothAidlTest::wait_and_validate_command_complete_event(
+ ::bluetooth::hci::OpCode opCode) {
+ std::vector<uint8_t> complete_event;
+ ASSERT_NO_FATAL_FAILURE(
+ wait_for_command_complete_event(opCode, complete_event));
}
// Send the command to read the controller's buffer sizes.
void BluetoothAidlTest::setBufferSizes() {
- std::vector<uint8_t> cmd{
- kCommandHciReadBufferSize,
- kCommandHciReadBufferSize + sizeof(kCommandHciReadBufferSize)};
+ std::vector<uint8_t> cmd;
+ ::bluetooth::packet::BitInserter bi{cmd};
+ ::bluetooth::hci::ReadBufferSizeBuilder::Create()->Serialize(bi);
hci->sendHciCommand(cmd);
ASSERT_NO_FATAL_FAILURE(wait_for_event());
- if (event_queue.empty()) {
- return;
- }
std::vector<uint8_t> event;
ASSERT_TRUE(event_queue.pop(event));
+ auto complete_view = ::bluetooth::hci::ReadBufferSizeCompleteView::Create(
+ ::bluetooth::hci::CommandCompleteView::Create(
+ ::bluetooth::hci::EventView::Create(
+ ::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event)))));
- ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
- ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
- ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
- ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
-
- max_acl_data_packet_length =
- event[kEventCommandCompleteStatusByte + 1] +
- (event[kEventCommandCompleteStatusByte + 2] << 8);
- max_sco_data_packet_length = event[kEventCommandCompleteStatusByte + 3];
- max_acl_data_packets = event[kEventCommandCompleteStatusByte + 4] +
- (event[kEventCommandCompleteStatusByte + 5] << 8);
- max_sco_data_packets = event[kEventCommandCompleteStatusByte + 6] +
- (event[kEventCommandCompleteStatusByte + 7] << 8);
+ ASSERT_TRUE(complete_view.IsValid());
+ ASSERT_EQ(complete_view.GetStatus(), ::bluetooth::hci::ErrorCode::SUCCESS);
+ max_acl_data_packet_length = complete_view.GetAclDataPacketLength();
+ max_sco_data_packet_length = complete_view.GetSynchronousDataPacketLength();
+ max_acl_data_packets = complete_view.GetTotalNumAclDataPackets();
+ max_sco_data_packets = complete_view.GetTotalNumSynchronousDataPackets();
ALOGD("%s: ACL max %d num %d SCO max %d num %d", __func__,
static_cast<int>(max_acl_data_packet_length),
@@ -459,39 +455,39 @@
// Enable flow control packets for SCO
void BluetoothAidlTest::setSynchronousFlowControlEnable() {
- std::vector<uint8_t> cmd{kCommandHciSynchronousFlowControlEnable,
- kCommandHciSynchronousFlowControlEnable +
- sizeof(kCommandHciSynchronousFlowControlEnable)};
+ std::vector<uint8_t> cmd;
+ ::bluetooth::packet::BitInserter bi{cmd};
+ ::bluetooth::hci::WriteSynchronousFlowControlEnableBuilder::Create(
+ ::bluetooth::hci::Enable::ENABLED)
+ ->Serialize(bi);
hci->sendHciCommand(cmd);
- wait_for_command_complete_event(cmd);
+ wait_and_validate_command_complete_event(
+ ::bluetooth::hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE);
}
// Send an HCI command (in Loopback mode) and check the response.
void BluetoothAidlTest::sendAndCheckHci(int num_packets) {
- ThroughputLogger logger = {__func__};
- int command_size = 0;
+ ThroughputLogger logger{__func__};
+ size_t command_size = 0;
+ char new_name[] = "John Jacob Jingleheimer Schmidt ___________________";
+ size_t new_name_length = strlen(new_name);
for (int n = 0; n < num_packets; n++) {
- // Send an HCI packet
- std::vector<uint8_t> write_name{
- kCommandHciWriteLocalName,
- kCommandHciWriteLocalName + sizeof(kCommandHciWriteLocalName)};
- // With a name
- char new_name[] = "John Jacob Jingleheimer Schmidt ___________________0";
- size_t new_name_length = strlen(new_name);
+ // The name to set is new_name
+ std::array<uint8_t, 248> name_array{};
for (size_t i = 0; i < new_name_length; i++) {
- write_name.push_back(static_cast<uint8_t>(new_name[i]));
+ name_array[i] = new_name[i];
}
// And the packet number
- size_t i = new_name_length - 1;
- for (int digits = n; digits > 0; digits = digits / 10, i--) {
- write_name[i] = static_cast<uint8_t>('0' + digits % 10);
+ char number[11] = "0000000000";
+ snprintf(number, sizeof(number), "%010d", static_cast<int>(n));
+ for (size_t i = new_name_length; i < new_name_length + sizeof(number) - 1;
+ i++) {
+ name_array[new_name_length + i] = number[i];
}
- // And padding
- for (size_t i = 0; i < 248 - new_name_length; i++) {
- write_name.push_back(static_cast<uint8_t>(0));
- }
-
+ std::vector<uint8_t> write_name;
+ ::bluetooth::packet::BitInserter bi{write_name};
+ ::bluetooth::hci::WriteLocalNameBuilder::Create(name_array)->Serialize(bi);
hci->sendHciCommand(write_name);
// Check the loopback of the HCI packet
@@ -499,28 +495,17 @@
std::vector<uint8_t> event;
ASSERT_TRUE(event_queue.pop(event));
-
- size_t compare_length = (write_name.size() > static_cast<size_t>(0xff)
- ? static_cast<size_t>(0xff)
- : write_name.size());
- ASSERT_GT(event.size(), compare_length + kEventFirstPayloadByte - 1);
-
- ASSERT_EQ(kEventLoopbackCommand, event[kEventCodeByte]);
- ASSERT_EQ(compare_length, event[kEventLengthByte]);
-
- // Don't compare past the end of the event.
- if (compare_length + kEventFirstPayloadByte > event.size()) {
- compare_length = event.size() - kEventFirstPayloadByte;
- ALOGE("Only comparing %d bytes", static_cast<int>(compare_length));
- }
+ auto event_view = ::bluetooth::hci::LoopbackCommandView::Create(
+ ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event))));
+ ASSERT_TRUE(event_view.IsValid());
+ std::vector<uint8_t> looped_back_command{event_view.GetPayload().begin(),
+ event_view.GetPayload().end()};
+ ASSERT_EQ(looped_back_command, write_name);
if (n == num_packets - 1) {
command_size = write_name.size();
}
-
- for (size_t i = 0; i < compare_length; i++) {
- ASSERT_EQ(write_name[i], event[kEventFirstPayloadByte + i]);
- }
}
logger.setTotalBytes(command_size * num_packets * 2);
}
@@ -528,16 +513,18 @@
// Send a SCO data packet (in Loopback mode) and check the response.
void BluetoothAidlTest::sendAndCheckSco(int num_packets, size_t size,
uint16_t handle) {
- ThroughputLogger logger = {__func__};
+ ThroughputLogger logger{__func__};
for (int n = 0; n < num_packets; n++) {
// Send a SCO packet
std::vector<uint8_t> sco_packet;
- sco_packet.push_back(static_cast<uint8_t>(handle & 0xff));
- sco_packet.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8));
- sco_packet.push_back(static_cast<uint8_t>(size & 0xff));
+ std::vector<uint8_t> payload;
for (size_t i = 0; i < size; i++) {
- sco_packet.push_back(static_cast<uint8_t>(i + n));
+ payload.push_back(static_cast<uint8_t>(i + n));
}
+ ::bluetooth::packet::BitInserter bi{sco_packet};
+ ::bluetooth::hci::ScoBuilder::Create(
+ handle, ::bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED, payload)
+ ->Serialize(bi);
hci->sendScoData(sco_packet);
// Check the loopback of the SCO packet
@@ -545,21 +532,7 @@
ASSERT_TRUE(
sco_queue.tryPopWithTimeout(sco_loopback, kWaitForScoDataTimeout));
- ASSERT_EQ(sco_packet.size(), sco_loopback.size());
- size_t successful_bytes = 0;
-
- for (size_t i = 0; i < sco_packet.size(); i++) {
- if (sco_packet[i] == sco_loopback[i]) {
- successful_bytes = i;
- } else {
- ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
- sco_packet[i], sco_loopback[i]);
- ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
- sco_packet[i + 1], sco_loopback[i + 1]);
- break;
- }
- }
- ASSERT_EQ(sco_packet.size(), successful_bytes + 1);
+ ASSERT_EQ(sco_packet, sco_loopback);
}
logger.setTotalBytes(num_packets * size * 2);
}
@@ -567,19 +540,20 @@
// Send an ACL data packet (in Loopback mode) and check the response.
void BluetoothAidlTest::sendAndCheckAcl(int num_packets, size_t size,
uint16_t handle) {
- ThroughputLogger logger = {__func__};
+ ThroughputLogger logger{__func__};
for (int n = 0; n < num_packets; n++) {
- // Send an ACL packet
- std::vector<uint8_t> acl_packet;
- acl_packet.push_back(static_cast<uint8_t>(handle & 0xff));
- acl_packet.push_back(static_cast<uint8_t>((handle & 0x0f00) >> 8) |
- kAclBroadcastPointToPoint |
- kAclPacketBoundaryFirstAutoFlushable);
- acl_packet.push_back(static_cast<uint8_t>(size & 0xff));
- acl_packet.push_back(static_cast<uint8_t>((size & 0xff00) >> 8));
+ // Send an ACL packet with counting data
+ auto payload = std::make_unique<::bluetooth::packet::RawBuilder>();
for (size_t i = 0; i < size; i++) {
- acl_packet.push_back(static_cast<uint8_t>(i + n));
+ payload->AddOctets1(static_cast<uint8_t>(i + n));
}
+ std::vector<uint8_t> acl_packet;
+ ::bluetooth::packet::BitInserter bi{acl_packet};
+ ::bluetooth::hci::AclBuilder::Create(
+ handle,
+ ::bluetooth::hci::PacketBoundaryFlag::FIRST_AUTOMATICALLY_FLUSHABLE,
+ ::bluetooth::hci::BroadcastFlag::POINT_TO_POINT, std::move(payload))
+ ->Serialize(bi);
hci->sendAclData(acl_packet);
std::vector<uint8_t> acl_loopback;
@@ -587,21 +561,7 @@
ASSERT_TRUE(
acl_queue.tryPopWithTimeout(acl_loopback, kWaitForAclDataTimeout));
- ASSERT_EQ(acl_packet.size(), acl_loopback.size());
- size_t successful_bytes = 0;
-
- for (size_t i = 0; i < acl_packet.size(); i++) {
- if (acl_packet[i] == acl_loopback[i]) {
- successful_bytes = i;
- } else {
- ALOGE("Miscompare at %d (expected %x, got %x)", static_cast<int>(i),
- acl_packet[i], acl_loopback[i]);
- ALOGE("At %d (expected %x, got %x)", static_cast<int>(i + 1),
- acl_packet[i + 1], acl_loopback[i + 1]);
- break;
- }
- }
- ASSERT_EQ(acl_packet.size(), successful_bytes + 1);
+ ASSERT_EQ(acl_packet, acl_loopback);
}
logger.setTotalBytes(num_packets * size * 2);
}
@@ -620,23 +580,29 @@
}
std::vector<uint8_t> event;
EXPECT_TRUE(event_queue.pop(event));
-
- EXPECT_EQ(kEventNumberOfCompletedPackets, event[kEventCodeByte]);
- EXPECT_EQ(1, event[kEventNumberOfCompletedPacketsNumHandles]);
-
- uint16_t event_handle = event[3] + (event[4] << 8);
- EXPECT_EQ(handle, event_handle);
-
- packets_processed += event[5] + (event[6] << 8);
+ auto event_view = ::bluetooth::hci::NumberOfCompletedPacketsView::Create(
+ ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event))));
+ if (!event_view.IsValid()) {
+ ADD_FAILURE();
+ return packets_processed;
+ }
+ auto completed_packets = event_view.GetCompletedPackets();
+ for (const auto& entry : completed_packets) {
+ EXPECT_EQ(handle, entry.connection_handle_);
+ packets_processed += entry.host_num_of_completed_packets_;
+ }
}
return packets_processed;
}
// Send local loopback command and initialize SCO and ACL handles.
void BluetoothAidlTest::enterLoopbackMode() {
- std::vector<uint8_t> cmd{kCommandHciWriteLoopbackModeLocal,
- kCommandHciWriteLoopbackModeLocal +
- sizeof(kCommandHciWriteLoopbackModeLocal)};
+ std::vector<uint8_t> cmd;
+ ::bluetooth::packet::BitInserter bi{cmd};
+ ::bluetooth::hci::WriteLoopbackModeBuilder::Create(
+ bluetooth::hci::LoopbackMode::ENABLE_LOCAL)
+ ->Serialize(bi);
hci->sendHciCommand(cmd);
// Receive connection complete events with data channels
@@ -652,97 +618,128 @@
}
std::vector<uint8_t> event;
ASSERT_TRUE(event_queue.pop(event));
- ASSERT_GT(event.size(),
- static_cast<size_t>(kEventCommandCompleteStatusByte));
- if (event[kEventCodeByte] == kEventConnectionComplete) {
- ASSERT_GT(event.size(),
- static_cast<size_t>(kEventConnectionCompleteType));
- ASSERT_EQ(event[kEventLengthByte], kEventConnectionCompleteParamLength);
- uint8_t connection_type = event[kEventConnectionCompleteType];
+ auto event_view =
+ ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event)));
+ ASSERT_TRUE(event_view.IsValid());
- ASSERT_TRUE(connection_type == kEventConnectionCompleteTypeSco ||
- connection_type == kEventConnectionCompleteTypeAcl);
-
- // Save handles
- uint16_t handle = event[kEventConnectionCompleteHandleLsByte] |
- event[kEventConnectionCompleteHandleLsByte + 1] << 8;
- if (connection_type == kEventConnectionCompleteTypeSco) {
- sco_connection_handles.push_back(handle);
- } else {
- acl_connection_handles.push_back(handle);
+ if (event_view.GetEventCode() ==
+ ::bluetooth::hci::EventCode::CONNECTION_COMPLETE) {
+ auto complete_view =
+ ::bluetooth::hci::ConnectionCompleteView::Create(event_view);
+ ASSERT_TRUE(complete_view.IsValid());
+ switch (complete_view.GetLinkType()) {
+ case ::bluetooth::hci::LinkType::ACL:
+ acl_connection_handles.push_back(complete_view.GetConnectionHandle());
+ break;
+ case ::bluetooth::hci::LinkType::SCO:
+ sco_connection_handles.push_back(complete_view.GetConnectionHandle());
+ break;
+ default:
+ ASSERT_EQ(complete_view.GetLinkType(),
+ ::bluetooth::hci::LinkType::ACL);
}
-
- ALOGD("Connect complete type = %d handle = %d",
- event[kEventConnectionCompleteType], handle);
connection_event_count++;
} else {
- ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
- ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
- ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
- ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
+ auto command_complete_view =
+ ::bluetooth::hci::WriteLoopbackModeCompleteView::Create(
+ ::bluetooth::hci::CommandCompleteView::Create(event_view));
+ ASSERT_TRUE(command_complete_view.IsValid());
+ ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
+ command_complete_view.GetStatus());
command_complete_received = true;
}
}
}
+void BluetoothAidlTest::send_and_wait_for_cmd_complete(
+ std::unique_ptr<CommandBuilder> cmd, std::vector<uint8_t>& cmd_complete) {
+ std::vector<uint8_t> cmd_bytes = cmd->SerializeToBytes();
+ hci->sendHciCommand(cmd_bytes);
+
+ auto view = CommandView::Create(
+ PacketView<true>(std::make_shared<std::vector<uint8_t>>(cmd_bytes)));
+ ASSERT_TRUE(view.IsValid());
+ ALOGI("Waiting for %s[0x%x]", OpCodeText(view.GetOpCode()).c_str(),
+ static_cast<int>(view.GetOpCode()));
+ ASSERT_NO_FATAL_FAILURE(
+ wait_for_command_complete_event(view.GetOpCode(), cmd_complete));
+}
+
// Empty test: Initialize()/Close() are called in SetUp()/TearDown().
TEST_P(BluetoothAidlTest, InitializeAndClose) {}
// Send an HCI Reset with sendHciCommand and wait for a command complete event.
TEST_P(BluetoothAidlTest, HciReset) {
- std::vector<uint8_t> reset{kCommandHciReset,
- kCommandHciReset + sizeof(kCommandHciReset)};
+ std::vector<uint8_t> reset;
+ ::bluetooth::packet::BitInserter bi{reset};
+ ::bluetooth::hci::ResetBuilder::Create()->Serialize(bi);
hci->sendHciCommand(reset);
- wait_for_command_complete_event(reset);
+ wait_and_validate_command_complete_event(::bluetooth::hci::OpCode::RESET);
}
// Read and check the HCI version of the controller.
TEST_P(BluetoothAidlTest, HciVersionTest) {
- std::vector<uint8_t> cmd{kCommandHciReadLocalVersionInformation,
- kCommandHciReadLocalVersionInformation +
- sizeof(kCommandHciReadLocalVersionInformation)};
+ std::vector<uint8_t> cmd;
+ ::bluetooth::packet::BitInserter bi{cmd};
+ ::bluetooth::hci::ReadLocalVersionInformationBuilder::Create()->Serialize(bi);
hci->sendHciCommand(cmd);
ASSERT_NO_FATAL_FAILURE(wait_for_event());
std::vector<uint8_t> event;
ASSERT_TRUE(event_queue.pop(event));
- ASSERT_GT(event.size(), static_cast<size_t>(kEventLocalLmpVersionByte));
-
- ASSERT_EQ(kEventCommandComplete, event[kEventCodeByte]);
- ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
- ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
- ASSERT_EQ(kHciStatusSuccess, event[kEventCommandCompleteStatusByte]);
-
- ASSERT_LE(kHciMinimumHciVersion, event[kEventLocalHciVersionByte]);
- ASSERT_LE(kHciMinimumLmpVersion, event[kEventLocalLmpVersionByte]);
+ auto complete_view =
+ ::bluetooth::hci::ReadLocalVersionInformationCompleteView::Create(
+ ::bluetooth::hci::CommandCompleteView::Create(
+ ::bluetooth::hci::EventView::Create(
+ ::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event)))));
+ ASSERT_TRUE(complete_view.IsValid());
+ ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, complete_view.GetStatus());
+ auto version = complete_view.GetLocalVersionInformation();
+ ASSERT_LE(::bluetooth::hci::HciVersion::V_3_0, version.hci_version_);
+ ASSERT_LE(::bluetooth::hci::LmpVersion::V_3_0, version.lmp_version_);
}
// Send an unknown HCI command and wait for the error message.
TEST_P(BluetoothAidlTest, HciUnknownCommand) {
- std::vector<uint8_t> cmd{
- kCommandHciShouldBeUnknown,
- kCommandHciShouldBeUnknown + sizeof(kCommandHciShouldBeUnknown)};
+ std::vector<uint8_t> cmd;
+ ::bluetooth::packet::BitInserter bi{cmd};
+ ::bluetooth::hci::CommandBuilder::Create(
+ static_cast<::bluetooth::hci::OpCode>(0x3cff),
+ std::make_unique<::bluetooth::packet::RawBuilder>())
+ ->Serialize(bi);
hci->sendHciCommand(cmd);
ASSERT_NO_FATAL_FAILURE(wait_for_event());
std::vector<uint8_t> event;
ASSERT_TRUE(event_queue.pop(event));
+ auto event_view =
+ ::bluetooth::hci::EventView::Create(::bluetooth::hci::PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(event)));
+ ASSERT_TRUE(event_view.IsValid());
- ASSERT_GT(event.size(), static_cast<size_t>(kEventCommandCompleteStatusByte));
- if (event[kEventCodeByte] == kEventCommandComplete) {
- ASSERT_EQ(cmd[0], event[kEventCommandCompleteOpcodeLsByte]);
- ASSERT_EQ(cmd[1], event[kEventCommandCompleteOpcodeLsByte + 1]);
- ASSERT_EQ(kHciStatusUnknownHciCommand,
- event[kEventCommandCompleteStatusByte]);
- } else {
- ASSERT_EQ(kEventCommandStatus, event[kEventCodeByte]);
- ASSERT_EQ(cmd[0], event[kEventCommandStatusOpcodeLsByte]);
- ASSERT_EQ(cmd[1], event[kEventCommandStatusOpcodeLsByte + 1]);
- ASSERT_EQ(kHciStatusUnknownHciCommand,
- event[kEventCommandStatusStatusByte]);
+ switch (event_view.GetEventCode()) {
+ case ::bluetooth::hci::EventCode::COMMAND_COMPLETE: {
+ auto command_complete =
+ ::bluetooth::hci::CommandCompleteView::Create(event_view);
+ ASSERT_TRUE(command_complete.IsValid());
+ ASSERT_EQ(command_complete.GetPayload()[0],
+ static_cast<uint8_t>(
+ ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
+ } break;
+ case ::bluetooth::hci::EventCode::COMMAND_STATUS: {
+ auto command_status =
+ ::bluetooth::hci::CommandStatusView::Create(event_view);
+ ASSERT_TRUE(command_status.IsValid());
+ ASSERT_EQ(command_status.GetStatus(),
+ ::bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+ } break;
+ default:
+ ADD_FAILURE();
}
}
@@ -851,20 +848,24 @@
// Set all bits in the event mask
TEST_P(BluetoothAidlTest, SetEventMask) {
- std::vector<uint8_t> set_event_mask{
- 0x01, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff};
- hci->sendHciCommand({set_event_mask});
- wait_for_command_complete_event(set_event_mask);
+ std::vector<uint8_t> cmd;
+ ::bluetooth::packet::BitInserter bi{cmd};
+ uint64_t full_mask = UINT64_MAX;
+ ::bluetooth::hci::SetEventMaskBuilder::Create(full_mask)->Serialize(bi);
+ hci->sendHciCommand(cmd);
+ wait_and_validate_command_complete_event(
+ ::bluetooth::hci::OpCode::SET_EVENT_MASK);
}
// Set all bits in the LE event mask
TEST_P(BluetoothAidlTest, SetLeEventMask) {
- std::vector<uint8_t> set_event_mask{
- 0x20, 0x0c, 0x08 /*parameter bytes*/, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff};
- hci->sendHciCommand({set_event_mask});
- wait_for_command_complete_event(set_event_mask);
+ std::vector<uint8_t> cmd;
+ ::bluetooth::packet::BitInserter bi{cmd};
+ uint64_t full_mask = UINT64_MAX;
+ ::bluetooth::hci::LeSetEventMaskBuilder::Create(full_mask)->Serialize(bi);
+ hci->sendHciCommand(cmd);
+ wait_and_validate_command_complete_event(
+ ::bluetooth::hci::OpCode::LE_SET_EVENT_MASK);
}
// Call initialize twice, second one should fail.
@@ -872,28 +873,32 @@
class SecondCb
: public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
public:
- ndk::ScopedAStatus initializationComplete(Status status) {
+ ndk::ScopedAStatus initializationComplete(Status status) override {
EXPECT_EQ(status, Status::ALREADY_INITIALIZED);
init_promise.set_value();
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& /*event*/) {
+ ndk::ScopedAStatus hciEventReceived(
+ const std::vector<uint8_t>& /*event*/) override {
ADD_FAILURE();
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& /*data*/) {
+ ndk::ScopedAStatus aclDataReceived(
+ const std::vector<uint8_t>& /*data*/) override {
ADD_FAILURE();
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& /*data*/) {
+ ndk::ScopedAStatus scoDataReceived(
+ const std::vector<uint8_t>& /*data*/) override {
ADD_FAILURE();
return ScopedAStatus::ok();
};
- ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& /*data*/) {
+ ndk::ScopedAStatus isoDataReceived(
+ const std::vector<uint8_t>& /*data*/) override {
ADD_FAILURE();
return ScopedAStatus::ok();
};
@@ -909,6 +914,66 @@
ASSERT_EQ(status, std::future_status::ready);
}
+TEST_P(BluetoothAidlTest, Cdd_C_12_1_Bluetooth5Requirements) {
+ std::vector<uint8_t> version_event;
+ send_and_wait_for_cmd_complete(ReadLocalVersionInformationBuilder::Create(),
+ version_event);
+ auto version_view = ReadLocalVersionInformationCompleteView::Create(
+ CommandCompleteView::Create(EventView::Create(PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(version_event)))));
+ ASSERT_TRUE(version_view.IsValid());
+ ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, version_view.GetStatus());
+ auto version = version_view.GetLocalVersionInformation();
+ if (version.hci_version_ < ::bluetooth::hci::HciVersion::V_5_0) {
+ // This test does not apply to controllers below 5.0
+ return;
+ };
+ // When HCI version is 5.0, LMP version must also be at least 5.0
+ ASSERT_GE(static_cast<int>(version.lmp_version_),
+ static_cast<int>(version.hci_version_));
+
+ std::vector<uint8_t> le_features_event;
+ send_and_wait_for_cmd_complete(LeReadLocalSupportedFeaturesBuilder::Create(),
+ le_features_event);
+ auto le_features_view = LeReadLocalSupportedFeaturesCompleteView::Create(
+ CommandCompleteView::Create(EventView::Create(PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(le_features_event)))));
+ ASSERT_TRUE(le_features_view.IsValid());
+ ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, le_features_view.GetStatus());
+ auto le_features = le_features_view.GetLeFeatures();
+ ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LL_PRIVACY));
+ ASSERT_TRUE(le_features & static_cast<uint64_t>(LLFeaturesBits::LE_2M_PHY));
+ ASSERT_TRUE(le_features &
+ static_cast<uint64_t>(LLFeaturesBits::LE_CODED_PHY));
+ ASSERT_TRUE(le_features &
+ static_cast<uint64_t>(LLFeaturesBits::LE_EXTENDED_ADVERTISING));
+
+ std::vector<uint8_t> num_adv_set_event;
+ send_and_wait_for_cmd_complete(
+ LeReadNumberOfSupportedAdvertisingSetsBuilder::Create(),
+ num_adv_set_event);
+ auto num_adv_set_view =
+ LeReadNumberOfSupportedAdvertisingSetsCompleteView::Create(
+ CommandCompleteView::Create(EventView::Create(PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(num_adv_set_event)))));
+ ASSERT_TRUE(num_adv_set_view.IsValid());
+ ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS, num_adv_set_view.GetStatus());
+ auto num_adv_set = num_adv_set_view.GetNumberSupportedAdvertisingSets();
+ ASSERT_GE(num_adv_set, kMinLeAdvSetForBt5);
+
+ std::vector<uint8_t> num_resolving_list_event;
+ send_and_wait_for_cmd_complete(LeReadResolvingListSizeBuilder::Create(),
+ num_resolving_list_event);
+ auto num_resolving_list_view = LeReadResolvingListSizeCompleteView::Create(
+ CommandCompleteView::Create(EventView::Create(PacketView<true>(
+ std::make_shared<std::vector<uint8_t>>(num_resolving_list_event)))));
+ ASSERT_TRUE(num_resolving_list_view.IsValid());
+ ASSERT_EQ(::bluetooth::hci::ErrorCode::SUCCESS,
+ num_resolving_list_view.GetStatus());
+ auto num_resolving_list = num_resolving_list_view.GetResolvingListSize();
+ ASSERT_GE(num_resolving_list, kMinLeResolvingListForBt5);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/current.txt b/current.txt
index a6c4d80..754093f 100644
--- a/current.txt
+++ b/current.txt
@@ -937,5 +937,6 @@
889b59e3e7a59afa67bf19882a44f51a2f9e43b6556ec52baa9ec3efd1ef7fbe android.hardware.camera.device@3.2::types
db37a1c757e2e69b1ec9c75a981a6987bd87a131d92ab6acc00e04d19f374281 android.hardware.automotive.vehicle@2.0::types
997017f581406fca1675d2f612f7ccd73f0d04eadd54bf6212e6cf5971d0872d android.hardware.automotive.vehicle@2.0::types
+06983ffe6d75e90a22503a6d9fd14417f983a36bb060a80ad5915240d69b8a40 android.hardware.automotive.vehicle@2.0::types
# There will be no more HIDL HALs. Use AIDL instead.
diff --git a/drm/aidl/OWNERS b/drm/aidl/OWNERS
index fa8fd20..fe69725 100644
--- a/drm/aidl/OWNERS
+++ b/drm/aidl/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 49079
-edwinwong@google.com
kelzhan@google.com
robertshih@google.com
diff --git a/drm/aidl/vts/OWNERS b/drm/aidl/vts/OWNERS
index e44b93e..fe69725 100644
--- a/drm/aidl/vts/OWNERS
+++ b/drm/aidl/vts/OWNERS
@@ -1,4 +1,3 @@
-edwinwong@google.com
-jtinker@google.com
+# Bug component: 49079
kelzhan@google.com
robertshih@google.com
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
index 0e2d72b..6eba887 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -42,5 +42,4 @@
AUTO_LOW_LATENCY_MODE = 5,
SUSPEND = 6,
DISPLAY_IDLE_TIMER = 7,
- MULTI_THREADED_PRESENT = 8,
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
index 7154d74..f4b2984 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -80,20 +80,4 @@
* IComposerCallback.onVsyncIdle.
*/
DISPLAY_IDLE_TIMER = 7,
- /**
- * Indicates that both the composer HAL implementation and the given display
- * support calling executeCommands concurrently from separate threads.
- * executeCommands for a particular display will never run concurrently to
- * any other executeCommands for the same display. In addition, the
- * CommandResultPayload must only reference displays included in the
- * DisplayCommands passed to executeCommands. Displays referenced from
- * separate threads must have minimal interference with one another. If a
- * HWC-managed display has this capability, SurfaceFlinger can run
- * executeCommands for this display concurrently with other displays with the
- * same capability.
- * @see IComposerClient.executeCommands
- * @see DisplayCommand.presentDisplay
- * @see DisplayCommand.validateDisplay
- */
- MULTI_THREADED_PRESENT = 8,
}
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 323554c..04fa098 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -2518,20 +2518,6 @@
}
}
-TEST_P(GraphicsComposerAidlCommandTest, MultiThreadedPresent) {
- std::vector<VtsDisplay*> displays;
- for (auto& display : mDisplays) {
- if (hasDisplayCapability(display.getDisplayId(),
- DisplayCapability::MULTI_THREADED_PRESENT)) {
- displays.push_back(&display);
- }
- }
- if (displays.size() <= 1u) {
- return;
- }
- // TODO(b/251842321): Try to present on multiple threads.
-}
-
/**
* Test Capability::SKIP_VALIDATE
*
@@ -2605,4 +2591,4 @@
}
return RUN_ALL_TESTS();
-}
\ No newline at end of file
+}
diff --git a/identity/OWNERS b/identity/OWNERS
index 6969910..9353bbc 100644
--- a/identity/OWNERS
+++ b/identity/OWNERS
@@ -1,2 +1,4 @@
+# Bug component: 1084909
+
swillden@google.com
zeuthen@google.com
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index d8a5a87..6f7ab54 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -61,15 +61,3 @@
],
require_root: true,
}
-
-java_test_host {
- name: "IdentityCredentialImplementedTest",
- libs: [
- "tradefed",
- ],
- srcs: ["src/**/*.java"],
- test_suites: [
- "vts",
- ],
- test_config: "IdentityCredentialImplementedTest.xml",
-}
diff --git a/identity/aidl/vts/IdentityCredentialImplementedTest.xml b/identity/aidl/vts/IdentityCredentialImplementedTest.xml
deleted file mode 100644
index 4276ae6..0000000
--- a/identity/aidl/vts/IdentityCredentialImplementedTest.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<configuration description="Runs IdentityCredentialImplementedTest">
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
-
- <test class="com.android.tradefed.testtype.HostTest" >
- <option name="jar" value="IdentityCredentialImplementedTest.jar" />
- </test>
-</configuration>
diff --git a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java b/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
deleted file mode 100644
index 4936f8c..0000000
--- a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tests.security.identity;
-
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.platform.test.annotations.RequiresDevice;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-// This is a host-test which executes shell commands on the device. It would be
-// nicer to have this be a Device test (like CTS) but this is currently not
-// possible, see https://source.android.com/docs/core/tests/vts
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class IdentityCredentialImplementedTest extends BaseHostJUnit4Test {
- // Returns the ro.vendor.api_level or 0 if not set.
- //
- // Throws NumberFormatException if ill-formatted.
- //
- // Throws DeviceNotAvailableException if device is not available.
- //
- private int getVendorApiLevel() throws NumberFormatException, DeviceNotAvailableException {
- String vendorApiLevelString =
- getDevice().executeShellCommand("getprop ro.vendor.api_level").trim();
- if (vendorApiLevelString.isEmpty()) {
- return 0;
- }
- return Integer.parseInt(vendorApiLevelString);
- }
-
- // As of Android 14 VSR (vendor API level 34), Identity Credential is required at feature
- // version 202301 or later.
- @RequiresDevice
- @Test
- public void testIdentityCredentialIsImplemented() throws Exception {
- int vendorApiLevel = getVendorApiLevel();
- assumeTrue(vendorApiLevel >= 34);
-
- final String minimumFeatureVersionNeeded = "202301";
-
- String result = getDevice().executeShellCommand(
- "pm has-feature android.hardware.identity_credential "
- + minimumFeatureVersionNeeded);
- if (!result.trim().equals("true")) {
- fail("Identity Credential feature version " + minimumFeatureVersionNeeded
- + " required but not found");
- }
- }
-}
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index c45dd3f..63b2e73 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -26,6 +26,7 @@
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
+#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <cutils/properties.h>
@@ -1059,6 +1060,42 @@
}
/*
+ * NewKeyGenerationTest.RsaWithSpecifiedValidity
+ *
+ * Verifies that KeyMint respects specified NOT_BEFORE and NOT_AFTER certificate dates.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithSpecifiedValidity) {
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_CERTIFICATE_NOT_BEFORE,
+ 1183806000000 /* 2007-07-07T11:00:00Z */)
+ .Authorization(TAG_CERTIFICATE_NOT_AFTER,
+ 1916049600000 /* 2030-09-19T12:00:00Z */),
+ &key_blob, &key_characteristics));
+ ASSERT_GT(cert_chain_.size(), 0);
+
+ X509_Ptr cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+ ASSERT_TRUE(!!cert.get());
+
+ const ASN1_TIME* not_before = X509_get0_notBefore(cert.get());
+ ASSERT_NE(not_before, nullptr);
+ time_t not_before_time;
+ ASSERT_EQ(ASN1_TIME_to_time_t(not_before, ¬_before_time), 1);
+ EXPECT_EQ(not_before_time, 1183806000);
+
+ const ASN1_TIME* not_after = X509_get0_notAfter(cert.get());
+ ASSERT_NE(not_after, nullptr);
+ time_t not_after_time;
+ ASSERT_EQ(ASN1_TIME_to_time_t(not_after, ¬_after_time), 1);
+ EXPECT_EQ(not_after_time, 1916049600);
+}
+
+/*
* NewKeyGenerationTest.RsaWithAttestation
*
* Verifies that keymint can generate all required RSA key sizes with attestation, and that the
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 7214234..ffcaa95 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -467,16 +467,16 @@
case 3:
if (isTeeDeviceInfo(*parsed) && parsed->size() != kNumTeeDeviceInfoEntries) {
error += fmt::format(
- "Err: Incorrect number of device info entries. Expected {} but got"
+ "Err: Incorrect number of device info entries. Expected {} but got "
"{}\n",
kNumTeeDeviceInfoEntries, parsed->size());
}
// TEE IRPC instances require all entries to be present in DeviceInfo. Non-TEE instances
// may omit `os_version`
- if (!isTeeDeviceInfo(*parsed) && (parsed->size() != kNumTeeDeviceInfoEntries ||
+ if (!isTeeDeviceInfo(*parsed) && (parsed->size() != kNumTeeDeviceInfoEntries &&
parsed->size() != kNumTeeDeviceInfoEntries - 1)) {
error += fmt::format(
- "Err: Incorrect number of device info entries. Expected {} or {} but got"
+ "Err: Incorrect number of device info entries. Expected {} or {} but got "
"{}\n",
kNumTeeDeviceInfoEntries - 1, kNumTeeDeviceInfoEntries, parsed->size());
}
@@ -619,7 +619,7 @@
}
// BCC is [ pubkey, + BccEntry]
- auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kProtectedData);
+ auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13);
if (!bccContents) {
return bccContents.message() + "\n" + prettyPrint(bcc.get());
}
@@ -910,7 +910,7 @@
}
// DICE chain is [ pubkey, + DiceChainEntry ].
- auto diceContents = validateBcc(diceCertChain, hwtrust::DiceChain::Kind::kAuthenticatedMessage);
+ auto diceContents = validateBcc(diceCertChain, hwtrust::DiceChain::Kind::kVsr14);
if (!diceContents) {
return diceContents.message() + "\n" + prettyPrint(diceCertChain);
}
diff --git a/security/rkp/CHANGELOG.md b/security/rkp/CHANGELOG.md
index 9409a6d..f425284 100644
--- a/security/rkp/CHANGELOG.md
+++ b/security/rkp/CHANGELOG.md
@@ -31,7 +31,7 @@
* IRemotelyProvisionedComponent
* The need for an EEK has been removed. There is no longer an encrypted portion of the CSR.
* Keys for new CSR format must be generated with test mode set to false, effectively removing test
- mode in the new CSR flow. Old behavior is kept unchanged for backwards compatibility.
+ mode in the new CSR flow.
* The schema for the CSR itself has been significantly simplified, please see
IRemotelyProvisionedComponent.aidl for more details. Notably,
* the chain of signing, MACing, and encryption operations has been replaced with a single
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 35b83dd..7960c7f 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -144,9 +144,9 @@
byte[] generateEcdsaP256KeyPair(in boolean testMode, out MacedPublicKey macedPublicKey);
/**
- * This method can be removed in version 3 of the HAL. The header is kept around for
- * backwards compatibility purposes. From v3, this method is allowed to raise a
- * ServiceSpecificException with an error code of STATUS_REMOVED.
+ * This method has been deprecated since version 3 of the HAL. The header is kept around for
+ * backwards compatibility purposes. From v3, this method must raise a ServiceSpecificException
+ * with an error code of STATUS_REMOVED.
*
* For v1 and v2 implementations:
* generateCertificateRequest creates a certificate request to be sent to the provisioning
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index bf40976..9f68bfa 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -408,16 +408,8 @@
ASSERT_FALSE(HasFatalFailure());
if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
- bytevec keysToSignMac;
- DeviceInfo deviceInfo;
- ProtectedData protectedData;
- auto status = provisionable_->generateCertificateRequest(
- false, {}, {}, {}, &deviceInfo, &protectedData, &keysToSignMac);
- if (!status.isOk() && (status.getServiceSpecificError() ==
- BnRemotelyProvisionedComponent::STATUS_REMOVED)) {
- GTEST_SKIP() << "This test case applies to RKP v3+ only if "
- << "generateCertificateRequest() is implemented.";
- }
+ GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
+ << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
}
}
};
@@ -798,6 +790,20 @@
BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
}
+/**
+ * Call generateCertificateRequest(). Make sure it's removed.
+ */
+TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed) {
+ bytevec keysToSignMac;
+ DeviceInfo deviceInfo;
+ ProtectedData protectedData;
+ auto status = provisionable_->generateCertificateRequest(
+ true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
+ &protectedData, &keysToSignMac);
+ ASSERT_FALSE(status.isOk()) << status.getMessage();
+ EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
+}
+
void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
bool* device_locked, vector<uint8_t>* verified_boot_hash) {