Snap for 8253222 from 509a0223c1ecbec4bfbf6720b449036ee772ea16 to sdk-release
Change-Id: I46bbb6c1d858a7a011f48364a216db3ac04a865a
diff --git a/audio/7.1/Android.bp b/audio/7.1/Android.bp
index 52980e2..cede72a 100644
--- a/audio/7.1/Android.bp
+++ b/audio/7.1/Android.bp
@@ -17,7 +17,6 @@
"IDevice.hal",
"IDevicesFactory.hal",
"IPrimaryDevice.hal",
- "IStreamIn.hal",
"IStreamOut.hal",
"IStreamOutLatencyModeCallback.hal",
],
diff --git a/audio/7.1/IDevice.hal b/audio/7.1/IDevice.hal
index 373d17f..c158e7e 100644
--- a/audio/7.1/IDevice.hal
+++ b/audio/7.1/IDevice.hal
@@ -20,7 +20,6 @@
import @7.0::AudioInOutFlag;
import @7.0::IDevice;
import @7.0::Result;
-import IStreamIn;
import IStreamOut;
interface IDevice extends @7.0::IDevice {
@@ -56,33 +55,14 @@
AudioConfig suggestedConfig);
/**
- * This method creates and opens the audio hardware input stream.
- * If the stream can not be opened with the proposed audio config,
- * HAL must provide suggested values for the audio config.
+ * Notifies the device module about the connection state of an input/output
+ * device attached to it. The devicePort identifies the device and may also
+ * provide extra information such as raw audio descriptors.
*
- * Note: INVALID_ARGUMENTS is returned both in the case when the
- * HAL can not use the provided config and in the case when
- * the value of any argument is invalid. In the latter case the
- * HAL must provide a default initialized suggested config.
- *
- * @param ioHandle handle assigned by AudioFlinger.
- * @param device device type and (if needed) address.
- * @param config stream configuration.
- * @param flags additional flags.
- * @param sinkMetadata Description of the audio that is suggested by the client.
- * May be used by implementations to configure processing effects.
+ * @param devicePort audio device port.
+ * @param connected whether the device is connected.
* @return retval operation completion status.
- * @return inStream in case of success, created input stream.
- * @return suggestedConfig in the case of rejection of the proposed config,
- * a config suggested by the HAL.
*/
- openInputStream_7_1(
- AudioIoHandle ioHandle,
- DeviceAddress device,
- AudioConfig config,
- vec<AudioInOutFlag> flags,
- SinkMetadata sinkMetadata) generates (
- Result retval,
- IStreamIn inStream,
- AudioConfig suggestedConfig);
+ setConnectedState_7_1(AudioPort devicePort, bool connected)
+ generates (Result retval);
};
diff --git a/audio/7.1/IStreamIn.hal b/audio/7.1/IStreamIn.hal
deleted file mode 100644
index abebe6a..0000000
--- a/audio/7.1/IStreamIn.hal
+++ /dev/null
@@ -1,22 +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 android.hardware.audio@7.1;
-
-import @7.0::IStreamIn;
-
-interface IStreamIn extends @7.0::IStreamIn {
-};
diff --git a/audio/7.1/config/api/current.txt b/audio/7.1/config/api/current.txt
index 0a0eb02..75fc5c0 100644
--- a/audio/7.1/config/api/current.txt
+++ b/audio/7.1/config/api/current.txt
@@ -86,6 +86,7 @@
enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_MUSIC;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_SONIFICATION;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_SPEECH;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_ULTRASOUND;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioContentType AUDIO_CONTENT_TYPE_UNKNOWN;
}
@@ -273,6 +274,7 @@
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_MMAP_NOIRQ;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_RAW;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_SYNC;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_ULTRASOUND;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_INPUT_FLAG_VOIP_TX;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
@@ -290,6 +292,7 @@
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_SPATIALIZER;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_SYNC;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_TTS;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_ULTRASOUND;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioInOutFlag AUDIO_OUTPUT_FLAG_VOIP_RX;
}
@@ -314,6 +317,7 @@
enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_HOTWORD;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_MIC;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_REMOTE_SUBMIX;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_ULTRASOUND;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_UNPROCESSED;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_CALL;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioSource AUDIO_SOURCE_VOICE_COMMUNICATION;
@@ -355,6 +359,7 @@
enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_GAME;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_MEDIA;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION;
+ enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION_EVENT;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_SAFETY;
enum_constant public static final android.audio.policy.configuration.V7_1.AudioUsage AUDIO_USAGE_UNKNOWN;
@@ -462,6 +467,7 @@
method @Nullable public String getName();
method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.AudioUsage> getPreferredUsage();
method @Nullable public java.util.List<android.audio.policy.configuration.V7_1.Profile> getProfile();
+ method @Nullable public long getRecommendedMuteDurationMs();
method @Nullable public android.audio.policy.configuration.V7_1.Role getRole();
method public void setFlags(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioInOutFlag>);
method public void setGains(@Nullable android.audio.policy.configuration.V7_1.Gains);
@@ -469,6 +475,7 @@
method public void setMaxOpenCount(@Nullable long);
method public void setName(@Nullable String);
method public void setPreferredUsage(@Nullable java.util.List<android.audio.policy.configuration.V7_1.AudioUsage>);
+ method public void setRecommendedMuteDurationMs(@Nullable long);
method public void setRole(@Nullable android.audio.policy.configuration.V7_1.Role);
}
diff --git a/audio/7.1/config/audio_policy_configuration.xsd b/audio/7.1/config/audio_policy_configuration.xsd
index defb506..7e1da90 100644
--- a/audio/7.1/config/audio_policy_configuration.xsd
+++ b/audio/7.1/config/audio_policy_configuration.xsd
@@ -180,6 +180,7 @@
<xs:enumeration value="AUDIO_OUTPUT_FLAG_INCALL_MUSIC" />
<xs:enumeration value="AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD" />
<xs:enumeration value="AUDIO_OUTPUT_FLAG_SPATIALIZER" />
+ <xs:enumeration value="AUDIO_OUTPUT_FLAG_ULTRASOUND" />
<xs:enumeration value="AUDIO_INPUT_FLAG_FAST" />
<xs:enumeration value="AUDIO_INPUT_FLAG_HW_HOTWORD" />
<xs:enumeration value="AUDIO_INPUT_FLAG_RAW" />
@@ -188,6 +189,7 @@
<xs:enumeration value="AUDIO_INPUT_FLAG_VOIP_TX" />
<xs:enumeration value="AUDIO_INPUT_FLAG_HW_AV_SYNC" />
<xs:enumeration value="AUDIO_INPUT_FLAG_DIRECT" />
+ <xs:enumeration value="AUDIO_INPUT_FLAG_ULTRASOUND" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="audioInOutFlags">
@@ -226,6 +228,7 @@
</xs:documentation>
</xs:annotation>
</xs:attribute>
+ <xs:attribute name="recommendedMuteDurationMs" type="xs:unsignedInt"/>
</xs:complexType>
<xs:unique name="mixPortProfileUniqueness">
<xs:selector xpath="profile"/>
@@ -440,6 +443,7 @@
<xs:enumeration value="AUDIO_USAGE_ALARM" />
<xs:enumeration value="AUDIO_USAGE_NOTIFICATION" />
<xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT" />
<xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
<xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
<xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
@@ -470,6 +474,7 @@
<xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
<xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
<xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_ULTRASOUND"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="samplingRates">
@@ -741,6 +746,7 @@
<xs:enumeration value="AUDIO_SOURCE_ECHO_REFERENCE"/>
<xs:enumeration value="AUDIO_SOURCE_FM_TUNER"/>
<xs:enumeration value="AUDIO_SOURCE_HOTWORD"/>
+ <xs:enumeration value="AUDIO_SOURCE_ULTRASOUND"/>
</xs:restriction>
</xs:simpleType>
<!-- Enum values of device_category from Volume.h. -->
diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp
index 218d7c0..0fd2947 100644
--- a/audio/common/all-versions/default/7.0/HidlUtils.cpp
+++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp
@@ -485,8 +485,12 @@
status_t HidlUtils::audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage) {
if (halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST ||
halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT ||
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED) {
+#else
halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED ||
halUsage == AUDIO_USAGE_NOTIFICATION_EVENT) {
+#endif
halUsage = AUDIO_USAGE_NOTIFICATION;
}
*usage = audio_usage_to_string(halUsage);
diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp
index 8f55744..9543674 100644
--- a/audio/common/all-versions/default/Android.bp
+++ b/audio/common/all-versions/default/Android.bp
@@ -157,6 +157,28 @@
],
}
+cc_library {
+ name: "android.hardware.audio.common@7.1-util",
+ defaults: ["android.hardware.audio.common-util_default"],
+ srcs: [
+ "7.0/HidlUtils.cpp",
+ "HidlUtilsCommon.cpp",
+ "UuidUtils.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.1-enums",
+ "libbase",
+ ],
+ cflags: [
+ "-DMAJOR_VERSION=7",
+ "-DMINOR_VERSION=1",
+ "-DCOMMON_TYPES_MINOR_VERSION=0",
+ "-DCORE_TYPES_MINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+}
+
// Note: this isn't a VTS test, but rather a unit test
// to verify correctness of conversion utilities.
cc_test {
@@ -189,6 +211,8 @@
name: "android.hardware.audio.common@7.0-util_tests",
defaults: ["android.hardware.audio.common-util_default"],
+ tidy_timeout_srcs: ["tests/hidlutils_tests.cpp"],
+
srcs: ["tests/hidlutils_tests.cpp"],
// Use static linking to allow running in presubmit on
@@ -214,3 +238,37 @@
test_suites: ["device-tests"],
}
+
+cc_test {
+ name: "android.hardware.audio.common@7.1-util_tests",
+ defaults: ["android.hardware.audio.common-util_default"],
+
+ tidy_timeout_srcs: ["tests/hidlutils_tests.cpp"],
+
+ srcs: ["tests/hidlutils_tests.cpp"],
+
+ // Use static linking to allow running in presubmit on
+ // targets that don't have HAL V7.1.
+ static_libs: [
+ "android.hardware.audio.common@7.1-enums",
+ "android.hardware.audio.common@7.1-util",
+ "android.hardware.audio.common@7.0",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libxml2",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ "-DMAJOR_VERSION=7",
+ "-DMINOR_VERSION=1",
+ "-DCOMMON_TYPES_MINOR_VERSION=0",
+ "-DCORE_TYPES_MINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+
+ test_suites: ["device-tests"],
+}
diff --git a/audio/common/all-versions/default/HidlUtilsCommon.cpp b/audio/common/all-versions/default/HidlUtilsCommon.cpp
index d2da193..bc3d870 100644
--- a/audio/common/all-versions/default/HidlUtilsCommon.cpp
+++ b/audio/common/all-versions/default/HidlUtilsCommon.cpp
@@ -20,7 +20,7 @@
namespace hardware {
namespace audio {
namespace common {
-namespace CPP_VERSION {
+namespace COMMON_TYPES_CPP_VERSION {
namespace implementation {
status_t HidlUtils::audioPortConfigsFromHal(unsigned int numHalConfigs,
@@ -51,7 +51,7 @@
}
} // namespace implementation
-} // namespace CPP_VERSION
+} // namespace COMMON_TYPES_CPP_VERSION
} // namespace common
} // namespace audio
} // namespace hardware
diff --git a/audio/common/all-versions/default/TEST_MAPPING b/audio/common/all-versions/default/TEST_MAPPING
index c965113..780beea 100644
--- a/audio/common/all-versions/default/TEST_MAPPING
+++ b/audio/common/all-versions/default/TEST_MAPPING
@@ -5,6 +5,9 @@
},
{
"name": "android.hardware.audio.common@7.0-util_tests"
+ },
+ {
+ "name": "android.hardware.audio.common@7.1-util_tests"
}
]
}
diff --git a/audio/common/all-versions/default/service/Android.bp b/audio/common/all-versions/default/service/Android.bp
index 1bd6abe..9890be2 100644
--- a/audio/common/all-versions/default/service/Android.bp
+++ b/audio/common/all-versions/default/service/Android.bp
@@ -52,6 +52,7 @@
shared_libs: [
"libcutils",
"libbinder",
+ "libbinder_ndk",
"libhidlbase",
"liblog",
"libutils",
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index e26369f..fbf6165 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -20,8 +20,10 @@
#include <string>
#include <vector>
+#include <android/binder_process.h>
#include <binder/ProcessState.h>
#include <cutils/properties.h>
+#include <dlfcn.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/LegacySupport.h>
#include <hwbinder/ProcessState.h>
@@ -45,6 +47,31 @@
return false;
}
+static bool registerExternalServiceImplementation(const std::string& libName,
+ const std::string& funcName) {
+ constexpr int dlMode = RTLD_LAZY;
+ void* handle = nullptr;
+ dlerror(); // clear
+ auto libPath = libName + ".so";
+ handle = dlopen(libPath.c_str(), dlMode);
+ if (handle == nullptr) {
+ const char* error = dlerror();
+ ALOGE("Failed to dlopen %s: %s", libPath.c_str(),
+ error != nullptr ? error : "unknown error");
+ return false;
+ }
+ binder_status_t (*factoryFunction)();
+ *(void**)(&factoryFunction) = dlsym(handle, funcName.c_str());
+ if (!factoryFunction) {
+ const char* error = dlerror();
+ ALOGE("Factory function %s not found in libName %s: %s", funcName.c_str(), libPath.c_str(),
+ error != nullptr ? error : "unknown error");
+ dlclose(handle);
+ return false;
+ }
+ return ((*factoryFunction)() == STATUS_OK);
+}
+
int main(int /* argc */, char* /* argv */ []) {
signal(SIGPIPE, SIG_IGN);
@@ -52,6 +79,9 @@
// start a threadpool for vndbinder interactions
::android::ProcessState::self()->startThreadPool();
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+
const int32_t defaultValue = -1;
int32_t value =
property_get_int32("persist.vendor.audio.service.hwbinder.size_kbyte", defaultValue);
@@ -101,6 +131,13 @@
"android.hardware.bluetooth.a2dp@1.0::IBluetoothAudioOffload"
}
};
+
+ const std::vector<std::pair<std::string,std::string>> optionalInterfaceSharedLibs = {
+ {
+ "android.hardware.bluetooth.audio-impl",
+ "createIBluetoothAudioProviderFactory",
+ },
+ };
// clang-format on
for (const auto& listIter : mandatoryInterfaces) {
@@ -117,5 +154,15 @@
"Could not register %s", interfaceFamilyName.c_str());
}
+ for (const auto& interfacePair : optionalInterfaceSharedLibs) {
+ const std::string& libraryName = interfacePair.first;
+ const std::string& interfaceLoaderFuncName = interfacePair.second;
+ if (registerExternalServiceImplementation(libraryName, interfaceLoaderFuncName)) {
+ ALOGI("%s() from %s success", interfaceLoaderFuncName.c_str(), libraryName.c_str());
+ } else {
+ ALOGW("%s() from %s failed", interfaceLoaderFuncName.c_str(), libraryName.c_str());
+ }
+ }
+
joinRpcThreadpool();
}
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index 2749cce..ec16b02 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -23,7 +23,7 @@
#include <log/log.h>
#include <HidlUtils.h>
-#include <android_audio_policy_configuration_V7_0-enums.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
#include <system/audio.h>
#include <xsdc/XsdcSupport.h>
@@ -32,7 +32,7 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index 86380a5..3536561 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -48,6 +48,8 @@
"libhidlbase",
"liblog",
"libmedia_helper",
+ "libmediautils_vendor",
+ "libmemunreachable",
"libutils",
"android.hardware.audio.common-util",
],
@@ -166,10 +168,10 @@
shared_libs: [
"android.hardware.audio@7.0",
"android.hardware.audio@7.1",
- "android.hardware.audio@7.0-util",
+ "android.hardware.audio@7.1-util",
"android.hardware.audio.common@7.0",
"android.hardware.audio.common@7.1-enums",
- "android.hardware.audio.common@7.0-util",
+ "android.hardware.audio.common@7.1-util",
"libbase",
],
cflags: [
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 98a59b9..b954fcd 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -30,6 +30,8 @@
#include <algorithm>
#include <android/log.h>
+#include <mediautils/MemoryLeakTrackUtil.h>
+#include <memunreachable/memunreachable.h>
#include <HidlUtils.h>
@@ -346,16 +348,6 @@
_hidl_cb(result, streamOut, suggestedConfig);
return Void();
}
-
-Return<void> Device::openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
- const AudioConfig& config, const AudioInputFlags& flags,
- const SinkMetadata& sinkMetadata,
- openInputStream_7_1_cb _hidl_cb) {
- auto [result, streamIn, suggestedConfig] =
- openInputStreamImpl(ioHandle, device, config, flags, sinkMetadata);
- _hidl_cb(result, streamIn, suggestedConfig);
- return Void();
-}
#endif // V7.1
Return<bool> Device::supportsAudioPatches() {
@@ -501,9 +493,32 @@
}
#endif
-Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) {
+Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
- analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
+ const int fd0 = fd->data[0];
+ bool dumpMem = false;
+ bool unreachableMemory = false;
+ for (const auto& option : options) {
+ if (option == "-m") {
+ dumpMem = true;
+ } else if (option == "--unreachable") {
+ unreachableMemory = true;
+ }
+ }
+
+ if (dumpMem) {
+ dprintf(fd0, "\nDumping memory:\n");
+ std::string s = dumpMemoryAddresses(100 /* limit */);
+ write(fd0, s.c_str(), s.size());
+ }
+ if (unreachableMemory) {
+ dprintf(fd0, "\nDumping unreachable memory:\n");
+ // TODO - should limit be an argument parameter?
+ std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */);
+ write(fd0, s.c_str(), s.size());
+ }
+
+ analyzeStatus("dump", mDevice->dump(mDevice, fd0));
}
return Void();
}
@@ -591,6 +606,21 @@
#endif
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+Return<Result> Device::setConnectedState_7_1(const AudioPort& devicePort, bool connected) {
+ if (version() >= AUDIO_DEVICE_API_VERSION_3_2 &&
+ mDevice->set_device_connected_state_v7 != nullptr) {
+ audio_port_v7 halPort;
+ if (status_t status = HidlUtils::audioPortToHal(devicePort, &halPort); status != NO_ERROR) {
+ return analyzeStatus("audioPortToHal", status);
+ }
+ return analyzeStatus("set_device_connected_state_v7",
+ mDevice->set_device_connected_state_v7(mDevice, &halPort, connected));
+ }
+ return Result::NOT_SUPPORTED;
+}
+#endif
+
} // namespace implementation
} // namespace CPP_VERSION
} // namespace audio
diff --git a/audio/core/all-versions/default/TEST_MAPPING b/audio/core/all-versions/default/TEST_MAPPING
index 1e29440..07e98f3 100644
--- a/audio/core/all-versions/default/TEST_MAPPING
+++ b/audio/core/all-versions/default/TEST_MAPPING
@@ -4,6 +4,9 @@
"name": "android.hardware.audio@7.0-util_tests"
},
{
+ "name": "android.hardware.audio@7.1-util_tests"
+ },
+ {
"name": "HalAudioV6_0GeneratorTest"
},
{
diff --git a/audio/core/all-versions/default/include/core/default/Device.h b/audio/core/all-versions/default/include/core/default/Device.h
index 0aeb6b3..0696f97 100644
--- a/audio/core/all-versions/default/include/core/default/Device.h
+++ b/audio/core/all-versions/default/include/core/default/Device.h
@@ -123,10 +123,6 @@
const AudioConfig& config, const AudioOutputFlags& flags,
const SourceMetadata& sourceMetadata,
openOutputStream_7_1_cb _hidl_cb) override;
- Return<void> openInputStream_7_1(int32_t ioHandle, const DeviceAddress& device,
- const AudioConfig& config, const AudioInputFlags& flags,
- const SinkMetadata& sinkMetadata,
- openInputStream_7_1_cb _hidl_cb) override;
#endif
Return<bool> supportsAudioPatches() override;
@@ -163,6 +159,9 @@
const hidl_vec<AudioPortConfig>& sinks,
createAudioPatch_cb _hidl_cb) override;
#endif
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ Return<Result> setConnectedState_7_1(const AudioPort& devicePort, bool connected) override;
+#endif
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
// Utility methods for extending interfaces.
diff --git a/audio/core/all-versions/default/include/core/default/StreamIn.h b/audio/core/all-versions/default/include/core/default/StreamIn.h
index a6346e5..4627eec 100644
--- a/audio/core/all-versions/default/include/core/default/StreamIn.h
+++ b/audio/core/all-versions/default/include/core/default/StreamIn.h
@@ -17,7 +17,9 @@
#ifndef ANDROID_HARDWARE_AUDIO_STREAMIN_H
#define ANDROID_HARDWARE_AUDIO_STREAMIN_H
-#include PATH(android/hardware/audio/FILE_VERSION/IStreamIn.h)
+// clang-format off
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamIn.h)
+// clang-format on
#include "Device.h"
#include "Stream.h"
diff --git a/audio/core/all-versions/default/util/Android.bp b/audio/core/all-versions/default/util/Android.bp
index 7caf18d..b96f2d2 100644
--- a/audio/core/all-versions/default/util/Android.bp
+++ b/audio/core/all-versions/default/util/Android.bp
@@ -112,6 +112,25 @@
],
}
+cc_library {
+ name: "android.hardware.audio@7.1-util",
+ defaults: ["android.hardware.audio-util_default"],
+ shared_libs: [
+ "android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.1-enums",
+ "android.hardware.audio.common@7.1-util",
+ "android.hardware.audio@7.1",
+ "libbase",
+ ],
+ cflags: [
+ "-DMAJOR_VERSION=7",
+ "-DMINOR_VERSION=1",
+ "-DCOMMON_TYPES_MINOR_VERSION=0",
+ "-DCORE_TYPES_MINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+}
+
// Note: this isn't a VTS test, but rather a unit test
// to verify correctness of conversion utilities.
cc_test {
@@ -145,3 +164,37 @@
test_suites: ["device-tests"],
}
+
+cc_test {
+ name: "android.hardware.audio@7.1-util_tests",
+ defaults: ["android.hardware.audio-util_default"],
+
+ srcs: ["tests/coreutils_tests.cpp"],
+
+ // Use static linking to allow running in presubmit on
+ // targets that don't have HAL V7.1.
+ static_libs: [
+ "android.hardware.audio.common@7.0",
+ "android.hardware.audio.common@7.1-enums",
+ "android.hardware.audio.common@7.1-util",
+ "android.hardware.audio@7.1",
+ "android.hardware.audio@7.1-util",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libxml2",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ "-DMAJOR_VERSION=7",
+ "-DMINOR_VERSION=1",
+ "-DCOMMON_TYPES_MINOR_VERSION=0",
+ "-DCORE_TYPES_MINOR_VERSION=0",
+ "-include common/all-versions/VersionMacro.h",
+ ],
+
+ test_suites: ["device-tests"],
+}
diff --git a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
index 3976b08..0e15960 100644
--- a/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
+++ b/audio/core/all-versions/default/util/tests/coreutils_tests.cpp
@@ -22,18 +22,18 @@
#define LOG_TAG "CoreUtils_Test"
#include <log/log.h>
-#include <android_audio_policy_configuration_V7_0-enums.h>
+#include PATH(APM_XSD_ENUMS_H_FILENAME)
#include <system/audio.h>
#include <util/CoreUtils.h>
#include <xsdc/XsdcSupport.h>
using namespace android;
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
-using namespace ::android::hardware::audio::CPP_VERSION;
+using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
using ::android::hardware::hidl_vec;
-using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
+using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
}
static constexpr audio_channel_mask_t kInvalidHalChannelMask = AUDIO_CHANNEL_INVALID;
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index a9797bb..7f4a777 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -28,8 +28,7 @@
if (getDeviceName() != DeviceManager::kPrimaryDevice) {
GTEST_SKIP() << "No primary device on this factory"; // returns
}
- EXPECT_TRUE(
- DeviceManager::getInstance().reset(getFactoryName(), DeviceManager::kPrimaryDevice));
+ EXPECT_TRUE(DeviceManager::getInstance().resetPrimary(getFactoryName()));
// Must use IDevicesFactory directly because DeviceManager always uses
// the latest interfaces version and corresponding methods for opening
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
index a567cf9..83ca9eb 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
@@ -15,9 +15,9 @@
*/
// clang-format off
-#include PATH(android/hardware/audio/FILE_VERSION/IStreamIn.h)
-#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
+#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/IStreamIn.h)
#include PATH(android/hardware/audio/CORE_TYPES_FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamOut.h)
#include PATH(android/hardware/audio/common/COMMON_TYPES_FILE_VERSION/types.h)
// clang-format on
#include <hidl/HidlSupport.h>
diff --git a/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp
index b750f56..d82d4ad 100644
--- a/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.1/AudioPrimaryHidlHalTest.cpp
@@ -16,3 +16,34 @@
// pull in all the <= 7.0 tests
#include "7.0/AudioPrimaryHidlHalTest.cpp"
+
+TEST_P(AudioHidlDeviceTest, SetConnectedState_7_1) {
+ doc::test("Check that the HAL can be notified of device connection and disconnection");
+ using AD = xsd::AudioDevice;
+ for (auto deviceType : {AD::AUDIO_DEVICE_OUT_HDMI, AD::AUDIO_DEVICE_OUT_WIRED_HEADPHONE,
+ AD::AUDIO_DEVICE_IN_USB_HEADSET}) {
+ SCOPED_TRACE("device=" + toString(deviceType));
+ for (bool state : {true, false}) {
+ SCOPED_TRACE("state=" + ::testing::PrintToString(state));
+ DeviceAddress address = {};
+ address.deviceType = toString(deviceType);
+ if (deviceType == AD::AUDIO_DEVICE_IN_USB_HEADSET) {
+ address.address.alsa({0, 0});
+ }
+ AudioPort devicePort;
+ devicePort.ext.device(address);
+ auto ret = getDevice()->setConnectedState_7_1(devicePort, state);
+ ASSERT_TRUE(ret.isOk());
+ if (ret == Result::NOT_SUPPORTED) {
+ doc::partialTest("setConnectedState_7_1 is not supported");
+ break; // other deviceType might be supported
+ }
+ ASSERT_OK(ret);
+ }
+ }
+
+ // Because there is no way of knowing if the devices were connected before
+ // calling setConnectedState, there is no way to restore the HAL to its
+ // initial state. To workaround this, destroy the HAL at the end of this test.
+ ASSERT_TRUE(resetDevice());
+}
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index d810c55..3007f01 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -48,6 +48,9 @@
cc_test {
name: "VtsHalAudioV2_0TargetTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
+ tidy_timeout_srcs: [
+ "2.0/AudioPrimaryHidlHalTest.cpp",
+ ],
srcs: [
"2.0/AudioPrimaryHidlHalTest.cpp",
],
@@ -74,6 +77,9 @@
cc_test {
name: "VtsHalAudioV4_0TargetTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
+ tidy_timeout_srcs: [
+ "4.0/AudioPrimaryHidlHalTest.cpp",
+ ],
srcs: [
"4.0/AudioPrimaryHidlHalTest.cpp",
],
@@ -126,6 +132,9 @@
cc_test {
name: "VtsHalAudioV6_0TargetTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
+ tidy_timeout_srcs: [
+ "6.0/AudioPrimaryHidlHalTest.cpp",
+ ],
srcs: [
"6.0/AudioPrimaryHidlHalTest.cpp",
"6.0/Generators.cpp",
@@ -153,6 +162,9 @@
cc_test {
name: "VtsHalAudioV7_0TargetTest",
defaults: ["VtsHalAudioTargetTest_defaults"],
+ tidy_timeout_srcs: [
+ "7.0/AudioPrimaryHidlHalTest.cpp",
+ ],
srcs: [
"7.0/AudioPrimaryHidlHalTest.cpp",
"7.0/Generators.cpp",
@@ -195,7 +207,7 @@
"android.hardware.audio.common@7.0",
"android.hardware.audio.common@7.0-enums",
"android.hardware.audio.common@7.1-enums",
- "android.hardware.audio.common@7.0-util",
+ "android.hardware.audio.common@7.1-util",
],
cflags: [
"-DMAJOR_VERSION=7",
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 404532a..fa3ee7f 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -91,8 +91,9 @@
using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
using namespace ::android::hardware::audio::common::test::utility;
using namespace ::android::hardware::audio::CPP_VERSION;
-using ReadParameters = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadParameters;
-using ReadStatus = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadStatus;
+using ReadParameters =
+ ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn::ReadParameters;
+using ReadStatus = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn::ReadStatus;
using WriteCommand = ::android::hardware::audio::CPP_VERSION::IStreamOut::WriteCommand;
using WriteStatus = ::android::hardware::audio::CPP_VERSION::IStreamOut::WriteStatus;
#if MAJOR_VERSION >= 7
@@ -1089,7 +1090,7 @@
class StreamReader : public StreamWorker<StreamReader> {
public:
- using IStreamIn = ::android::hardware::audio::CPP_VERSION::IStreamIn;
+ using IStreamIn = ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn;
StreamReader(IStreamIn* stream, size_t bufferSize)
: mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
@@ -1204,7 +1205,8 @@
EventFlag* mEfGroup = nullptr;
};
-class InputStreamTest : public OpenStreamTest<::android::hardware::audio::CPP_VERSION::IStreamIn> {
+class InputStreamTest
+ : public OpenStreamTest<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn> {
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
#if MAJOR_VERSION <= 6
@@ -1226,13 +1228,8 @@
auto flags = getInputFlags();
testOpen(
[&](AudioIoHandle handle, AudioConfig config, auto cb) {
-#if MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
return getDevice()->openInputStream(handle, address, config, flags,
initMetadata, cb);
-#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
- return getDevice()->openInputStream_7_1(handle, address, config, flags,
- initMetadata, cb);
-#endif
},
config);
}
@@ -1605,8 +1602,9 @@
"InputStream::setGain");
}
-static void testPrepareForReading(::android::hardware::audio::CPP_VERSION::IStreamIn* stream,
- uint32_t frameSize, uint32_t framesCount) {
+static void testPrepareForReading(
+ ::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn* stream, uint32_t frameSize,
+ uint32_t framesCount) {
Result res;
// Ignore output parameters as the call should fail
ASSERT_OK(stream->prepareForReading(frameSize, framesCount,
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index c8e0167..6bb39ed 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -96,40 +96,83 @@
}
};
-using FactoryAndDevice = std::tuple<std::string, std::string>;
-class DeviceManager : public InterfaceManager<DeviceManager, FactoryAndDevice, IDevice> {
+namespace impl {
+
+class PrimaryDeviceManager
+ : public InterfaceManager<PrimaryDeviceManager, std::string, IPrimaryDevice> {
public:
- static DeviceManager& getInstance() {
- static DeviceManager instance;
- return instance;
+ static sp<IPrimaryDevice> createInterfaceInstance(const std::string& factoryName) {
+ sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
+ return openPrimaryDevice(factory);
}
+
+ bool reset(const std::string& factoryName) __attribute__((warn_unused_result)) {
+#if MAJOR_VERSION <= 5
+ return InterfaceManager::reset(factoryName, true);
+#elif MAJOR_VERSION >= 6
+ {
+ sp<IPrimaryDevice> device = getExisting(factoryName);
+ if (device != nullptr) {
+ auto ret = device->close();
+ ALOGE_IF(!ret.isOk(), "PrimaryDevice %s close failed: %s", factoryName.c_str(),
+ ret.description().c_str());
+ }
+ }
+ return InterfaceManager::reset(factoryName, false);
+#endif
+ }
+
+ private:
+ static sp<IPrimaryDevice> openPrimaryDevice(const sp<IDevicesFactory>& factory) {
+ if (factory == nullptr) return {};
+ Result result;
+ sp<IPrimaryDevice> primaryDevice;
+#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1)
+ sp<IDevice> device;
+#if MAJOR_VERSION == 2
+ auto ret = factory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, device));
+ if (ret.isOk() && result == Result::OK && device != nullptr) {
+ primaryDevice = IPrimaryDevice::castFrom(device);
+ }
+#elif MAJOR_VERSION >= 4
+ auto ret = factory->openPrimaryDevice(returnIn(result, device));
+ if (ret.isOk() && result == Result::OK && device != nullptr) {
+ primaryDevice = IPrimaryDevice::castFrom(device);
+ }
+#endif
+ if (!ret.isOk() || result != Result::OK || primaryDevice == nullptr) {
+ ALOGW("Primary device can not be opened, transaction: %s, result %d, device %p",
+ ret.description().c_str(), result, device.get());
+ return nullptr;
+ }
+#else // V7.1
+ auto ret = factory->openPrimaryDevice_7_1(returnIn(result, primaryDevice));
+ if (!ret.isOk() || result != Result::OK) {
+ ALOGW("Primary device can not be opened, transaction: %s, result %d",
+ ret.description().c_str(), result);
+ return nullptr;
+ }
+#endif
+ return primaryDevice;
+ }
+};
+
+using FactoryAndDevice = std::tuple<std::string, std::string>;
+class RegularDeviceManager
+ : public InterfaceManager<RegularDeviceManager, FactoryAndDevice, IDevice> {
+ public:
static sp<IDevice> createInterfaceInstance(const FactoryAndDevice& factoryAndDevice) {
auto [factoryName, name] = factoryAndDevice;
sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
return openDevice(factory, name);
}
- using InterfaceManager::reset;
-
- static constexpr const char* kPrimaryDevice = "primary";
sp<IDevice> get(const std::string& factoryName, const std::string& name) {
- if (name == kPrimaryDevice) {
- (void)getPrimary(factoryName); // for initializing primaryDevice if needed.
- }
return InterfaceManager::get(std::make_tuple(factoryName, name));
}
- sp<IPrimaryDevice> getPrimary(const std::string& factoryName) {
- if (primaryDevice == nullptr) {
- sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
- primaryDevice = openPrimaryDevice(factory);
- }
- return primaryDevice;
- }
+
bool reset(const std::string& factoryName, const std::string& name)
__attribute__((warn_unused_result)) {
- if (name == kPrimaryDevice) {
- primaryDevice.clear();
- }
#if MAJOR_VERSION <= 5
return InterfaceManager::reset(std::make_tuple(factoryName, name), true);
#elif MAJOR_VERSION >= 6
@@ -144,9 +187,6 @@
return InterfaceManager::reset(std::make_tuple(factoryName, name), false);
#endif
}
- bool resetPrimary(const std::string& factoryName) __attribute__((warn_unused_result)) {
- return reset(factoryName, kPrimaryDevice);
- }
private:
static sp<IDevice> openDevice(const sp<IDevicesFactory>& factory, const std::string& name) {
@@ -155,9 +195,7 @@
sp<IDevice> device;
#if MAJOR_VERSION == 2
IDevicesFactory::Device dev = IDevicesFactory::IDevicesFactory::Device(-1);
- if (name == AUDIO_HARDWARE_MODULE_ID_PRIMARY) {
- dev = IDevicesFactory::Device::PRIMARY;
- } else if (name == AUDIO_HARDWARE_MODULE_ID_A2DP) {
+ if (name == AUDIO_HARDWARE_MODULE_ID_A2DP) {
dev = IDevicesFactory::Device::A2DP;
} else if (name == AUDIO_HARDWARE_MODULE_ID_USB) {
dev = IDevicesFactory::Device::USB;
@@ -179,47 +217,62 @@
}
return device;
}
+};
- static sp<IPrimaryDevice> openPrimaryDevice(const sp<IDevicesFactory>& factory) {
- if (factory == nullptr) return {};
- Result result;
- sp<IDevice> device;
- sp<IPrimaryDevice> primaryDevice;
-#if MAJOR_VERSION == 2
- auto ret = factory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, device));
- if (ret.isOk() && result == Result::OK && device != nullptr) {
- primaryDevice = IPrimaryDevice::castFrom(device);
+} // namespace impl
+
+class DeviceManager {
+ public:
+ static DeviceManager& getInstance() {
+ static DeviceManager instance;
+ return instance;
+ }
+
+ static constexpr const char* kPrimaryDevice = "primary";
+
+ sp<IDevice> get(const std::string& factoryName, const std::string& name) {
+ if (name == kPrimaryDevice) {
+ auto primary = getPrimary(factoryName);
+ return primary ? deviceFromPrimary(primary) : nullptr;
}
-#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0))
- auto ret = factory->openPrimaryDevice(returnIn(result, device));
- if (ret.isOk() && result == Result::OK && device != nullptr) {
- primaryDevice = IPrimaryDevice::castFrom(device);
- }
-#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1
- auto ret = factory->openPrimaryDevice_7_1(returnIn(result, primaryDevice));
- if (ret.isOk() && result == Result::OK && primaryDevice != nullptr) {
- auto getDeviceRet = primaryDevice->getDevice();
- if (getDeviceRet.isOk()) {
- device = getDeviceRet;
- } else {
- primaryDevice.clear();
- ALOGW("Primary device can not downcast, transaction: %s, primary %p",
- getDeviceRet.description().c_str(), primaryDevice.get());
- return {};
- }
- }
-#endif
- if (!ret.isOk() || result != Result::OK || device == nullptr) {
- ALOGW("Primary device can not be opened, transaction: %s, result %d, device %p",
- ret.description().c_str(), result, device.get());
- return {};
- }
- return primaryDevice;
+ return mDevices.get(factoryName, name);
+ }
+
+ sp<IPrimaryDevice> getPrimary(const std::string& factoryName) {
+ return mPrimary.get(factoryName);
+ }
+
+ bool reset(const std::string& factoryName, const std::string& name)
+ __attribute__((warn_unused_result)) {
+ return name == kPrimaryDevice ? resetPrimary(factoryName)
+ : mDevices.reset(factoryName, name);
+ }
+
+ bool resetPrimary(const std::string& factoryName) __attribute__((warn_unused_result)) {
+ return mPrimary.reset(factoryName);
+ }
+
+ static void waitForInstanceDestruction() {
+ // Does not matter which device manager to use.
+ impl::RegularDeviceManager::waitForInstanceDestruction();
}
private:
- // There can only be one primary device across all HAL modules.
- // A reference to a complete interface is used because in V7.1 IDevice can not
- // be upcasted to IPrimaryDevice.
- sp<IPrimaryDevice> primaryDevice;
+ sp<IDevice> deviceFromPrimary(const sp<IPrimaryDevice>& primary) {
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ auto ret = primary->getDevice();
+ if (ret.isOk()) {
+ return ret;
+ } else {
+ ALOGW("Error retrieving IDevice from primary: transaction: %s, primary %p",
+ ret.description().c_str(), primary.get());
+ return nullptr;
+ }
+#else
+ return primary;
+#endif
+ }
+
+ impl::PrimaryDeviceManager mPrimary;
+ impl::RegularDeviceManager mDevices;
};
diff --git a/audio/effect/all-versions/vts/functional/Android.bp b/audio/effect/all-versions/vts/functional/Android.bp
index 48d6474..3b15ed4 100644
--- a/audio/effect/all-versions/vts/functional/Android.bp
+++ b/audio/effect/all-versions/vts/functional/Android.bp
@@ -26,6 +26,9 @@
cc_defaults {
name: "VtsHalAudioEffectTargetTest_default",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "VtsHalAudioEffectTargetTest.cpp",
+ ],
srcs: [
"VtsHalAudioEffectTargetTest.cpp",
"ValidateAudioEffectsConfiguration.cpp",
diff --git a/automotive/audiocontrol/aidl/Android.bp b/automotive/audiocontrol/aidl/Android.bp
index 4acfd82..623097c 100644
--- a/automotive/audiocontrol/aidl/Android.bp
+++ b/automotive/audiocontrol/aidl/Android.bp
@@ -13,11 +13,17 @@
name: "android.hardware.automotive.audiocontrol",
vendor_available: true,
srcs: ["android/hardware/automotive/audiocontrol/*.aidl"],
+ imports: [
+ "android.media.audio.common.types",
+ "android.hardware.audio.common",
+ ],
stability: "vintf",
backend: {
java: {
- sdk_version: "module_current",
+ platform_apis: true,
},
},
- versions: ["1"],
+ versions: [
+ "1",
+ ],
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
index 3dc393a..58a3667 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl
similarity index 85%
rename from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
rename to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl
index 766f637..fb6ac65 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * 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.
@@ -31,10 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.bluetooth.audio;
-@Backing(type="byte") @VintfStability
-enum LeAudioMode {
- UNKNOWN = 0,
- UNICAST = 1,
- BROADCAST = 2,
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioGainConfigInfo {
+ int zoneId;
+ String devicePortAddress;
+ int volumeIndex;
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
index 6d729e2..23abb46 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -22,4 +38,5 @@
String[] deviceAddressesToDuck;
String[] deviceAddressesToUnduck;
String[] usagesHoldingFocus;
+ @nullable android.hardware.audio.common.PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index bc4162b..8dc5ffe 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -18,10 +34,16 @@
package android.hardware.automotive.audiocontrol;
@VintfStability
interface IAudioControl {
+ /**
+ * @deprecated use {@link android.hardware.audio.common.PlaybackTrackMetadata} instead.
+ */
oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
oneway void onDevicesToDuckChange(in android.hardware.automotive.audiocontrol.DuckingInfo[] duckingInfos);
oneway void onDevicesToMuteChange(in android.hardware.automotive.audiocontrol.MutingInfo[] mutingInfos);
oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener);
oneway void setBalanceTowardRight(in float value);
oneway void setFadeTowardFront(in float value);
+ oneway void onAudioFocusChangeWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
+ oneway void setAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
+ oneway void registerGainCallback(in android.hardware.automotive.audiocontrol.IAudioGainCallback callback);
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl
similarity index 82%
copy from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl
index 766f637..17a087f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * 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.
@@ -31,10 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.bluetooth.audio;
-@Backing(type="byte") @VintfStability
-enum LeAudioMode {
- UNKNOWN = 0,
- UNICAST = 1,
- BROADCAST = 2,
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+interface IAudioGainCallback {
+ oneway void onAudioDeviceGainsChanged(in android.hardware.automotive.audiocontrol.Reasons[] reasons, in android.hardware.automotive.audiocontrol.AudioGainConfigInfo[] gains);
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl
index f00f042..3e17552 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
@@ -20,4 +36,6 @@
interface IFocusListener {
oneway void abandonAudioFocus(in String usage, in int zoneId);
oneway void requestAudioFocus(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain);
+ oneway void abandonAudioFocusWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId);
+ oneway void requestAudioFocusWithMetaData(in android.hardware.audio.common.PlaybackTrackMetadata playbackMetaData, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain);
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl
index ab902ec..b25ed0f 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl
@@ -1,14 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
//
-// You must not make a backward incompatible changes to the AIDL files built
+// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
similarity index 79%
copy from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
index 766f637..c1e22d4 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * 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.
@@ -31,10 +31,17 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.hardware.bluetooth.audio;
-@Backing(type="byte") @VintfStability
-enum LeAudioMode {
- UNKNOWN = 0,
- UNICAST = 1,
- BROADCAST = 2,
+package android.hardware.automotive.audiocontrol;
+@Backing(type="int") @VintfStability
+enum Reasons {
+ FORCED_MASTER_MUTE = 1,
+ REMOTE_MUTE = 2,
+ TCU_MUTE = 4,
+ ADAS_DUCKING = 8,
+ NAV_DUCKING = 16,
+ PROJECTION_DUCKING = 32,
+ THERMAL_LIMITATION = 64,
+ SUSPEND_EXIT_VOL_LIMITATION = 128,
+ EXTERNAL_AMP_VOL_FEEDBACK = 256,
+ OTHER = -2147483648,
}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl
new file mode 100644
index 0000000..c938296
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioGainConfigInfo.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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 android.hardware.automotive.audiocontrol;
+
+/**
+ * NOTE:
+ * Was expecting to reuse android.media.audio types... Limit info to minimum to prevent
+ * duplicating aidl_api. Will follow up if AudioGainConfig is exposed by android.media AIDL API.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioGainConfigInfo {
+ /**
+ * The identifier for the audio zone the audio device port associated to this gain belongs to.
+ *
+ */
+ int zoneId;
+
+ /**
+ * The Audio Output Device Port Address.
+ *
+ * This is the address that can be retrieved at JAVA layer using the introspection
+ * {@link android.media.AudioManager#listAudioDevicePorts} API then
+ * {@link audio.media.AudioDeviceInfo#getAddress} API.
+ *
+ * At HAL layer, it corresponds to audio_port_v7.audio_port_device_ext.address.
+ *
+ * Devices that does not have an address will indicate an empty string "".
+ */
+ String devicePortAddress;
+
+ /**
+ * UI Index of the corresponding AudioGain in AudioPort.gains.
+ */
+ int volumeIndex;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
index e95fe9b..c30d5f6 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
@@ -14,7 +14,9 @@
* limitations under the License.
*/
- package android.hardware.automotive.audiocontrol;
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.audio.common.PlaybackTrackMetadata;
/**
* The current ducking information for a single audio zone.
@@ -48,7 +50,15 @@
/**
* List of usages currently holding focus for this audio zone.
*
+ * This field was deprecated in version 2.
+ * Use playbackMetaDataHoldingFocus instead.
+ *
* <p> See {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
*/
String[] usagesHoldingFocus;
- }
\ No newline at end of file
+
+ /**
+ * List of output stream metadata associated with the current focus holder for this audio zone
+ */
+ @nullable PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index 3a02245..100f1ba 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -20,6 +20,40 @@
import android.hardware.automotive.audiocontrol.DuckingInfo;
import android.hardware.automotive.audiocontrol.MutingInfo;
import android.hardware.automotive.audiocontrol.IFocusListener;
+import android.hardware.automotive.audiocontrol.IAudioGainCallback;
+import android.hardware.automotive.audiocontrol.AudioGainConfigInfo;
+import android.hardware.automotive.audiocontrol.Reasons;
+
+/**
+ * Important note on Metadata:
+ * Metadata qualifies a playback track for an output stream.
+ * This is highly closed to {@link android.media.AudioAttributes}.
+ * It allows to identify the audio stream rendered / requesting / abandonning the focus.
+ *
+ * AudioControl 1.0 was limited to identification through {@code AttributeUsage} listed as
+ * {@code audioUsage} in audio_policy_configuration.xsd.
+ *
+ * Any new OEM needs would not be possible without extension.
+ *
+ * Relying on {@link android.hardware.automotive.audiocontrol.PlaybackTrackMetadata} allows
+ * to use a combination of {@code AttributeUsage}, {@code AttributeContentType} and
+ * {@code AttributeTags} to identify the use case / routing thanks to
+ * {@link android.media.audiopolicy.AudioProductStrategy}.
+ * The belonging to a strategy is deduced by an AOSP logic (in sync at native and java layer).
+ *
+ * IMPORTANT NOTE ON TAGS:
+ * To limit the possibilies and prevent from confusion, we expect the String to follow
+ * a given formalism that will be enforced.
+ *
+ * 1 / By convention, tags shall be a "key=value" pair.
+ * Vendor must namespace their tag's key (for example com.google.strategy=VR) to avoid conflicts.
+ * vendor specific applications and must be prefixed by "VX_". Vendor must
+ *
+ * 2 / Tags reported here shall be the same as the tags used to define a given
+ * {@link android.media.audiopolicy.AudioProductStrategy} and so in
+ * audio_policy_engine_configuration.xml file.
+ */
+import android.hardware.audio.common.PlaybackTrackMetadata;
/**
* Interacts with the car's audio subsystem to manage audio sources and volumes
@@ -36,8 +70,12 @@
* The HAL is not required to wait for an callback of AUDIOFOCUS_GAIN before playing audio, nor
* is it required to stop playing audio in the event of a AUDIOFOCUS_LOSS callback is received.
*
+ * This method was deprecated in version 2 to allow getting rid of usages limitation.
+ * Use {@link IAudioControl#onAudioFocusChangeWithMetaData} instead.
+ *
* @param usage The audio usage associated with the focus change {@code AttributeUsage}. See
* {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
+ * @deprecated use {@link android.hardware.audio.common.PlaybackTrackMetadata} instead.
* @param zoneId The identifier for the audio zone that the HAL is playing the stream in
* @param focusChange the AudioFocusChange that has occurred.
*/
@@ -99,4 +137,51 @@
* range.
*/
oneway void setFadeTowardFront(in float value);
-}
\ No newline at end of file
+
+ /**
+ * Notifies HAL of changes in audio focus status for focuses requested or abandoned by the HAL.
+ *
+ * This will be called in response to IFocusListener's requestAudioFocus and
+ * abandonAudioFocus, as well as part of any change in focus being held by the HAL due focus
+ * request from other activities or services.
+ *
+ * The HAL is not required to wait for an callback of AUDIOFOCUS_GAIN before playing audio, nor
+ * is it required to stop playing audio in the event of a AUDIOFOCUS_LOSS callback is received.
+ *
+ * @param playbackMetaData The output stream metadata associated with the focus request
+ * @param zoneId The identifier for the audio zone that the HAL is playing the stream in
+ * @param focusChange the AudioFocusChange that has occurred.
+ */
+ oneway void onAudioFocusChangeWithMetaData(in PlaybackTrackMetadata playbackMetaData,
+ in int zoneId, in AudioFocusChange focusChange);
+
+ /**
+ * Notifies HAL of changes in output devices that the HAL should apply gain change to
+ * and the reason(s) why
+ *
+ * This may be called in response to changes in audio focus, and will include a list of
+ * {@link android.hardware.automotive.audiocontrol.AudioGainConfigInfo} objects per audio zone
+ * that experienced a change in audo focus.
+ *
+ * @param reasons List of reasons that triggered the given gains changed.
+ * This must be one or more of the
+ * {@link android.hardware.automotive.audiocontrol.Reasons} constants.
+ *
+ * @param gains List of gains the change is intended to.
+ */
+ oneway void setAudioDeviceGainsChanged(in Reasons[] reasons, in AudioGainConfigInfo[] gains);
+
+ /**
+ * Registers callback to be used by HAL for reporting unexpected gain(s) changed and the
+ * reason(s) why.
+ *
+ * It is expected that there will only ever be a single callback registered. If the
+ * observer dies, the HAL implementation must unregister observer automatically. If called when
+ * a listener is already registered, the existing one should be unregistered and replaced with
+ * the new callback.
+ *
+ * @param callback The {@link android.hardware.automotive.audiocontrol.IAudioGainCallback}
+ * interface.
+ */
+ oneway void registerGainCallback(in IAudioGainCallback callback);
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl
new file mode 100644
index 0000000..17b4341
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioGainCallback.aidl
@@ -0,0 +1,65 @@
+/*
+ * 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 android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioGainConfigInfo;
+import android.hardware.automotive.audiocontrol.Reasons;
+
+/**
+ * Interface definition for a callback to be invoked when the gain(s) of the device port(s) is(are)
+ * updated at HAL layer.
+ *
+ * <p>This defines counter part API of
+ * {@link android.hardware.automotive.audiocontrol.IAudioControl#onDevicesToDuckChange},
+ * {@link android.hardware.automotive.audiocontrol.IAudioControl#onDevicesToMuteChange} and
+ * {@link android.hardware.automotive.audiocontrol.IAudioControl#setAudioDeviceGainsChanged} APIs.
+ *
+ * The previous API defines Mute/Duck order decided by the client (e.g. CarAudioService)
+ * and delegated to AudioControl for application.
+ *
+ * This callback interface defines Mute/Duck notification decided by AudioControl HAL (due to
+ * e.g. - external conditions from Android IVI subsystem
+ * - regulation / need faster decision rather than using
+ * {@link android.hardware.automotive.audiocontrol.IAudioControl#onAudioFocusChange} to
+ * report the use case and then waiting for CarAudioService decision to Mute/Duck.
+ */
+@VintfStability
+oneway interface IAudioGainCallback {
+ /**
+ * Used to indicated the one or more audio device port gains have changed unexpectidely, i.e.
+ * initiated by HAL, not by CarAudioService.
+ * This is the counter part of the
+ * {@link android.hardware.automotive.audiocontrol.onDevicesToDuckChange},
+ * {@link android.hardware.automotive.audiocontrol.onDevicesToMuteChange} and
+ * {@link android.hardware.automotive.audiocontrol.setAudioDeviceGainsChanged} APIs.
+ *
+ * Flexibility is given to OEM to mute/duck in HAL or in CarAudioService.
+ * For critical use cases (i.e. when regulation is required), better to handle mute/duck in
+ * HAL layer and informs upper layer.
+ * Non critical use case may report gain and focus and CarAudioService to decide of duck/mute.
+ *
+ * @param reasons List of reasons that triggered the given gains changed.
+ * This must be one or more of the
+ * {@link android.hardware.automotive.audiocontrol.Reasons} constants.
+ * It will define if the port has been muted/ducked or must now affected
+ * by gain limitation that shall be notified/enforced at CarAudioService
+ * layer.
+ *
+ * @param gains List of gains affected by the change.
+ */
+ void onAudioDeviceGainsChanged(in Reasons[] reasons, in AudioGainConfigInfo[] gains);
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl
index b79295a..1ce1f40 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl
@@ -18,10 +18,13 @@
import android.hardware.automotive.audiocontrol.AudioFocusChange;
+import android.hardware.audio.common.PlaybackTrackMetadata;
+
/**
* Callback interface for audio focus listener.
*
* For typical configuration, the listener the car audio service.
+ *
*/
@VintfStability
interface IFocusListener {
@@ -33,6 +36,9 @@
* interaction is oneway to avoid blocking HAL so that it is not required to wait for a response
* before stopping audio playback.
*
+ * Deprecated in version 2 to allow generic interface callback listener.
+ * Use {@link IFocusListener#abandonHalAudioFocusWithMetaData} instead.
+ *
* @param usage The audio usage for which the HAL is abandoning focus {@code AttributeUsage}.
* See {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
* @param zoneId The identifier for the audio zone that the HAL abandoning focus
@@ -47,6 +53,9 @@
* interaction is oneway to avoid blocking HAL so that it is not required to wait for a response
* before playing audio.
*
+ * Deprecated in version 2 to allow generic interface callback listener.
+ * Use {@link IFocusListener#requestAudioFocusWithMetaData} instead.
+ *
* @param usage The audio usage associated with the focus request {@code AttributeUsage}. See
* {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
* @param zoneId The identifier for the audio zone where the HAL is requesting focus
@@ -54,4 +63,29 @@
* following: GAIN, GAIN_TRANSIENT, GAIN_TRANSIENT_MAY_DUCK, GAIN_TRANSIENT_EXCLUSIVE.
*/
oneway void requestAudioFocus(in String usage, in int zoneId, in AudioFocusChange focusGain);
-}
\ No newline at end of file
+
+ /**
+ * Used to indicate that the audio output stream associated with
+ * {@link android.hardware.audio.common.PlaybackTrackMetadata} has released
+ * the focus.
+ *
+ * @param playbackMetaData The output stream metadata associated with the focus request
+ * @param zoneId The identifier for the audio zone that the HAL abandoning focus
+ */
+ oneway void abandonAudioFocusWithMetaData(in PlaybackTrackMetadata playbackMetaData,
+ in int zoneId);
+
+ /**
+ * Used to indicate that the audio output stream associated with
+ * {@link android.hardware.audio.common.PlaybackTrackMetadata} has taken the focus.
+ *
+ * @param playbackMetaData The output stream metadata associated with the focus request
+ * @param zoneId The identifier for the audio zone that the HAL abandoning focus
+ * @param focusGain The focus type requested.
+ * This must be one of the
+ * {@link android.hardware.automotive.audiocontrol.AudioFocusChange}
+ * constants.
+ */
+ oneway void requestAudioFocusWithMetaData(in PlaybackTrackMetadata playbackMetaData,
+ in int zoneId, in AudioFocusChange focusGain);
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/Reasons.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/Reasons.aidl
new file mode 100644
index 0000000..3d9e8a2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/Reasons.aidl
@@ -0,0 +1,85 @@
+/*
+ * 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 android.hardware.automotive.audiocontrol;
+
+/**
+ * Enum to identify the reason(s) of
+ * {@link android.hardware.automotive.audiocontrol.AudioGainConfigInfo} changed event
+ */
+@Backing(type="int")
+@VintfStability
+enum Reasons {
+ /**
+ * Magic Key Code (may be SWRC button combination) to force muting all audio sources.
+ * This may be used for example in case of cyber attach to ensure driver can safely drive back
+ * to garage to restore sw.
+ */
+ FORCED_MASTER_MUTE = 0x1,
+ /**
+ * Reports a mute request outside the IVI (Android) system.
+ * It may target to mute the list of
+ * {@link android.hardware.automotive.audiocontrol.AudioGainConfigInfo}.
+ * A focus request may also be reported in addition if the use case that initiates the mute
+ * has matching {@link android.hardware.automotive.audiocontrol.PlaybackTrackMetadata}
+ * For regulation issue, the action of mute could be managed by HAL itself.
+ */
+ REMOTE_MUTE = 0x2,
+ /**
+ * Reports a mute initiated by the TCU. It may be applied to all audio source (no
+ * associated {@link android.hardware.automotive.audiocontrol.AudioGainConfigInfo} reported, or
+ * it may target to mute only the given list of ports.
+ * A focus request may also be reported in addition.
+ * For regulation issue, the action of mute could be managed by HAL itself.
+ */
+ TCU_MUTE = 0x4,
+ /**
+ * Reports a duck due to ADAS use case. A focus request may also be reported in addition.
+ * For regulation issue, the action of duck could be managed by HAL itself.
+ * It gives a chance to CarAudioService to decide whether contextual volume change may be
+ * applied from the ducked index base or not.
+ */
+ ADAS_DUCKING = 0x8,
+ /**
+ * Reports a duck due to navigation use case. It gives a chance to CarAudioService to decide
+ * whether contextual volume change may be applied from the ducked index base or not.
+ */
+ NAV_DUCKING = 0x10,
+ /**
+ * Some device projection stack may send signal to IVI to duck / unduck main audio stream.
+ * In this case, Contextual Volume Policy may be adapted to control the alternate / secondary
+ * audio stream.
+ */
+ PROJECTION_DUCKING = 0x20,
+ /**
+ * When the amplifier is overheating, it may be recovered by limiting the volume.
+ */
+ THERMAL_LIMITATION = 0x40,
+ /**
+ * Before the system enters suspend, it may ensure while exiting suspend or during cold boot
+ * that the volume is limited to prevent from sound explosion.
+ */
+ SUSPEND_EXIT_VOL_LIMITATION = 0x80,
+ /**
+ * When using an external amplifier, it may be required to keep volume in sync and have
+ * asynchronous notification of effective volume change.
+ */
+ EXTERNAL_AMP_VOL_FEEDBACK = 0x100,
+ /**
+ * For other OEM use.
+ */
+ OTHER = 0x80000000,
+}
diff --git a/automotive/can/1.0/default/Android.bp b/automotive/can/1.0/default/Android.bp
index c0c17e2..31eabf6 100644
--- a/automotive/can/1.0/default/Android.bp
+++ b/automotive/can/1.0/default/Android.bp
@@ -46,13 +46,7 @@
vendor: true,
relative_install_path: "hw",
srcs: [
- "CanBus.cpp",
- "CanBusNative.cpp",
- "CanBusVirtual.cpp",
- "CanBusSlcan.cpp",
- "CanController.cpp",
- "CanSocket.cpp",
- "CloseHandle.cpp",
+ ":automotiveCanV1.0_sources",
"service.cpp",
],
shared_libs: [
@@ -65,3 +59,22 @@
"libnl++",
],
}
+
+filegroup {
+ name: "automotiveCanV1.0_sources",
+ srcs: [
+ "CanBus.cpp",
+ "CanBusNative.cpp",
+ "CanBusVirtual.cpp",
+ "CanBusSlcan.cpp",
+ "CanController.cpp",
+ "CanSocket.cpp",
+ "CloseHandle.cpp",
+ ],
+}
+
+cc_library_headers {
+ name: "automotiveCanV1.0_headers",
+ vendor: true,
+ export_include_dirs: ["."],
+}
diff --git a/automotive/can/1.0/default/tests/fuzzer/Android.bp b/automotive/can/1.0/default/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..52b43b0
--- /dev/null
+++ b/automotive/can/1.0/default/tests/fuzzer/Android.bp
@@ -0,0 +1,54 @@
+/*
+ * 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_fuzz {
+ name: "automotiveCanV1.0_fuzzer",
+ vendor: true,
+ defaults: ["android.hardware.automotive.can@defaults"],
+ srcs: [
+ "AutomotiveCanV1_0Fuzzer.cpp",
+ ":automotiveCanV1.0_sources",
+ ],
+ header_libs: [
+ "automotiveCanV1.0_headers",
+ "android.hardware.automotive.can@hidl-utils-lib",
+ ],
+ shared_libs: [
+ "android.hardware.automotive.can@1.0",
+ "libhidlbase",
+ ],
+ static_libs: [
+ "android.hardware.automotive.can@libnetdevice",
+ "android.hardware.automotive@libc++fs",
+ "libnl++",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 533764,
+ },
+}
diff --git a/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.cpp b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.cpp
new file mode 100644
index 0000000..96110db
--- /dev/null
+++ b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ *
+ */
+#include "AutomotiveCanV1_0Fuzzer.h"
+
+namespace android::hardware::automotive::can::V1_0::implementation::fuzzer {
+
+constexpr CanController::InterfaceType kInterfaceType[] = {CanController::InterfaceType::VIRTUAL,
+ CanController::InterfaceType::SOCKETCAN,
+ CanController::InterfaceType::SLCAN};
+constexpr FilterFlag kFilterFlag[] = {FilterFlag::DONT_CARE, FilterFlag::SET, FilterFlag::NOT_SET};
+constexpr size_t kInterfaceTypeLength = std::size(kInterfaceType);
+constexpr size_t kFilterFlagLength = std::size(kFilterFlag);
+constexpr size_t kMaxCharacters = 30;
+constexpr size_t kMaxPayloadBytes = 64;
+constexpr size_t kMaxFilters = 20;
+constexpr size_t kMaxSerialNumber = 1000;
+constexpr size_t kMaxBuses = 10;
+constexpr size_t kMaxRepeat = 5;
+
+Bus CanFuzzer::makeBus() {
+ ICanController::BusConfig config = {};
+ if (mBusNames.size() > 0 && mLastInterface < mBusNames.size()) {
+ config.name = mBusNames[mLastInterface++];
+ } else {
+ config.name = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
+ }
+ config.interfaceId.virtualif({mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters)});
+ return Bus(mCanController, config);
+}
+
+void CanFuzzer::getSupportedInterfaceTypes() {
+ hidl_vec<CanController::InterfaceType> iftypesResult;
+ mCanController->getSupportedInterfaceTypes(hidl_utils::fill(&iftypesResult));
+}
+
+hidl_vec<hidl_string> CanFuzzer::getBusNames() {
+ hidl_vec<hidl_string> services = {};
+ if (auto manager = hidl::manager::V1_2::IServiceManager::getService(); manager) {
+ manager->listManifestByInterface(ICanBus::descriptor, hidl_utils::fill(&services));
+ }
+ return services;
+}
+
+void CanFuzzer::invokeUpInterface() {
+ const CanController::InterfaceType iftype =
+ kInterfaceType[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+ 0, kInterfaceTypeLength - 1)];
+ std::string configName;
+
+ if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
+ (shouldInvokeValidBus) && (mBusNames.size() > 0)) {
+ const size_t busNameIndex =
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
+ configName = mBusNames[busNameIndex];
+ } else {
+ configName = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
+ }
+ const std::string ifname = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
+
+ ICanController::BusConfig config = {.name = configName};
+
+ if (iftype == CanController::InterfaceType::SOCKETCAN) {
+ CanController::BusConfig::InterfaceId::Socketcan socketcan = {};
+ if (const bool shouldPassSerialSocket = mFuzzedDataProvider->ConsumeBool();
+ shouldPassSerialSocket) {
+ socketcan.serialno(
+ {mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxSerialNumber)});
+ } else {
+ socketcan.ifname(ifname);
+ }
+ config.interfaceId.socketcan(socketcan);
+ } else if (iftype == CanController::InterfaceType::SLCAN) {
+ CanController::BusConfig::InterfaceId::Slcan slcan = {};
+ if (const bool shouldPassSerialSlcan = mFuzzedDataProvider->ConsumeBool();
+ shouldPassSerialSlcan) {
+ slcan.serialno(
+ {mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxSerialNumber)});
+ } else {
+ slcan.ttyname(ifname);
+ }
+ config.interfaceId.slcan(slcan);
+ } else if (iftype == CanController::InterfaceType::VIRTUAL) {
+ config.interfaceId.virtualif({ifname});
+ }
+
+ const size_t numInvocations =
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kMaxRepeat);
+ for (size_t i = 0; i < numInvocations; ++i) {
+ mCanController->upInterface(config);
+ }
+}
+
+void CanFuzzer::invokeDownInterface() {
+ hidl_string configName;
+ if (const bool shouldInvokeValidBus = mFuzzedDataProvider->ConsumeBool();
+ (shouldInvokeValidBus) && (mBusNames.size() > 0)) {
+ const size_t busNameIndex =
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, mBusNames.size() - 1);
+ configName = mBusNames[busNameIndex];
+ } else {
+ configName = mFuzzedDataProvider->ConsumeRandomLengthString(kMaxCharacters);
+ }
+
+ const size_t numInvocations =
+ mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(0, kMaxRepeat);
+ for (size_t i = 0; i < numInvocations; ++i) {
+ mCanController->downInterface(configName);
+ }
+}
+
+void CanFuzzer::invokeController() {
+ getSupportedInterfaceTypes();
+ invokeUpInterface();
+ invokeDownInterface();
+}
+
+void CanFuzzer::invokeBus() {
+ const size_t numBuses = mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(1, kMaxBuses);
+ for (size_t i = 0; i < numBuses; ++i) {
+ if (const bool shouldSendMessage = mFuzzedDataProvider->ConsumeBool(); shouldSendMessage) {
+ auto sendingBus = makeBus();
+ CanMessage msg = {.id = mFuzzedDataProvider->ConsumeIntegral<uint32_t>()};
+ uint32_t numPayloadBytes =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kMaxPayloadBytes);
+ hidl_vec<uint8_t> payload(numPayloadBytes);
+ for (uint32_t j = 0; j < numPayloadBytes; ++j) {
+ payload[j] = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
+ }
+ msg.payload = payload;
+ msg.remoteTransmissionRequest = mFuzzedDataProvider->ConsumeBool();
+ msg.isExtendedId = mFuzzedDataProvider->ConsumeBool();
+ sendingBus.send(msg);
+ } else {
+ auto listeningBus = makeBus();
+ uint32_t numFilters =
+ mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(1, kMaxFilters);
+ hidl_vec<CanMessageFilter> filterVector(numFilters);
+ for (uint32_t k = 0; k < numFilters; ++k) {
+ filterVector[k].id = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
+ filterVector[k].mask = mFuzzedDataProvider->ConsumeIntegral<uint32_t>();
+ filterVector[k].rtr =
+ kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+ 0, kFilterFlagLength - 1)];
+ filterVector[k].extendedFormat =
+ kFilterFlag[mFuzzedDataProvider->ConsumeIntegralInRange<size_t>(
+ 0, kFilterFlagLength - 1)];
+ filterVector[k].exclude = mFuzzedDataProvider->ConsumeBool();
+ }
+ auto listener = listeningBus.listen(filterVector);
+ }
+ }
+}
+
+void CanFuzzer::deInit() {
+ mCanController.clear();
+ if (mFuzzedDataProvider) {
+ delete mFuzzedDataProvider;
+ }
+ mBusNames = {};
+}
+
+void CanFuzzer::process(const uint8_t* data, size_t size) {
+ mFuzzedDataProvider = new FuzzedDataProvider(data, size);
+ invokeController();
+ invokeBus();
+}
+
+bool CanFuzzer::init() {
+ mCanController = sp<CanController>::make();
+ if (!mCanController) {
+ return false;
+ }
+ mBusNames = getBusNames();
+ return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size < 1) {
+ return 0;
+ }
+ CanFuzzer canFuzzer;
+ if (canFuzzer.init()) {
+ canFuzzer.process(data, size);
+ }
+ return 0;
+}
+
+} // namespace android::hardware::automotive::can::V1_0::implementation::fuzzer
diff --git a/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.h b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.h
new file mode 100644
index 0000000..930cddd
--- /dev/null
+++ b/automotive/can/1.0/default/tests/fuzzer/AutomotiveCanV1_0Fuzzer.h
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ *
+ */
+#ifndef __AUTOMOTIVE_CAN_V1_0_FUZZER_H__
+#define __AUTOMOTIVE_CAN_V1_0_FUZZER_H__
+#include <CanController.h>
+#include <android/hidl/manager/1.2/IServiceManager.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <hidl-utils/hidl-utils.h>
+
+namespace android::hardware::automotive::can::V1_0::implementation::fuzzer {
+
+using ::android::sp;
+
+struct CanMessageListener : public can::V1_0::ICanMessageListener {
+ DISALLOW_COPY_AND_ASSIGN(CanMessageListener);
+
+ CanMessageListener() {}
+
+ virtual Return<void> onReceive(const can::V1_0::CanMessage& msg) override {
+ std::unique_lock<std::mutex> lock(mMessagesGuard);
+ mMessages.push_back(msg);
+ mMessagesUpdated.notify_one();
+ return {};
+ }
+
+ virtual ~CanMessageListener() {
+ if (mCloseHandle) {
+ mCloseHandle->close();
+ }
+ }
+
+ void assignCloseHandle(sp<ICloseHandle> closeHandle) { mCloseHandle = closeHandle; }
+
+ private:
+ sp<ICloseHandle> mCloseHandle;
+
+ std::mutex mMessagesGuard;
+ std::condition_variable mMessagesUpdated GUARDED_BY(mMessagesGuard);
+ std::vector<can::V1_0::CanMessage> mMessages GUARDED_BY(mMessagesGuard);
+};
+
+struct Bus {
+ DISALLOW_COPY_AND_ASSIGN(Bus);
+
+ Bus(sp<ICanController> controller, const ICanController::BusConfig& config)
+ : mIfname(config.name), mController(controller) {
+ const auto result = controller->upInterface(config);
+ const auto manager = hidl::manager::V1_2::IServiceManager::getService();
+ const auto service = manager->get(ICanBus::descriptor, config.name);
+ mBus = ICanBus::castFrom(service);
+ }
+
+ virtual ~Bus() { reset(); }
+
+ void reset() {
+ mBus.clear();
+ if (mController) {
+ mController->downInterface(mIfname);
+ mController.clear();
+ }
+ }
+
+ ICanBus* operator->() const { return mBus.get(); }
+ sp<ICanBus> get() { return mBus; }
+
+ sp<CanMessageListener> listen(const hidl_vec<CanMessageFilter>& filter) {
+ sp<CanMessageListener> listener = sp<CanMessageListener>::make();
+
+ if (!mBus) {
+ return listener;
+ }
+ Result result;
+ sp<ICloseHandle> closeHandle;
+ mBus->listen(filter, listener, hidl_utils::fill(&result, &closeHandle)).assertOk();
+ listener->assignCloseHandle(closeHandle);
+
+ return listener;
+ }
+
+ void send(const CanMessage& msg) {
+ if (!mBus) {
+ return;
+ }
+ mBus->send(msg);
+ }
+
+ private:
+ const std::string mIfname;
+ sp<ICanController> mController;
+ sp<ICanBus> mBus;
+};
+
+class CanFuzzer {
+ public:
+ ~CanFuzzer() { deInit(); }
+ bool init();
+ void process(const uint8_t* data, size_t size);
+ void deInit();
+
+ private:
+ Bus makeBus();
+ hidl_vec<hidl_string> getBusNames();
+ void getSupportedInterfaceTypes();
+ void invokeBus();
+ void invokeController();
+ void invokeUpInterface();
+ void invokeDownInterface();
+ FuzzedDataProvider* mFuzzedDataProvider = nullptr;
+ sp<CanController> mCanController = nullptr;
+ hidl_vec<hidl_string> mBusNames = {};
+ unsigned mLastInterface = 0;
+};
+} // namespace android::hardware::automotive::can::V1_0::implementation::fuzzer
+
+#endif // __AUTOMOTIVE_CAN_V1_0_FUZZER_H__
diff --git a/automotive/evs/1.1/vts/functional/Android.bp b/automotive/evs/1.1/vts/functional/Android.bp
index cbc2150..18687bf 100644
--- a/automotive/evs/1.1/vts/functional/Android.bp
+++ b/automotive/evs/1.1/vts/functional/Android.bp
@@ -25,6 +25,9 @@
cc_test {
name: "VtsHalEvsV1_1TargetTest",
+ tidy_timeout_srcs: [
+ "VtsHalEvsV1_1TargetTest.cpp",
+ ],
srcs: [
"FrameHandler.cpp",
"FrameHandlerUltrasonics.cpp",
diff --git a/automotive/sv/1.0/vts/functional/Android.bp b/automotive/sv/1.0/vts/functional/Android.bp
index 1ff3450..e94893c 100644
--- a/automotive/sv/1.0/vts/functional/Android.bp
+++ b/automotive/sv/1.0/vts/functional/Android.bp
@@ -25,6 +25,9 @@
cc_test {
name: "VtsHalSurroundViewV1_0TargetTest",
+ tidy_timeout_srcs: [
+ "VtsHalSurroundViewV1_0TargetTest.cpp",
+ ],
srcs: [
"VtsHalSurroundViewV1_0TargetTest.cpp",
"SurroundViewStreamHandler.cpp",
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 869c0c9..14177dd 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -172,6 +172,9 @@
vendor: true,
defaults: ["vhal_v2_0_target_defaults"],
whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
+ tidy_timeout_srcs: [
+ "tests/VmsUtils_test.cpp",
+ ],
srcs: [
"tests/RecurrentTimer_test.cpp",
"tests/SubscriptionManager_test.cpp",
diff --git a/automotive/vehicle/2.0/utils/Android.bp b/automotive/vehicle/2.0/utils/Android.bp
index a75ce49..770d447 100644
--- a/automotive/vehicle/2.0/utils/Android.bp
+++ b/automotive/vehicle/2.0/utils/Android.bp
@@ -39,6 +39,9 @@
name: "android.hardware.automotive.vehicle@2.0-utils-unit-tests",
defaults: ["vhal_v2_0_defaults"],
vendor: true,
+ tidy_timeout_srcs: [
+ "tests/UserHalHelper_test.cpp",
+ ],
srcs: [
"tests/UserHalHelper_test.cpp",
],
diff --git a/biometrics/fingerprint/2.1/vts/functional/Android.bp b/biometrics/fingerprint/2.1/vts/functional/Android.bp
index 0935bf6..68b3360 100644
--- a/biometrics/fingerprint/2.1/vts/functional/Android.bp
+++ b/biometrics/fingerprint/2.1/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalBiometricsFingerprintV2_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalBiometricsFingerprintV2_1TargetTest.cpp"],
srcs: ["VtsHalBiometricsFingerprintV2_1TargetTest.cpp"],
static_libs: ["android.hardware.biometrics.fingerprint@2.1"],
test_suites: ["general-tests", "vts"],
diff --git a/bluetooth/audio/2.1/vts/functional/Android.bp b/bluetooth/audio/2.1/vts/functional/Android.bp
index 3314a8a..cea7326 100644
--- a/bluetooth/audio/2.1/vts/functional/Android.bp
+++ b/bluetooth/audio/2.1/vts/functional/Android.bp
@@ -10,6 +10,7 @@
cc_test {
name: "VtsHalBluetoothAudioV2_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalBluetoothAudioV2_1TargetTest.cpp"],
srcs: ["VtsHalBluetoothAudioV2_1TargetTest.cpp"],
static_libs: [
"android.hardware.audio.common@5.0",
diff --git a/bluetooth/audio/2.2/Android.bp b/bluetooth/audio/2.2/Android.bp
deleted file mode 100644
index d66e84e..0000000
--- a/bluetooth/audio/2.2/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is autogenerated by hidl-gen -Landroidbp.
-
-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"],
-}
-
-hidl_interface {
- name: "android.hardware.bluetooth.audio@2.2",
- root: "android.hardware",
- srcs: [
- "types.hal",
- "IBluetoothAudioPort.hal",
- "IBluetoothAudioProvider.hal",
- "IBluetoothAudioProvidersFactory.hal",
- ],
- interfaces: [
- "android.hardware.audio.common@5.0",
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "android.hidl.base@1.0",
- "android.hidl.safe_union@1.0",
- ],
- apex_available: [
- "//apex_available:platform",
- "com.android.bluetooth",
- ],
- gen_java: false,
-}
diff --git a/bluetooth/audio/2.2/IBluetoothAudioPort.hal b/bluetooth/audio/2.2/IBluetoothAudioPort.hal
deleted file mode 100644
index 344899c..0000000
--- a/bluetooth/audio/2.2/IBluetoothAudioPort.hal
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.bluetooth.audio@2.2;
-
-import @2.0::IBluetoothAudioPort;
-import android.hardware.audio.common@5.0::SinkMetadata;
-
-interface IBluetoothAudioPort extends @2.0::IBluetoothAudioPort {
- /**
- * Called when the metadata of the stream's sink has been changed.
- *
- * @param sinkMetadata Description of the audio that is recorded by the
- * clients.
- */
- updateSinkMetadata(SinkMetadata sinkMetadata);
-};
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
deleted file mode 100644
index 7c91805..0000000
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.bluetooth.audio@2.2;
-
-import @2.1::IBluetoothAudioProvider;
-import @2.2::IBluetoothAudioPort;
-import @2.0::Status;
-
-/**
- * HAL interface from the Bluetooth stack to the Audio HAL
- *
- * The Bluetooth stack calls methods in this interface to start and end audio
- * sessions and sends callback events to the Audio HAL.
- *
- * Note: For HIDL APIs with a "generates" statement, the callback parameter used
- * for return value must be invoked synchronously before the API call returns.
- */
-interface IBluetoothAudioProvider extends @2.1::IBluetoothAudioProvider {
-
- /**
- * This method indicates that the Bluetooth stack is ready to stream audio.
- * It registers an instance of IBluetoothAudioPort with and provides the
- * current negotiated codec to the Audio HAL. After this method is called,
- * the Audio HAL can invoke IBluetoothAudioPort.startStream().
- *
- * Note: endSession() must be called to unregister this IBluetoothAudioPort
- *
- * @param hostIf An instance of IBluetoothAudioPort for stream control
- * @param audioConfig The audio configuration negotiated with the remote
- * device. The PCM parameters are set if software based encoding,
- * otherwise the correct codec configuration is used for hardware
- * encoding.
- *
- * @return status One of the following
- * SUCCESS if this IBluetoothAudioPort was successfully registered with
- * the Audio HAL
- * UNSUPPORTED_CODEC_CONFIGURATION if the Audio HAL cannot register this
- * IBluetoothAudioPort with the given codec configuration
- * FAILURE if the Audio HAL cannot register this IBluetoothAudioPort for
- * any other reason
- * @return dataMQ The fast message queue for audio data from/to this
- * provider. Audio data will be in PCM format as specified by the
- * audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
- * from/to hardware or on failure.
- */
- startSession_2_2(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
- generates (Status status, fmq_sync<uint8_t> dataMQ);
-
- /**
- * Called when the audio configuration of the stream has been changed.
- *
- * @param audioConfig The audio configuration negotiated with the remote
- * device. The PCM parameters are set if software based encoding,
- * otherwise the correct codec configuration is used for hardware
- * encoding.
- */
- updateAudioConfiguration(AudioConfiguration audioConfig);
-
- /**
- * Called when the supported latency mode is updated.
- *
- * @param allowed If the peripheral devices can't keep up with low latency
- * mode, the API will be called with supported is false.
- */
- setLowLatencyModeAllowed(bool allowed);
-};
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
deleted file mode 100644
index ae9c598..0000000
--- a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.bluetooth.audio@2.2;
-
-import IBluetoothAudioProvider;
-import @2.1::IBluetoothAudioProvidersFactory;
-import @2.0::Status;
-import @2.1::SessionType;
-
-/**
- * This factory allows a HAL implementation to be split into multiple
- * independent providers.
- *
- * When the Bluetooth stack is ready to create an audio session, it must first
- * obtain the IBluetoothAudioProvider for that session type by calling
- * openProvider().
- *
- * Note: For HIDL APIs with a "generates" statement, the callback parameter used
- * for return value must be invoked synchronously before the API call returns.
- */
-interface IBluetoothAudioProvidersFactory extends @2.1::IBluetoothAudioProvidersFactory {
- /**
- * Opens an audio provider for a session type. To close the provider, it is
- * necessary to release references to the returned provider object.
- *
- * @param sessionType The session type (e.g.
- * LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
- *
- * @return status One of the following
- * SUCCESS if the Audio HAL successfully opens the provider with the
- * given session type
- * FAILURE if the Audio HAL cannot open the provider
- * @return provider The provider of the specified session type
- */
- openProvider_2_2(SessionType sessionType)
- generates (Status status, IBluetoothAudioProvider provider);
-
- /**
- * Gets a list of audio capabilities for a session type.
- *
- * For software encoding, the PCM capabilities are returned.
- * For hardware encoding, the supported codecs and their capabilities are
- * returned.
- *
- * @param sessionType The session type (e.g.
- * A2DP_SOFTWARE_ENCODING_DATAPATH).
- * @return audioCapabilities A list containing all the capabilities
- * supported by the sesson type. The capabilities is a list of
- * available options when configuring the codec for the session.
- * For software encoding it is the PCM data rate.
- * For hardware encoding it is the list of supported codecs and their
- * capabilities.
- * If a provider isn't supported, an empty list should be returned.
- * Note: Only one entry should exist per codec when using hardware
- * encoding.
- */
- getProviderCapabilities_2_2(SessionType sessionType)
- generates (vec<AudioCapabilities> audioCapabilities);
-};
diff --git a/bluetooth/audio/2.2/OWNERS b/bluetooth/audio/2.2/OWNERS
deleted file mode 100644
index 84f5b1e..0000000
--- a/bluetooth/audio/2.2/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-aliceypkuo@google.com
-ugoyu@google.com
-sattiraju@google.com
diff --git a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
deleted file mode 100644
index 2a6d93a..0000000
--- a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderA2dpOffload"
-
-#include "A2dpOffloadAudioProvider.h"
-
-#include <android-base/logging.h>
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-
-#include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
-using ::android::hardware::kSynchronizedReadWrite;
-using ::android::hardware::MessageQueue;
-using ::android::hardware::Void;
-using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
-
-using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-A2dpOffloadAudioProvider::A2dpOffloadAudioProvider()
- : BluetoothAudioProvider() {
- session_type_ = V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
-}
-
-bool A2dpOffloadAudioProvider::isValid(const V2_0::SessionType& sessionType) {
- return isValid(static_cast<V2_1::SessionType>(sessionType));
-}
-
-bool A2dpOffloadAudioProvider::isValid(const V2_1::SessionType& sessionType) {
- return (sessionType == session_type_);
-}
-
-Return<void> A2dpOffloadAudioProvider::startSession(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- /**
- * Initialize the audio platform if audioConfiguration is supported.
- * Save the IBluetoothAudioPort interface, so that it can be used
- * later to send stream control commands to the HAL client, based on
- * interaction with Audio framework.
- */
- if (audioConfig.getDiscriminator() !=
- AudioConfiguration::hidl_discriminator::codecConfig) {
- LOG(WARNING) << __func__
- << " - Invalid Audio Configuration=" << toString(audioConfig);
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- } else if (!android::bluetooth::audio::IsOffloadCodecConfigurationValid(
- session_type_, audioConfig.codecConfig())) {
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- return BluetoothAudioProvider::startSession(hostIf, audioConfig, _hidl_cb);
-}
-
-Return<void> A2dpOffloadAudioProvider::onSessionReady(
- startSession_cb _hidl_cb) {
- BluetoothAudioSessionReport_2_2::OnSessionStarted(session_type_, stack_iface_,
- nullptr, audio_config_);
- _hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor());
- return Void();
-}
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.h
deleted file mode 100644
index 7ccdedc..0000000
--- a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BluetoothAudioProvider.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-class A2dpOffloadAudioProvider : public BluetoothAudioProvider {
- public:
- A2dpOffloadAudioProvider();
-
- bool isValid(const V2_1::SessionType& sessionType) override;
- bool isValid(const V2_0::SessionType& sessionType) override;
-
- Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_0::AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
-
- private:
- Return<void> onSessionReady(startSession_cb _hidl_cb) override;
-};
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
deleted file mode 100644
index eb87178..0000000
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderA2dpSoftware"
-
-#include "A2dpSoftwareAudioProvider.h"
-
-#include <android-base/logging.h>
-
-#include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_2.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
-using ::android::hardware::Void;
-using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
-
-// Here the buffer size is based on SBC
-static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo
-// SBC is 128, and here we choose the LCM of 16, 24, and 32
-static constexpr uint32_t kPcmFrameCount = 96;
-static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
-// The max counts by 1 tick (20ms) for SBC is about 7. Since using 96 for the
-// PCM counts, here we just choose a greater number
-static constexpr uint32_t kRtpFrameCount = 10;
-static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
-static constexpr uint32_t kBufferCount = 2; // double buffer
-static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
-
-A2dpSoftwareAudioProvider::A2dpSoftwareAudioProvider()
- : BluetoothAudioProvider(), mDataMQ(nullptr) {
- LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
- << " byte(s)";
- std::unique_ptr<DataMQ> tempDataMQ(
- new DataMQ(kDataMqSize, /* EventFlag */ true));
- if (tempDataMQ && tempDataMQ->isValid()) {
- mDataMQ = std::move(tempDataMQ);
- session_type_ = V2_1::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
- } else {
- ALOGE_IF(!tempDataMQ, "failed to allocate data MQ");
- ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "data MQ is invalid");
- }
-}
-
-bool A2dpSoftwareAudioProvider::isValid(const V2_0::SessionType& sessionType) {
- return isValid(static_cast<V2_1::SessionType>(sessionType));
-}
-
-bool A2dpSoftwareAudioProvider::isValid(const V2_1::SessionType& sessionType) {
- return (sessionType == session_type_ && mDataMQ && mDataMQ->isValid());
-}
-
-Return<void> A2dpSoftwareAudioProvider::startSession(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- /**
- * Initialize the audio platform if audioConfiguration is supported.
- * Save the IBluetoothAudioPort interface, so that it can be used
- * later to send stream control commands to the HAL client, based on
- * interaction with Audio framework.
- */
- if (audioConfig.getDiscriminator() !=
- AudioConfiguration::hidl_discriminator::pcmConfig) {
- LOG(WARNING) << __func__
- << " - Invalid Audio Configuration=" << toString(audioConfig);
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- } else if (!android::bluetooth::audio::IsSoftwarePcmConfigurationValid(
- audioConfig.pcmConfig())) {
- LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
- << toString(audioConfig.pcmConfig());
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- return BluetoothAudioProvider::startSession(hostIf, audioConfig, _hidl_cb);
-}
-
-Return<void> A2dpSoftwareAudioProvider::onSessionReady(
- startSession_cb _hidl_cb) {
- if (mDataMQ && mDataMQ->isValid()) {
- BluetoothAudioSessionReport_2_2::OnSessionStarted(
- session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
- _hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
- } else {
- _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
- }
- return Void();
-}
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
deleted file mode 100644
index ac3aece..0000000
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-
-#include "BluetoothAudioProvider.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::hardware::kSynchronizedReadWrite;
-using ::android::hardware::MessageQueue;
-
-using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-class A2dpSoftwareAudioProvider : public BluetoothAudioProvider {
- public:
- A2dpSoftwareAudioProvider();
-
- bool isValid(const V2_1::SessionType& sessionType) override;
- bool isValid(const V2_0::SessionType& sessionType) override;
-
- Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_0::AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
-
- private:
- // audio data queue for software encoding
- std::unique_ptr<DataMQ> mDataMQ;
-
- Return<void> onSessionReady(startSession_cb _hidl_cb) override;
-};
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/Android.bp b/bluetooth/audio/2.2/default/Android.bp
deleted file mode 100644
index 7a5ae75..0000000
--- a/bluetooth/audio/2.2/default/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_interfaces_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_library_shared {
- name: "android.hardware.bluetooth.audio@2.2-impl",
- defaults: ["hidl_defaults"],
- vendor: true,
- relative_install_path: "hw",
- srcs: [
- "BluetoothAudioProvidersFactory.cpp",
- "BluetoothAudioProvider.cpp",
- "A2dpOffloadAudioProvider.cpp",
- "A2dpSoftwareAudioProvider.cpp",
- "HearingAidAudioProvider.cpp",
- "LeAudioAudioProvider.cpp",
- "LeAudioOffloadAudioProvider.cpp",
- ],
- header_libs: ["libhardware_headers"],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
- "libbase",
- "libbluetooth_audio_session",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
-}
diff --git a/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
deleted file mode 100644
index c5613fb..0000000
--- a/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.2/types.h>
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::sp;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::audio::common::V5_0::SinkMetadata;
-using ::android::hardware::audio::common::V5_0::SourceMetadata;
-using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
-
-class AudioPort_2_0_to_2_2_Wrapper : public V2_2::IBluetoothAudioPort {
- public:
- AudioPort_2_0_to_2_2_Wrapper(const sp<V2_0::IBluetoothAudioPort>& port) {
- this->port = port;
- }
-
- Return<void> startStream() override { return port->startStream(); }
- Return<void> suspendStream() override { return port->suspendStream(); }
- Return<void> stopStream() override { return port->stopStream(); }
- Return<void> getPresentationPosition(
- getPresentationPosition_cb _hidl_cb) override {
- return port->getPresentationPosition(_hidl_cb);
- }
- Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
- return port->updateMetadata(sourceMetadata);
- }
- Return<void> updateSinkMetadata(const SinkMetadata&) override {
- // DO NOTHING, 2.0 AudioPort doesn't support sink metadata updates
- return Void();
- }
-
- sp<V2_0::IBluetoothAudioPort> port;
-};
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
\ No newline at end of file
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
deleted file mode 100644
index 62511e9..0000000
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderStub"
-
-#include "BluetoothAudioProvider.h"
-
-#include <android-base/logging.h>
-
-#include "AudioPort_2_0_to_2_2_Wrapper.h"
-#include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_2.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
-using ::android::hardware::kSynchronizedReadWrite;
-using ::android::hardware::MessageQueue;
-using ::android::hardware::Void;
-
-using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-void BluetoothAudioDeathRecipient::serviceDied(
- uint64_t cookie __unused,
- const wp<::android::hidl::base::V1_0::IBase>& who __unused) {
- LOG(ERROR) << "BluetoothAudioDeathRecipient::" << __func__
- << " - BluetoothAudio Service died";
- provider_->endSession();
-}
-
-BluetoothAudioProvider::BluetoothAudioProvider()
- : death_recipient_(new BluetoothAudioDeathRecipient(this)),
- session_type_(V2_1::SessionType::UNKNOWN),
- audio_config_({}) {}
-
-Return<void> BluetoothAudioProvider::startSession(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- AudioConfiguration audioConfig_2_2;
-
- if (audioConfig.getDiscriminator() ==
- V2_0::AudioConfiguration::hidl_discriminator::pcmConfig) {
- audioConfig_2_2.pcmConfig(
- {.sampleRate =
- static_cast<V2_1::SampleRate>(audioConfig.pcmConfig().sampleRate),
- .channelMode = audioConfig.pcmConfig().channelMode,
- .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
- .dataIntervalUs = 0});
- } else {
- audioConfig_2_2.codecConfig(audioConfig.codecConfig());
- }
-
- sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
- new AudioPort_2_0_to_2_2_Wrapper(hostIf);
- return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
-}
-
-Return<void> BluetoothAudioProvider::startSession_2_1(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- AudioConfiguration audioConfig_2_2;
- if (audioConfig.getDiscriminator() ==
- V2_1::AudioConfiguration::hidl_discriminator::leAudioCodecConfig) {
- audioConfig_2_2.leAudioConfig().mode = LeAudioMode::UNKNOWN;
- audioConfig_2_2.leAudioConfig().config.unicastConfig() = {
- .streamMap = {{
- .streamHandle = 0xFFFF,
- .audioChannelAllocation =
- audioConfig.leAudioCodecConfig().audioChannelAllocation,
- }},
- .peerDelay = 0,
- .lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
- } else if (audioConfig.getDiscriminator() ==
- V2_1::AudioConfiguration::hidl_discriminator::pcmConfig) {
- audioConfig_2_2.pcmConfig(audioConfig.pcmConfig());
- } else {
- audioConfig_2_2.codecConfig(audioConfig.codecConfig());
- }
-
- sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
- new AudioPort_2_0_to_2_2_Wrapper(hostIf);
- return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
-}
-
-Return<void> BluetoothAudioProvider::startSession_2_2(
- const sp<V2_2::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- if (hostIf == nullptr) {
- _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
- return Void();
- }
-
- /**
- * Initialize the audio platform if audioConfiguration is supported.
- * Save the IBluetoothAudioPort interface, so that it can be used
- * later to send stream control commands to the HAL client, based on
- * interaction with Audio framework.
- */
- audio_config_ = audioConfig;
- stack_iface_ = hostIf;
- stack_iface_->linkToDeath(death_recipient_, 0);
-
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << ", AudioConfiguration=[" << toString(audio_config_) << "]";
-
- onSessionReady(_hidl_cb);
- return Void();
-}
-
-Return<void> BluetoothAudioProvider::streamStarted(
- BluetoothAudioStatus status) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << ", status=" << toString(status);
-
- /**
- * Streaming on control path has started,
- * HAL server should start the streaming on data path.
- */
- if (stack_iface_) {
- BluetoothAudioSessionReport_2_2::ReportControlStatus(session_type_, true,
- status);
- } else {
- LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
- << ", status=" << toString(status) << " has NO session";
- }
-
- return Void();
-}
-
-Return<void> BluetoothAudioProvider::streamSuspended(
- BluetoothAudioStatus status) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << ", status=" << toString(status);
-
- /**
- * Streaming on control path has suspend,
- * HAL server should suspend the streaming on data path.
- */
- if (stack_iface_) {
- BluetoothAudioSessionReport_2_2::ReportControlStatus(session_type_, false,
- status);
- } else {
- LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
- << ", status=" << toString(status) << " has NO session";
- }
-
- return Void();
-}
-
-Return<void> BluetoothAudioProvider::endSession() {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
-
- if (stack_iface_) {
- BluetoothAudioSessionReport_2_2::OnSessionEnded(session_type_);
- stack_iface_->unlinkToDeath(death_recipient_);
- } else {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- }
-
- /**
- * Clean up the audio platform as remote audio device is no
- * longer active
- */
- stack_iface_ = nullptr;
- audio_config_ = {};
-
- return Void();
-}
-
-Return<void> BluetoothAudioProvider::updateAudioConfiguration(
- const AudioConfiguration& audioConfig) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
-
- if (stack_iface_ == nullptr) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- return Void();
- }
-
- if (audioConfig.getDiscriminator() != audio_config_.getDiscriminator()) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << " audio config type is not match";
- return Void();
- }
-
- audio_config_ = audioConfig;
- BluetoothAudioSessionReport_2_2::ReportAudioConfigChanged(session_type_,
- audio_config_);
-
- return Void();
-}
-
-Return<void> BluetoothAudioProvider::setLowLatencyModeAllowed(bool allowed) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
-
- if (stack_iface_ == nullptr) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- return Void();
- }
- LOG(INFO) << __func__ << " allowed: " << allowed;
- return Void();
-}
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
deleted file mode 100644
index 90c158e..0000000
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioProvider.h>
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::sp;
-using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
-
-using BluetoothAudioStatus =
- ::android::hardware::bluetooth::audio::V2_0::Status;
-
-class BluetoothAudioDeathRecipient;
-
-class BluetoothAudioProvider : public IBluetoothAudioProvider {
- public:
- BluetoothAudioProvider();
- ~BluetoothAudioProvider() = default;
-
- virtual bool isValid(const V2_1::SessionType& sessionType) = 0;
- virtual bool isValid(const V2_0::SessionType& sessionType) = 0;
-
- Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_0::AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
- Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_1::AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
- Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
- Return<void> streamStarted(BluetoothAudioStatus status) override;
- Return<void> streamSuspended(BluetoothAudioStatus status) override;
- Return<void> endSession() override;
- Return<void> updateAudioConfiguration(
- const AudioConfiguration& audioConfig) override;
-
- Return<void> setLowLatencyModeAllowed(bool allowed) override;
-
- protected:
- sp<BluetoothAudioDeathRecipient> death_recipient_;
-
- V2_1::SessionType session_type_;
- AudioConfiguration audio_config_;
- sp<V2_2::IBluetoothAudioPort> stack_iface_;
-
- virtual Return<void> onSessionReady(startSession_cb _hidl_cb) = 0;
-};
-
-class BluetoothAudioDeathRecipient : public hidl_death_recipient {
- public:
- BluetoothAudioDeathRecipient(const sp<BluetoothAudioProvider> provider)
- : provider_(provider) {}
-
- virtual void serviceDied(
- uint64_t cookie,
- const wp<::android::hidl::base::V1_0::IBase>& who) override;
-
- private:
- sp<BluetoothAudioProvider> provider_;
-};
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
deleted file mode 100644
index 490a436..0000000
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProvidersFactory"
-
-#include "BluetoothAudioProvidersFactory.h"
-
-#include <android-base/logging.h>
-
-#include "BluetoothAudioSupportedCodecsDB_2_2.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Void;
-using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
-
-A2dpSoftwareAudioProvider
- BluetoothAudioProvidersFactory::a2dp_software_provider_instance_;
-A2dpOffloadAudioProvider
- BluetoothAudioProvidersFactory::a2dp_offload_provider_instance_;
-HearingAidAudioProvider
- BluetoothAudioProvidersFactory::hearing_aid_provider_instance_;
-LeAudioOutputAudioProvider
- BluetoothAudioProvidersFactory::leaudio_output_provider_instance_;
-LeAudioOffloadOutputAudioProvider
- BluetoothAudioProvidersFactory::leaudio_offload_output_provider_instance_;
-LeAudioInputAudioProvider
- BluetoothAudioProvidersFactory::leaudio_input_provider_instance_;
-LeAudioOffloadInputAudioProvider
- BluetoothAudioProvidersFactory::leaudio_offload_input_provider_instance_;
-
-Return<void> BluetoothAudioProvidersFactory::openProvider(
- const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
- BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
- BluetoothAudioProvider* provider = nullptr;
-
- switch (sessionType) {
- case V2_0::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
- provider = &a2dp_software_provider_instance_;
- break;
- case V2_0::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
- provider = &a2dp_offload_provider_instance_;
- break;
- case V2_0::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
- provider = &hearing_aid_provider_instance_;
- break;
- default:
- status = BluetoothAudioStatus::FAILURE;
- }
-
- if (provider == nullptr || !provider->isValid(sessionType)) {
- provider = nullptr;
- status = BluetoothAudioStatus::FAILURE;
- LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
- << ", status=" << toString(status);
- }
-
- _hidl_cb(status, provider);
- return Void();
-}
-
-Return<void> BluetoothAudioProvidersFactory::openProvider_2_1(
- const V2_1::SessionType sessionType, openProvider_2_1_cb _hidl_cb) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
- BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
- BluetoothAudioProvider* provider = nullptr;
-
- switch (sessionType) {
- case V2_1::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
- provider = &a2dp_software_provider_instance_;
- break;
- case V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
- provider = &a2dp_offload_provider_instance_;
- break;
- case V2_1::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
- provider = &hearing_aid_provider_instance_;
- break;
- case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
- provider = &leaudio_output_provider_instance_;
- break;
- case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
- provider = &leaudio_input_provider_instance_;
- break;
- default:
- status = BluetoothAudioStatus::FAILURE;
- }
-
- if (provider == nullptr || !provider->isValid(sessionType)) {
- provider = nullptr;
- status = BluetoothAudioStatus::FAILURE;
- LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
- << ", status=" << toString(status);
- }
-
- _hidl_cb(status, provider);
- return Void();
-}
-
-Return<void> BluetoothAudioProvidersFactory::openProvider_2_2(
- const V2_1::SessionType sessionType, openProvider_2_2_cb _hidl_cb) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
- BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
- BluetoothAudioProvider* provider = nullptr;
-
- switch (sessionType) {
- case V2_1::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
- provider = &a2dp_software_provider_instance_;
- break;
- case V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
- provider = &a2dp_offload_provider_instance_;
- break;
- case V2_1::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
- provider = &hearing_aid_provider_instance_;
- break;
- case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
- provider = &leaudio_output_provider_instance_;
- break;
- case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
- provider = &leaudio_offload_output_provider_instance_;
- break;
- case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
- provider = &leaudio_input_provider_instance_;
- break;
- case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
- provider = &leaudio_offload_input_provider_instance_;
- break;
- default:
- status = BluetoothAudioStatus::FAILURE;
- }
-
- if (provider == nullptr || !provider->isValid(sessionType)) {
- provider = nullptr;
- status = BluetoothAudioStatus::FAILURE;
- LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
- << ", status=" << toString(status);
- }
-
- _hidl_cb(status, provider);
- return Void();
-}
-
-Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities(
- const V2_0::SessionType sessionType, getProviderCapabilities_cb _hidl_cb) {
- hidl_vec<V2_0::AudioCapabilities> audio_capabilities =
- hidl_vec<V2_0::AudioCapabilities>(0);
- if (sessionType == V2_0::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- std::vector<CodecCapabilities> db_codec_capabilities =
- android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
- if (db_codec_capabilities.size()) {
- audio_capabilities.resize(db_codec_capabilities.size());
- for (int i = 0; i < db_codec_capabilities.size(); ++i) {
- audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
- }
- }
- } else if (sessionType != V2_0::SessionType::UNKNOWN) {
- std::vector<::android::hardware::bluetooth::audio::V2_0::PcmParameters>
- db_pcm_capabilities =
- android::bluetooth::audio::GetSoftwarePcmCapabilities();
- if (db_pcm_capabilities.size() == 1) {
- audio_capabilities.resize(1);
- audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
- }
- }
- LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
- << " supports " << audio_capabilities.size() << " codecs";
- _hidl_cb(audio_capabilities);
- return Void();
-}
-
-Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_1(
- const V2_1::SessionType sessionType,
- getProviderCapabilities_2_1_cb _hidl_cb) {
- hidl_vec<V2_1::AudioCapabilities> audio_capabilities =
- hidl_vec<V2_1::AudioCapabilities>(0);
- if (sessionType == V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- std::vector<CodecCapabilities> db_codec_capabilities =
- android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
- if (db_codec_capabilities.size()) {
- audio_capabilities.resize(db_codec_capabilities.size());
- for (int i = 0; i < db_codec_capabilities.size(); ++i) {
- audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
- }
- }
- } else if (sessionType != V2_1::SessionType::UNKNOWN) {
- std::vector<V2_1::PcmParameters> db_pcm_capabilities =
- android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
- if (db_pcm_capabilities.size() == 1) {
- audio_capabilities.resize(1);
- audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
- }
- }
- LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
- << " supports " << audio_capabilities.size() << " codecs";
- _hidl_cb(audio_capabilities);
- return Void();
-}
-
-Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_2(
- const V2_1::SessionType sessionType,
- getProviderCapabilities_2_2_cb _hidl_cb) {
- hidl_vec<V2_2::AudioCapabilities> audio_capabilities =
- hidl_vec<V2_2::AudioCapabilities>(0);
- if (sessionType == V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- std::vector<CodecCapabilities> db_codec_capabilities =
- android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
- if (db_codec_capabilities.size()) {
- audio_capabilities.resize(db_codec_capabilities.size());
- for (int i = 0; i < db_codec_capabilities.size(); ++i) {
- audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
- }
- }
- } else if (sessionType == V2_1::SessionType::
- LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- sessionType == V2_1::SessionType::
- LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities =
- android::bluetooth::audio::GetLeAudioOffloadCodecCapabilities(
- sessionType);
- if (db_codec_capabilities.size()) {
- audio_capabilities.resize(db_codec_capabilities.size());
- for (int i = 0; i < db_codec_capabilities.size(); ++i) {
- audio_capabilities[i].leAudioCapabilities(db_codec_capabilities[i]);
- }
- }
- } else if (sessionType != V2_1::SessionType::UNKNOWN) {
- std::vector<V2_1::PcmParameters> db_pcm_capabilities =
- android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
- if (db_pcm_capabilities.size() == 1) {
- audio_capabilities.resize(1);
- audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
- }
- }
- LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
- << " supports " << audio_capabilities.size() << " codecs";
- _hidl_cb(audio_capabilities);
- return Void();
-}
-
-IBluetoothAudioProvidersFactory* HIDL_FETCH_IBluetoothAudioProvidersFactory(
- const char* /* name */) {
- return new BluetoothAudioProvidersFactory();
-}
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
deleted file mode 100644
index 4f549d9..0000000
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.h>
-
-#include "A2dpOffloadAudioProvider.h"
-#include "A2dpSoftwareAudioProvider.h"
-#include "BluetoothAudioProvider.h"
-#include "HearingAidAudioProvider.h"
-#include "LeAudioAudioProvider.h"
-#include "LeAudioOffloadAudioProvider.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-class BluetoothAudioProvidersFactory : public IBluetoothAudioProvidersFactory {
- public:
- BluetoothAudioProvidersFactory() {}
-
- Return<void> openProvider(const V2_0::SessionType sessionType,
- openProvider_cb _hidl_cb) override;
-
- Return<void> getProviderCapabilities(
- const V2_0::SessionType sessionType,
- getProviderCapabilities_cb _hidl_cb) override;
-
- Return<void> openProvider_2_1(const V2_1::SessionType sessionType,
- openProvider_2_1_cb _hidl_cb) override;
-
- Return<void> openProvider_2_2(const V2_1::SessionType sessionType,
- openProvider_2_2_cb _hidl_cb) override;
-
- Return<void> getProviderCapabilities_2_1(
- const V2_1::SessionType sessionType,
- getProviderCapabilities_2_1_cb _hidl_cb) override;
-
- Return<void> getProviderCapabilities_2_2(
- const V2_1::SessionType sessionType,
- getProviderCapabilities_2_2_cb _hidl_cb) override;
-
- private:
- static A2dpSoftwareAudioProvider a2dp_software_provider_instance_;
- static A2dpOffloadAudioProvider a2dp_offload_provider_instance_;
- static HearingAidAudioProvider hearing_aid_provider_instance_;
- static LeAudioOutputAudioProvider leaudio_output_provider_instance_;
- static LeAudioInputAudioProvider leaudio_input_provider_instance_;
- static LeAudioOffloadOutputAudioProvider
- leaudio_offload_output_provider_instance_;
- static LeAudioOffloadInputAudioProvider
- leaudio_offload_input_provider_instance_;
-};
-
-extern "C" IBluetoothAudioProvidersFactory*
-HIDL_FETCH_IBluetoothAudioProvidersFactory(const char* name);
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
deleted file mode 100644
index 25e49a1..0000000
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderHearingAid"
-
-#include "HearingAidAudioProvider.h"
-
-#include <android-base/logging.h>
-
-#include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_2.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
-using ::android::hardware::Void;
-using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
-
-static constexpr uint32_t kPcmFrameSize = 4; // 16 bits per sample / stereo
-static constexpr uint32_t kPcmFrameCount = 128;
-static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
-static constexpr uint32_t kRtpFrameCount = 7; // max counts by 1 tick (20ms)
-static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
-static constexpr uint32_t kBufferCount = 1; // single buffer
-static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
-
-HearingAidAudioProvider::HearingAidAudioProvider()
- : BluetoothAudioProvider(), mDataMQ(nullptr) {
- LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
- << " byte(s)";
- std::unique_ptr<DataMQ> tempDataMQ(
- new DataMQ(kDataMqSize, /* EventFlag */ true));
- if (tempDataMQ && tempDataMQ->isValid()) {
- mDataMQ = std::move(tempDataMQ);
- session_type_ = V2_1::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
- } else {
- ALOGE_IF(!tempDataMQ, "failed to allocate data MQ");
- ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "data MQ is invalid");
- }
-}
-
-bool HearingAidAudioProvider::isValid(const V2_0::SessionType& sessionType) {
- return isValid(static_cast<V2_1::SessionType>(sessionType));
-}
-
-bool HearingAidAudioProvider::isValid(const V2_1::SessionType& sessionType) {
- return (sessionType == session_type_ && mDataMQ && mDataMQ->isValid());
-}
-
-Return<void> HearingAidAudioProvider::startSession(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- /**
- * Initialize the audio platform if audioConfiguration is supported.
- * Save the IBluetoothAudioPort interface, so that it can be used
- * later to send stream control commands to the HAL client, based on
- * interaction with Audio framework.
- */
- if (audioConfig.getDiscriminator() !=
- AudioConfiguration::hidl_discriminator::pcmConfig) {
- LOG(WARNING) << __func__
- << " - Invalid Audio Configuration=" << toString(audioConfig);
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- } else if (!android::bluetooth::audio::IsSoftwarePcmConfigurationValid(
- audioConfig.pcmConfig())) {
- LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
- << toString(audioConfig.pcmConfig());
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- return BluetoothAudioProvider::startSession(hostIf, audioConfig, _hidl_cb);
-}
-
-Return<void> HearingAidAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
- if (mDataMQ && mDataMQ->isValid()) {
- BluetoothAudioSessionReport_2_2::OnSessionStarted(
- session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
- _hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
- } else {
- _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
- }
- return Void();
-}
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
deleted file mode 100644
index 63290b5..0000000
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-
-#include "BluetoothAudioProvider.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::hardware::kSynchronizedReadWrite;
-using ::android::hardware::MessageQueue;
-
-using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-class HearingAidAudioProvider : public BluetoothAudioProvider {
- public:
- HearingAidAudioProvider();
-
- bool isValid(const V2_1::SessionType& sessionType) override;
- bool isValid(const V2_0::SessionType& sessionType) override;
-
- Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_0::AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
-
- private:
- // audio data queue for software encoding
- std::unique_ptr<DataMQ> mDataMQ;
-
- Return<void> onSessionReady(startSession_cb _hidl_cb) override;
-};
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
deleted file mode 100644
index a7a0023..0000000
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderLeAudio"
-
-#include "LeAudioAudioProvider.h"
-
-#include <android-base/logging.h>
-
-#include "AudioPort_2_0_to_2_2_Wrapper.h"
-#include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_2.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
-using ::android::hardware::Void;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-
-static constexpr uint32_t kBufferOutCount = 2; // two frame buffer
-static constexpr uint32_t kBufferInCount = 2; // two frame buffer
-
-LeAudioOutputAudioProvider::LeAudioOutputAudioProvider()
- : LeAudioAudioProvider() {
- session_type_ = V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
-}
-
-LeAudioInputAudioProvider::LeAudioInputAudioProvider()
- : LeAudioAudioProvider() {
- session_type_ = V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH;
-}
-
-LeAudioAudioProvider::LeAudioAudioProvider()
- : BluetoothAudioProvider(), mDataMQ(nullptr) {}
-
-bool LeAudioAudioProvider::isValid(const V2_0::SessionType& sessionType) {
- LOG(ERROR) << __func__ << ", invalid session type for Le Audio provider: "
- << toString(sessionType);
-
- return false;
-}
-
-bool LeAudioAudioProvider::isValid(const V2_1::SessionType& sessionType) {
- return (sessionType == session_type_);
-}
-
-Return<void> LeAudioAudioProvider::startSession_2_1(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- if (audioConfig.getDiscriminator() !=
- V2_1::AudioConfiguration::hidl_discriminator::pcmConfig) {
- LOG(WARNING) << __func__
- << " - Invalid Audio Configuration=" << toString(audioConfig);
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- AudioConfiguration audioConfig_2_2;
- audioConfig_2_2.pcmConfig(
- {.sampleRate =
- static_cast<V2_1::SampleRate>(audioConfig.pcmConfig().sampleRate),
- .channelMode = audioConfig.pcmConfig().channelMode,
- .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
- .dataIntervalUs = 0});
-
- sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
- new AudioPort_2_0_to_2_2_Wrapper(hostIf);
- return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
-}
-
-Return<void> LeAudioAudioProvider::startSession_2_2(
- const sp<V2_2::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- /**
- * Initialize the audio platform if audioConfiguration is supported.
- * Save the IBluetoothAudioPort interface, so that it can be used
- * later to send stream control commands to the HAL client, based on
- * interaction with Audio framework.
- */
- if (audioConfig.getDiscriminator() !=
- AudioConfiguration::hidl_discriminator::pcmConfig) {
- LOG(WARNING) << __func__
- << " - Invalid Audio Configuration=" << toString(audioConfig);
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- } else if (!android::bluetooth::audio::IsSoftwarePcmConfigurationValid_2_1(
- audioConfig.pcmConfig())) {
- LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
- << toString(audioConfig.pcmConfig());
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- uint32_t kDataMqSize = 0;
- switch (audioConfig.pcmConfig().sampleRate) {
- case SampleRate::RATE_8000:
- kDataMqSize = 8000;
- break;
- case SampleRate::RATE_16000:
- kDataMqSize = 16000;
- break;
- case SampleRate::RATE_24000:
- kDataMqSize = 24000;
- break;
- case SampleRate::RATE_32000:
- kDataMqSize = 32000;
- break;
- case SampleRate::RATE_44100:
- kDataMqSize = 44100;
- break;
- case SampleRate::RATE_48000:
- kDataMqSize = 48000;
- break;
- default:
- LOG(WARNING) << __func__ << " - Unsupported sampling frequency="
- << toString(audioConfig.pcmConfig());
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- /* Number of samples per millisecond */
- kDataMqSize = ceil(kDataMqSize / 1000);
-
- switch (audioConfig.pcmConfig().channelMode) {
- case ChannelMode::MONO:
- break;
- case ChannelMode::STEREO:
- kDataMqSize *= 2;
- break;
- default:
- /* This should never happen it would be caught while validating
- * parameters.
- */
- break;
- }
-
- switch (audioConfig.pcmConfig().bitsPerSample) {
- case BitsPerSample::BITS_16:
- kDataMqSize *= 2;
- break;
- case BitsPerSample::BITS_24:
- kDataMqSize *= 3;
- break;
- case BitsPerSample::BITS_32:
- kDataMqSize *= 4;
- break;
- default:
- /* This should never happen it would be caught while validating
- * parameters.
- */
- break;
- }
-
- if (session_type_ == V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH)
- kDataMqSize *= kBufferOutCount;
- else if (session_type_ ==
- V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH)
- kDataMqSize *= kBufferInCount;
- else
- LOG(WARNING) << __func__ << ", default single buffer used";
-
- kDataMqSize *= audioConfig.pcmConfig().dataIntervalUs / 1000;
-
- LOG(INFO) << __func__ << " - size of audio buffer " << kDataMqSize
- << " byte(s)";
-
- std::unique_ptr<DataMQ> tempDataMQ(
- new DataMQ(kDataMqSize, /* EventFlag */ true));
- if (tempDataMQ && tempDataMQ->isValid()) {
- mDataMQ = std::move(tempDataMQ);
- } else {
- ALOGE_IF(!tempDataMQ, "failed to allocate data MQ");
- ALOGE_IF(tempDataMQ && !tempDataMQ->isValid(), "data MQ is invalid");
- _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
- return Void();
- }
-
- return BluetoothAudioProvider::startSession_2_2(hostIf, audioConfig,
- _hidl_cb);
-}
-
-Return<void> LeAudioAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
- if (mDataMQ && mDataMQ->isValid()) {
- BluetoothAudioSessionReport_2_2::OnSessionStarted(
- session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
- _hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
- } else {
- _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
- }
- return Void();
-}
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
deleted file mode 100644
index 3de1724..0000000
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.2/types.h>
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-
-#include "BluetoothAudioProvider.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::hardware::kSynchronizedReadWrite;
-using ::android::hardware::MessageQueue;
-
-using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-class LeAudioAudioProvider : public BluetoothAudioProvider {
- public:
- LeAudioAudioProvider();
-
- bool isValid(const V2_1::SessionType& sessionType) override;
- bool isValid(const V2_0::SessionType& sessionType) override;
-
- Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_1::AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
-
- Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
-
- private:
- /** queue for software encodec/decoded audio data */
- std::unique_ptr<DataMQ> mDataMQ;
-
- Return<void> onSessionReady(startSession_cb _hidl_cb) override;
-};
-
-class LeAudioOutputAudioProvider : public LeAudioAudioProvider {
- public:
- LeAudioOutputAudioProvider();
-};
-
-class LeAudioInputAudioProvider : public LeAudioAudioProvider {
- public:
- LeAudioInputAudioProvider();
-};
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
deleted file mode 100644
index 2b0c02f..0000000
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderLeAudioOffload"
-
-#include "LeAudioOffloadAudioProvider.h"
-
-#include <android-base/logging.h>
-
-#include "AudioPort_2_0_to_2_2_Wrapper.h"
-#include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_2.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_2;
-using ::android::hardware::Void;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-
-using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider()
- : LeAudioOffloadAudioProvider() {
- session_type_ =
- V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
-}
-
-LeAudioOffloadInputAudioProvider::LeAudioOffloadInputAudioProvider()
- : LeAudioOffloadAudioProvider() {
- session_type_ =
- V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
-}
-
-LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider()
- : BluetoothAudioProvider() {}
-
-bool LeAudioOffloadAudioProvider::isValid(
- const V2_0::SessionType& sessionType) {
- LOG(ERROR) << __func__
- << ", invalid session type for Offloaded Le Audio provider: "
- << toString(sessionType);
-
- return false;
-}
-
-bool LeAudioOffloadAudioProvider::isValid(
- const V2_1::SessionType& sessionType) {
- return (sessionType == session_type_);
-}
-
-Return<void> LeAudioOffloadAudioProvider::startSession_2_1(
- const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- if (audioConfig.getDiscriminator() !=
- V2_1::AudioConfiguration::hidl_discriminator::leAudioCodecConfig) {
- LOG(WARNING) << __func__
- << " - Invalid Audio Configuration=" << toString(audioConfig);
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- AudioConfiguration audioConfig_2_2;
- audioConfig_2_2.leAudioConfig().mode = LeAudioMode::UNKNOWN;
- audioConfig_2_2.leAudioConfig().config.unicastConfig() = {
- .streamMap = {{
- .streamHandle = 0xFFFF,
- .audioChannelAllocation =
- audioConfig.leAudioCodecConfig().audioChannelAllocation,
- }},
- .peerDelay = 0,
- .lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
-
- sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
- new AudioPort_2_0_to_2_2_Wrapper(hostIf);
- return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
-}
-
-Return<void> LeAudioOffloadAudioProvider::startSession_2_2(
- const sp<V2_2::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
- /**
- * Initialize the audio platform if audioConfiguration is supported.
- * Save the IBluetoothAudioPort interface, so that it can be used
- * later to send stream control commands to the HAL client, based on
- * interaction with Audio framework.
- */
- if (audioConfig.getDiscriminator() !=
- AudioConfiguration::hidl_discriminator::leAudioConfig) {
- LOG(WARNING) << __func__
- << " - Invalid Audio Configuration=" << toString(audioConfig);
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- if (!android::bluetooth::audio::IsOffloadLeAudioConfigurationValid(
- session_type_, audioConfig.leAudioConfig())) {
- LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration="
- << toString(audioConfig.leAudioConfig());
- _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
- DataMQ::Descriptor());
- return Void();
- }
-
- return BluetoothAudioProvider::startSession_2_2(hostIf, audioConfig,
- _hidl_cb);
-}
-
-Return<void> LeAudioOffloadAudioProvider::onSessionReady(
- startSession_cb _hidl_cb) {
- BluetoothAudioSessionReport_2_2::OnSessionStarted(session_type_, stack_iface_,
- nullptr, audio_config_);
- _hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor());
- return Void();
-}
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
deleted file mode 100644
index fe58de5..0000000
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.2/types.h>
-
-#include "BluetoothAudioProvider.h"
-
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-namespace V2_2 {
-namespace implementation {
-
-class LeAudioOffloadAudioProvider : public BluetoothAudioProvider {
- public:
- LeAudioOffloadAudioProvider();
-
- bool isValid(const V2_1::SessionType& sessionType) override;
- bool isValid(const V2_0::SessionType& sessionType) override;
-
- Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
- const V2_1::AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
-
- Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
- const AudioConfiguration& audioConfig,
- startSession_cb _hidl_cb) override;
-
- private:
- Return<void> onSessionReady(startSession_cb _hidl_cb) override;
-};
-
-class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider {
- public:
- LeAudioOffloadOutputAudioProvider();
-};
-
-class LeAudioOffloadInputAudioProvider : public LeAudioOffloadAudioProvider {
- public:
- LeAudioOffloadInputAudioProvider();
-};
-
-} // namespace implementation
-} // namespace V2_2
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
diff --git a/bluetooth/audio/2.2/default/OWNERS b/bluetooth/audio/2.2/default/OWNERS
deleted file mode 100644
index 17ea464..0000000
--- a/bluetooth/audio/2.2/default/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-include platform/packages/modules/Bluetooth:/OWNERS
-
-cheneyni@google.com
-aliceypkuo@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/2.2/types.hal b/bluetooth/audio/2.2/types.hal
deleted file mode 100644
index 6755899..0000000
--- a/bluetooth/audio/2.2/types.hal
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.bluetooth.audio@2.2;
-
-import @2.1::Lc3Parameters;
-import @2.1::PcmParameters;
-import @2.0::CodecConfiguration;
-import @2.0::CodecCapabilities;
-import @2.1::CodecType;
-
-enum LeAudioMode : uint8_t {
- UNKNOWN = 0x00,
- UNICAST = 0x01,
- BROADCAST = 0x02,
-};
-
-enum AudioLocation : uint8_t {
- UNKNOWN = 0,
- FRONT_LEFT = 1,
- FRONT_RIGHT = 2,
-};
-
-struct UnicastStreamMap {
- /* The connection handle used for a unicast or a broadcast group. */
- uint16_t streamHandle;
- /* Audio channel allocation is a bit field, each enabled bit means that given audio direction,
- * i.e. "left", or "right" is used. Ordering of audio channels comes from the least significant
- * bit to the most significant bit. */
- uint32_t audioChannelAllocation;
-};
-
-struct BroadcastStreamMap {
- /* The connection handle used for a unicast or a broadcast group. */
- uint16_t streamHandle;
- /* Audio channel allocation is a bit field, each enabled bit means that given audio direction,
- * i.e. "left", or "right" is used. Ordering of audio channels comes from the least significant
- * bit to the most significant bit. */
- uint32_t audioChannelAllocation;
- Lc3Parameters lc3Config;
-};
-
-struct UnicastConfig {
- vec<UnicastStreamMap> streamMap;
- uint32_t peerDelay;
- Lc3Parameters lc3Config;
-};
-
-struct BroadcastConfig {
- vec<BroadcastStreamMap> streamMap;
-};
-
-struct LeAudioConfiguration {
- /* The mode of the LE audio */
- LeAudioMode mode;
- safe_union CodecConfig {
- UnicastConfig unicastConfig;
- BroadcastConfig broadcastConfig;
- } config;
-};
-
-/** Used to configure either a Hardware or Software Encoding session based on session type */
-safe_union AudioConfiguration {
- PcmParameters pcmConfig;
- CodecConfiguration codecConfig;
- LeAudioConfiguration leAudioConfig;
-};
-
-/** Used to specify the capabilities of the different session types */
-safe_union AudioCapabilities {
- PcmParameters pcmCapabilities;
- CodecCapabilities codecCapabilities;
- LeAudioCodecCapabilitiesSetting leAudioCapabilities;
-};
-
-/**
- * Used to specify the le audio capabilities for unicast and broadcast hardware offload.
- */
-struct LeAudioCodecCapabilitiesSetting{
- UnicastCapability unicastEncodeCapability;
- UnicastCapability unicastDecodeCapability;
- BroadcastCapability broadcastCapability;
-};
-
-/**
- * Used to specify the le audio unicast codec capabilities for hardware offload.
- */
-struct UnicastCapability {
- CodecType codecType;
- AudioLocation supportedChannel;
-
- // The number of connected device
- uint8_t deviceCount;
-
- // Supported channel count for each device
- uint8_t channelCountPerDevice;
-
- // Should use safe union when there is more than one codec
- Lc3Parameters capabilities;
-};
-
-/**
- * Used to specify the le audio broadcast codec capabilities for hardware offload.
- */
-struct BroadcastCapability {
- CodecType codecType;
- AudioLocation supportedChannel;
-
- // Supported channel count for each stream
- uint8_t channelCountPerStream;
-
- // Should use safe union when there is more than one codec
- vec<Lc3Parameters> capabilities;
-};
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index 50b54c3..3abfb31 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -37,4 +37,5 @@
android.hardware.bluetooth.audio.PcmConfiguration pcmConfig;
android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig;
android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
+ android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration leAudioBroadcastConfig;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
index 7c0d825..c20c057 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
@@ -38,4 +38,5 @@
SUCCESS = 1,
UNSUPPORTED_CODEC_CONFIGURATION = 2,
FAILURE = 3,
+ RECONFIGURATION = 4,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index cc3c641..d364371 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -35,11 +35,10 @@
@VintfStability
interface IBluetoothAudioPort {
android.hardware.bluetooth.audio.PresentationPosition getPresentationPosition();
- void startStream();
+ void startStream(boolean isLowLatency);
void stopStream();
void suspendStream();
void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
void setLatencyMode(in android.hardware.bluetooth.audio.LatencyMode latencyMode);
- void setCodecType(in android.hardware.bluetooth.audio.CodecType codecType);
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index 6e0bd98..267af0f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -35,7 +35,7 @@
@VintfStability
interface IBluetoothAudioProvider {
void endSession();
- android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
+ android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig, in android.hardware.bluetooth.audio.LatencyMode[] supportedLatencyModes);
void streamStarted(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
similarity index 90%
rename from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 5fa3926..7d53b0c 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -33,8 +33,9 @@
package android.hardware.bluetooth.audio;
@VintfStability
-parcelable BroadcastConfiguration {
- android.hardware.bluetooth.audio.BroadcastConfiguration.BroadcastStreamMap[] streamMap;
+parcelable LeAudioBroadcastConfiguration {
+ android.hardware.bluetooth.audio.CodecType codecType;
+ android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap[] streamMap;
@VintfStability
parcelable BroadcastStreamMap {
char streamHandle;
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 2bc1791..edb6795 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -34,12 +34,13 @@
package android.hardware.bluetooth.audio;
@VintfStability
parcelable LeAudioConfiguration {
- android.hardware.bluetooth.audio.LeAudioMode mode;
- android.hardware.bluetooth.audio.LeAudioConfiguration.LeAudioModeConfig modeConfig;
android.hardware.bluetooth.audio.CodecType codecType;
+ android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap;
+ int peerDelayUs;
+ android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
@VintfStability
- union LeAudioModeConfig {
- android.hardware.bluetooth.audio.UnicastConfiguration unicastConfig;
- android.hardware.bluetooth.audio.BroadcastConfiguration broadcastConfig;
+ parcelable StreamMap {
+ char streamHandle;
+ int audioChannelAllocation;
}
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index 72d7fb2..baec9c2 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -42,4 +42,6 @@
LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6,
LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
+ LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH = 8,
+ LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 9,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
deleted file mode 100644
index b385763..0000000
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.bluetooth.audio;
-@VintfStability
-parcelable UnicastConfiguration {
- android.hardware.bluetooth.audio.UnicastConfiguration.UnicastStreamMap[] streamMap;
- int peerDelay;
- android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
- @VintfStability
- parcelable UnicastStreamMap {
- char streamHandle;
- int audioChannelAllocation;
- }
-}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index 81b41dc..a06337e 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -17,6 +17,7 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.CodecConfiguration;
+import android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration;
import android.hardware.bluetooth.audio.LeAudioConfiguration;
import android.hardware.bluetooth.audio.PcmConfiguration;
@@ -28,4 +29,5 @@
PcmConfiguration pcmConfig;
CodecConfiguration a2dpConfig;
LeAudioConfiguration leAudioConfig;
+ LeAudioBroadcastConfiguration leAudioBroadcastConfig;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
index ec78445..9ddafe9 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
@@ -23,5 +23,6 @@
SUCCESS = 1,
UNSUPPORTED_CODEC_CONFIGURATION = 2,
// General failure
- FAILURE = 3
+ FAILURE = 3,
+ RECONFIGURATION = 4,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
index cb63f88..f1301fb 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
@@ -19,7 +19,6 @@
import android.hardware.bluetooth.audio.AudioLocation;
import android.hardware.bluetooth.audio.CodecType;
import android.hardware.bluetooth.audio.Lc3Capabilities;
-import android.hardware.bluetooth.audio.LeAudioMode;
/**
* Used to specify the le audio broadcast codec capabilities for hardware offload.
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 81c2ce2..4ddf645 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -47,8 +47,11 @@
* This indicates that the caller of this method has opened the data path
* and wants to start an audio stream. The caller must wait for a
* IBluetoothAudioProvider.streamStarted(Status) call.
+ *
+ * @param isLowLatency true if the stream being started with the latency
+ * control mechanism.
*/
- void startStream();
+ void startStream(boolean isLowLatency);
/**
* This indicates that the caller of this method wants to stop the audio
@@ -87,11 +90,4 @@
* @param latencyMode latency mode from audio
*/
void setLatencyMode(in LatencyMode latencyMode);
-
- /**
- * Called when codec type is changed.
- *
- * @param codecType codec type from audio
- */
- void setCodecType(in CodecType codecType);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index ca6f691..d5c051e 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -19,6 +19,7 @@
import android.hardware.bluetooth.audio.AudioConfiguration;
import android.hardware.bluetooth.audio.BluetoothAudioStatus;
import android.hardware.bluetooth.audio.IBluetoothAudioPort;
+import android.hardware.bluetooth.audio.LatencyMode;
import android.hardware.common.fmq.MQDescriptor;
import android.hardware.common.fmq.SynchronizedReadWrite;
@@ -50,6 +51,8 @@
* device. The PCM parameters are set if software based encoding,
* otherwise the correct codec configuration is used for hardware
* encoding.
+ * @param supportedLatencyModes latency modes supported by the active
+ * remote device
*
* @return The fast message queue for audio data from/to this
* provider. Audio data will be in PCM format as specified by the
@@ -57,8 +60,8 @@
* from/to hardware or on failure
*/
MQDescriptor<byte, SynchronizedReadWrite> startSession(
- in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig);
-
+ in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig,
+ in LatencyMode[] supportedLatencyModes);
/**
* Callback for IBluetoothAudioPort.startStream()
*
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
similarity index 87%
rename from bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
rename to bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index cfc9d3a..e9a1a0c 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -16,14 +16,15 @@
package android.hardware.bluetooth.audio;
+import android.hardware.bluetooth.audio.CodecType;
import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
@VintfStability
-parcelable BroadcastConfiguration {
+parcelable LeAudioBroadcastConfiguration {
@VintfStability
parcelable BroadcastStreamMap {
/*
- * The connection handle used for a unicast or a broadcast group.
+ * The connection handle used for a broadcast group.
* Range: 0x0000 to 0xEFFF
*/
char streamHandle;
@@ -35,5 +36,6 @@
int audioChannelAllocation;
LeAudioCodecConfiguration leAudioCodecConfig;
}
+ CodecType codecType;
BroadcastStreamMap[] streamMap;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 515794b..0d1e3de 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -16,22 +16,28 @@
package android.hardware.bluetooth.audio;
-import android.hardware.bluetooth.audio.BroadcastConfiguration;
import android.hardware.bluetooth.audio.CodecType;
-import android.hardware.bluetooth.audio.LeAudioMode;
-import android.hardware.bluetooth.audio.UnicastConfiguration;
+import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
@VintfStability
parcelable LeAudioConfiguration {
@VintfStability
- union LeAudioModeConfig {
- UnicastConfiguration unicastConfig;
- BroadcastConfiguration broadcastConfig;
+ parcelable StreamMap {
+ /*
+ * The connection handle used for a unicast group.
+ * Range: 0x0000 to 0xEFFF
+ */
+ char streamHandle;
+ /*
+ * Audio channel allocation is a bit field, each enabled bit means that given audio
+ * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
+ * least significant bit to the most significant bit. The valus follows the Bluetooth SIG
+ * Audio Location assigned number.
+ */
+ int audioChannelAllocation;
}
- /*
- * The mode of the LE audio
- */
- LeAudioMode mode;
- LeAudioModeConfig modeConfig;
CodecType codecType;
+ StreamMap[] streamMap;
+ int peerDelayUs;
+ LeAudioCodecConfiguration leAudioCodecConfig;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
deleted file mode 100644
index 2cf019e..0000000
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.bluetooth.audio;
-
-@VintfStability
-@Backing(type="byte")
-enum LeAudioMode {
- UNKNOWN,
- UNICAST,
- BROADCAST,
-}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
index 30faae3..95beee7 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -33,19 +33,33 @@
*/
HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
/**
- * Used when encoded by Bluetooth Stack and streaming to LE Audio device
+ * Used when audio is encoded by the Bluetooth Stack and is streamed to LE
+ * Audio unicast device.
*/
LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
/**
- * Used when decoded by Bluetooth Stack and streaming to audio framework
+ * Used when audio is decoded by the Bluetooth Stack and is streamed to LE
+ * Audio unicast device.
*/
LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
/**
- * Encoding is done by HW an there is control only
+ * Used when audio is encoded by hardware offload and is streamed to LE
+ * Audio unicast device. This is a control path only.
*/
LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
/**
- * Decoding is done by HW an there is control only
+ * Used when audio is decoded by hardware offload and is streamed to LE
+ * Audio unicast device. This is a control path only.
*/
LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ /**
+ * Used when audio is encoded by the Bluetooth stack and is streamed to LE
+ * Audio broadcast channels.
+ */
+ LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ /**
+ * Used when audio is encoded by hardware offload and is streamed to LE
+ * Audio broadcast channels. This is a control path only.
+ */
+ LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
index cd8a4c1..f8a924a 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -19,7 +19,6 @@
import android.hardware.bluetooth.audio.AudioLocation;
import android.hardware.bluetooth.audio.CodecType;
import android.hardware.bluetooth.audio.Lc3Capabilities;
-import android.hardware.bluetooth.audio.LeAudioMode;
/**
* Used to specify the le audio unicast codec capabilities for hardware offload.
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
deleted file mode 100644
index 7be2c5b..0000000
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.bluetooth.audio;
-
-import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
-
-@VintfStability
-parcelable UnicastConfiguration {
- @VintfStability
- parcelable UnicastStreamMap {
- /*
- * The connection handle used for a unicast or a broadcast group.
- * Range: 0x0000 to 0xEFFF
- */
- char streamHandle;
- /*
- * Audio channel allocation is a bit field, each enabled bit means that given audio
- * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
- * least significant bit to the most significant bit. The valus follows the Bluetooth SIG
- * Audio Location assigned number.
- */
- int audioChannelAllocation;
- }
- UnicastStreamMap[] streamMap;
- int peerDelay;
- LeAudioCodecConfiguration leAudioCodecConfig;
-}
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
index fc8a911..866776e 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
@@ -38,7 +38,10 @@
ndk::ScopedAStatus A2dpOffloadAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return) {
+ latency_modes_ = latency_modes;
if (audio_config.getTag() != AudioConfiguration::a2dpConfig) {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
@@ -52,8 +55,8 @@
*_aidl_return = DataMQDesc();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- return BluetoothAudioProvider::startSession(host_if, audio_config,
- _aidl_return);
+ return BluetoothAudioProvider::startSession(
+ host_if, audio_config, latency_modes, _aidl_return);
}
ndk::ScopedAStatus A2dpOffloadAudioProvider::onSessionReady(
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
index 5934f5b..4621e85 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
@@ -32,7 +32,9 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return);
private:
ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
index 5a413e0..d2f58f3 100644
--- a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.cpp
@@ -61,7 +61,10 @@
ndk::ScopedAStatus A2dpSoftwareAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return) {
+ latency_modes_ = latency_modes;
if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
@@ -77,8 +80,8 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- return BluetoothAudioProvider::startSession(host_if, audio_config,
- _aidl_return);
+ return BluetoothAudioProvider::startSession(
+ host_if, audio_config, latency_modes, _aidl_return);
}
ndk::ScopedAStatus A2dpSoftwareAudioProvider::onSessionReady(
diff --git a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
index 3bc0a13..10f533a 100644
--- a/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
+++ b/bluetooth/audio/aidl/default/A2dpSoftwareAudioProvider.h
@@ -32,7 +32,9 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return);
private:
// audio data queue for software encoding
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index fc882d4..13a5440 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -19,6 +19,7 @@
"HearingAidAudioProvider.cpp",
"LeAudioOffloadAudioProvider.cpp",
"LeAudioSoftwareAudioProvider.cpp",
+ "service.cpp",
],
export_include_dirs: ["."],
header_libs: ["libhardware_headers"],
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 54e82d1..0dd8148 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -34,11 +34,15 @@
ndk::ScopedAStatus BluetoothAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latencyModes,
+ DataMQDesc* _aidl_return) {
if (host_if == nullptr) {
*_aidl_return = DataMQDesc();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
+
+ latency_modes_ = latencyModes;
audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
stack_iface_ = host_if;
@@ -131,6 +135,8 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
LOG(INFO) << __func__ << " - allowed " << allowed;
+ BluetoothAudioSessionReport::ReportLowLatencyModeAllowedChanged(
+ session_type_, allowed);
return ndk::ScopedAStatus::ok();
}
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index 393aaba..75794e8 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -16,6 +16,7 @@
#pragma once
#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioProvider.h>
+#include <aidl/android/hardware/bluetooth/audio/LatencyMode.h>
#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
#include <fmq/AidlMessageQueue.h>
@@ -37,10 +38,11 @@
class BluetoothAudioProvider : public BnBluetoothAudioProvider {
public:
BluetoothAudioProvider();
-
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return);
ndk::ScopedAStatus endSession();
ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status);
ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status);
@@ -59,6 +61,7 @@
std::shared_ptr<IBluetoothAudioPort> stack_iface_;
std::unique_ptr<AudioConfiguration> audio_config_ = nullptr;
SessionType session_type_;
+ std::vector<LatencyMode> latency_modes_;
};
} // namespace audio
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 1e55a0b..1e1680a 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -64,6 +64,14 @@
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
provider = ndk::SharedRefBase::make<LeAudioOffloadInputAudioProvider>();
break;
+ case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
+ provider =
+ ndk::SharedRefBase::make<LeAudioSoftwareBroadcastAudioProvider>();
+ break;
+ case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+ provider =
+ ndk::SharedRefBase::make<LeAudioOffloadBroadcastAudioProvider>();
+ break;
default:
provider = nullptr;
break;
@@ -93,7 +101,10 @@
} else if (session_type ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type ==
- SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type ==
+ SessionType::
+ LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities =
BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(session_type);
if (db_codec_capabilities.size()) {
diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
index 66ce93b..c754849 100644
--- a/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.cpp
@@ -56,7 +56,10 @@
ndk::ScopedAStatus HearingAidAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return) {
+ latency_modes_ = latency_modes;
if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
@@ -71,8 +74,8 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- return BluetoothAudioProvider::startSession(host_if, audio_config,
- _aidl_return);
+ return BluetoothAudioProvider::startSession(
+ host_if, audio_config, latency_modes, _aidl_return);
}
ndk::ScopedAStatus HearingAidAudioProvider::onSessionReady(
diff --git a/bluetooth/audio/aidl/default/HearingAidAudioProvider.h b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h
index a7e19e9..a158c86 100644
--- a/bluetooth/audio/aidl/default/HearingAidAudioProvider.h
+++ b/bluetooth/audio/aidl/default/HearingAidAudioProvider.h
@@ -32,7 +32,9 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return);
private:
// audio data queue for software encoding
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 72ac9bd..1a3c658 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -38,6 +38,12 @@
session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH;
}
+LeAudioOffloadBroadcastAudioProvider::LeAudioOffloadBroadcastAudioProvider()
+ : LeAudioOffloadAudioProvider() {
+ session_type_ =
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH;
+}
+
LeAudioOffloadAudioProvider::LeAudioOffloadAudioProvider()
: BluetoothAudioProvider() {}
@@ -47,7 +53,10 @@
ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return) {
+ latency_modes_ = latency_modes;
if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
@@ -64,8 +73,8 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- return BluetoothAudioProvider::startSession(host_if, audio_config,
- _aidl_return);
+ return BluetoothAudioProvider::startSession(
+ host_if, audio_config, latency_modes, _aidl_return);
}
ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady(
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index a27a2e7..614c794 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -32,7 +32,9 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return);
private:
ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
@@ -48,6 +50,12 @@
LeAudioOffloadInputAudioProvider();
};
+class LeAudioOffloadBroadcastAudioProvider
+ : public LeAudioOffloadAudioProvider {
+ public:
+ LeAudioOffloadBroadcastAudioProvider();
+};
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
index 67b7d60..1f64b43 100644
--- a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
@@ -55,6 +55,11 @@
session_type_ = SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH;
}
+LeAudioSoftwareBroadcastAudioProvider::LeAudioSoftwareBroadcastAudioProvider()
+ : LeAudioSoftwareAudioProvider() {
+ session_type_ = SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH;
+}
+
LeAudioSoftwareAudioProvider::LeAudioSoftwareAudioProvider()
: BluetoothAudioProvider(), data_mq_(nullptr) {}
@@ -64,7 +69,10 @@
ndk::ScopedAStatus LeAudioSoftwareAudioProvider::startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return) {
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return) {
+ latency_modes_ = latency_modes;
if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
@@ -78,7 +86,9 @@
}
uint32_t buffer_modifier = 0;
- if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH)
+ if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ ==
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH)
buffer_modifier = kBufferOutCount;
else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH)
buffer_modifier = kBufferInCount;
@@ -112,8 +122,8 @@
}
data_mq_ = std::move(temp_data_mq);
- return BluetoothAudioProvider::startSession(host_if, audio_config,
- _aidl_return);
+ return BluetoothAudioProvider::startSession(
+ host_if, audio_config, latency_modes, _aidl_return);
}
ndk::ScopedAStatus LeAudioSoftwareAudioProvider::onSessionReady(
diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h
index fa58182..21243ff 100644
--- a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.h
@@ -32,7 +32,9 @@
ndk::ScopedAStatus startSession(
const std::shared_ptr<IBluetoothAudioPort>& host_if,
- const AudioConfiguration& audio_config, DataMQDesc* _aidl_return);
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes,
+ DataMQDesc* _aidl_return);
private:
// audio data queue for software encoding
@@ -51,6 +53,12 @@
LeAudioSoftwareInputAudioProvider();
};
+class LeAudioSoftwareBroadcastAudioProvider
+ : public LeAudioSoftwareAudioProvider {
+ public:
+ LeAudioSoftwareBroadcastAudioProvider();
+};
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/aidl/default/service.cpp b/bluetooth/audio/aidl/default/service.cpp
new file mode 100644
index 0000000..f8f9cde
--- /dev/null
+++ b/bluetooth/audio/aidl/default/service.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BtAudioAIDLService"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothAudioProviderFactory.h"
+
+using ::aidl::android::hardware::bluetooth::audio::
+ BluetoothAudioProviderFactory;
+
+extern "C" __attribute__((visibility("default"))) binder_status_t
+createIBluetoothAudioProviderFactory() {
+ auto factory = ::ndk::SharedRefBase::make<BluetoothAudioProviderFactory>();
+ const std::string instance_name =
+ std::string() + BluetoothAudioProviderFactory::descriptor + "/default";
+ binder_status_t aidl_status = AServiceManager_addService(
+ factory->asBinder().get(), instance_name.c_str());
+ ALOGW_IF(aidl_status != STATUS_OK, "Could not register %s, status=%d",
+ instance_name.c_str(), aidl_status);
+ return aidl_status;
+}
\ No newline at end of file
diff --git a/bluetooth/audio/aidl/vts/Android.bp b/bluetooth/audio/aidl/vts/Android.bp
new file mode 100644
index 0000000..feb952e
--- /dev/null
+++ b/bluetooth/audio/aidl/vts/Android.bp
@@ -0,0 +1,32 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBluetoothAudioTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ tidy_timeout_srcs: ["VtsHalBluetoothAudioTargetTest.cpp"],
+ srcs: ["VtsHalBluetoothAudioTargetTest.cpp"],
+ shared_libs: [
+ "android.hardware.audio.common-V1-ndk",
+ "android.hardware.bluetooth.audio-V1-ndk",
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "libfmq",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
new file mode 100644
index 0000000..18352a0
--- /dev/null
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -0,0 +1,1673 @@
+/*
+ * 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.
+ */
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/audio/BnBluetoothAudioPort.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.h>
+#include <aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include <cstdint>
+#include <future>
+#include <unordered_set>
+#include <vector>
+
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::bluetooth::audio::AacCapabilities;
+using aidl::android::hardware::bluetooth::audio::AacConfiguration;
+using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
+using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
+using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
+using aidl::android::hardware::bluetooth::audio::AudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort;
+using aidl::android::hardware::bluetooth::audio::BroadcastCapability;
+using aidl::android::hardware::bluetooth::audio::ChannelMode;
+using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
+using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::CodecType;
+using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
+using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
+using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
+using aidl::android::hardware::bluetooth::audio::LatencyMode;
+using aidl::android::hardware::bluetooth::audio::Lc3Capabilities;
+using aidl::android::hardware::bluetooth::audio::Lc3Configuration;
+using aidl::android::hardware::bluetooth::audio::LdacCapabilities;
+using aidl::android::hardware::bluetooth::audio::LdacConfiguration;
+using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration;
+using aidl::android::hardware::bluetooth::audio::
+ LeAudioCodecCapabilitiesSetting;
+using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration;
+using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
+using aidl::android::hardware::bluetooth::audio::PresentationPosition;
+using aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
+using aidl::android::hardware::bluetooth::audio::SbcCapabilities;
+using aidl::android::hardware::bluetooth::audio::SbcChannelMode;
+using aidl::android::hardware::bluetooth::audio::SbcConfiguration;
+using aidl::android::hardware::bluetooth::audio::SessionType;
+using aidl::android::hardware::bluetooth::audio::UnicastCapability;
+using aidl::android::hardware::common::fmq::MQDescriptor;
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using android::AidlMessageQueue;
+using android::ProcessState;
+using android::String16;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
+
+using MqDataType = int8_t;
+using MqDataMode = SynchronizedReadWrite;
+using DataMQ = AidlMessageQueue<MqDataType, MqDataMode>;
+using DataMQDesc = MQDescriptor<MqDataType, MqDataMode>;
+
+// Constants
+
+static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000};
+static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
+static constexpr ChannelMode a2dp_channel_modes[] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+static constexpr CodecType a2dp_codec_types[] = {
+ CodecType::UNKNOWN, CodecType::SBC, CodecType::AAC,
+ CodecType::APTX, CodecType::APTX_HD, CodecType::LDAC,
+ CodecType::LC3, CodecType::APTX_ADAPTIVE};
+static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
+// Helpers
+
+template <typename T>
+struct identity {
+ typedef T type;
+};
+
+template <class T>
+bool contained_in_vector(const std::vector<T>& vector,
+ const typename identity<T>::type& target) {
+ return std::find(vector.begin(), vector.end(), target) != vector.end();
+}
+
+void copy_codec_specific(CodecConfiguration::CodecSpecific& dst,
+ const CodecConfiguration::CodecSpecific& src) {
+ switch (src.getTag()) {
+ case CodecConfiguration::CodecSpecific::sbcConfig:
+ dst.set<CodecConfiguration::CodecSpecific::sbcConfig>(
+ src.get<CodecConfiguration::CodecSpecific::sbcConfig>());
+ break;
+ case CodecConfiguration::CodecSpecific::aacConfig:
+ dst.set<CodecConfiguration::CodecSpecific::aacConfig>(
+ src.get<CodecConfiguration::CodecSpecific::aacConfig>());
+ break;
+ case CodecConfiguration::CodecSpecific::ldacConfig:
+ dst.set<CodecConfiguration::CodecSpecific::ldacConfig>(
+ src.get<CodecConfiguration::CodecSpecific::ldacConfig>());
+ break;
+ case CodecConfiguration::CodecSpecific::aptxConfig:
+ dst.set<CodecConfiguration::CodecSpecific::aptxConfig>(
+ src.get<CodecConfiguration::CodecSpecific::aptxConfig>());
+ break;
+ case CodecConfiguration::CodecSpecific::lc3Config:
+ dst.set<CodecConfiguration::CodecSpecific::lc3Config>(
+ src.get<CodecConfiguration::CodecSpecific::lc3Config>());
+ break;
+ case CodecConfiguration::CodecSpecific::aptxAdaptiveConfig:
+ dst.set<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>(
+ src.get<CodecConfiguration::CodecSpecific::aptxAdaptiveConfig>());
+ break;
+ default:
+ break;
+ }
+}
+
+class BluetoothAudioPort : public BnBluetoothAudioPort {
+ public:
+ BluetoothAudioPort() {}
+
+ ndk::ScopedAStatus startStream(bool) { return ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus suspendStream() { return ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus stopStream() { return ScopedAStatus::ok(); }
+
+ ndk::ScopedAStatus getPresentationPosition(PresentationPosition*) {
+ return ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus updateSourceMetadata(const SourceMetadata&) {
+ return ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus updateSinkMetadata(const SinkMetadata&) {
+ return ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus setLatencyMode(const LatencyMode) {
+ return ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus setCodecType(const CodecType) {
+ return ScopedAStatus::ok();
+ }
+
+ protected:
+ virtual ~BluetoothAudioPort() = default;
+};
+
+class BluetoothAudioProviderFactoryAidl
+ : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ provider_factory_ = IBluetoothAudioProviderFactory::fromBinder(
+ SpAIBinder(AServiceManager_getService(GetParam().c_str())));
+ audio_provider_ = nullptr;
+ ASSERT_NE(provider_factory_, nullptr);
+ }
+
+ virtual void TearDown() override { provider_factory_ = nullptr; }
+
+ void GetProviderCapabilitiesHelper(const SessionType& session_type) {
+ temp_provider_capabilities_.clear();
+ auto aidl_retval = provider_factory_->getProviderCapabilities(
+ session_type, &temp_provider_capabilities_);
+ // AIDL calls should not be failed and callback has to be executed
+ ASSERT_TRUE(aidl_retval.isOk());
+ switch (session_type) {
+ case SessionType::UNKNOWN: {
+ ASSERT_TRUE(temp_provider_capabilities_.empty());
+ } break;
+ case SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
+ case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
+ case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
+ case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
+ case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
+ // All software paths are mandatory and must have exact 1
+ // "PcmParameters"
+ ASSERT_EQ(temp_provider_capabilities_.size(), 1);
+ ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
+ AudioCapabilities::pcmCapabilities);
+ } break;
+ case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
+ std::unordered_set<CodecType> codec_types;
+ // empty capability means offload is unsupported
+ for (auto& audio_capability : temp_provider_capabilities_) {
+ ASSERT_EQ(audio_capability.getTag(),
+ AudioCapabilities::a2dpCapabilities);
+ const auto& codec_capabilities =
+ audio_capability.get<AudioCapabilities::a2dpCapabilities>();
+ // Every codec can present once at most
+ ASSERT_EQ(codec_types.count(codec_capabilities.codecType), 0);
+ switch (codec_capabilities.codecType) {
+ case CodecType::SBC:
+ ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+ CodecCapabilities::Capabilities::sbcCapabilities);
+ break;
+ case CodecType::AAC:
+ ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+ CodecCapabilities::Capabilities::aacCapabilities);
+ break;
+ case CodecType::APTX:
+ case CodecType::APTX_HD:
+ ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+ CodecCapabilities::Capabilities::aptxCapabilities);
+ break;
+ case CodecType::LDAC:
+ ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+ CodecCapabilities::Capabilities::ldacCapabilities);
+ break;
+ case CodecType::LC3:
+ ASSERT_EQ(codec_capabilities.capabilities.getTag(),
+ CodecCapabilities::Capabilities::lc3Capabilities);
+ break;
+ case CodecType::APTX_ADAPTIVE:
+ case CodecType::VENDOR:
+ case CodecType::UNKNOWN:
+ break;
+ }
+ codec_types.insert(codec_capabilities.codecType);
+ }
+ } break;
+ case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+ case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
+ case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH: {
+ ASSERT_FALSE(temp_provider_capabilities_.empty());
+ for (auto audio_capability : temp_provider_capabilities_) {
+ ASSERT_EQ(audio_capability.getTag(),
+ AudioCapabilities::leAudioCapabilities);
+ }
+ } break;
+ }
+ }
+
+ /***
+ * This helps to open the specified provider and check the openProvider()
+ * has corruct return values. BUT, to keep it simple, it does not consider
+ * the capability, and please do so at the SetUp of each session's test.
+ ***/
+ void OpenProviderHelper(const SessionType& session_type) {
+ auto aidl_retval =
+ provider_factory_->openProvider(session_type, &audio_provider_);
+ if (aidl_retval.isOk()) {
+ ASSERT_NE(session_type, SessionType::UNKNOWN);
+ ASSERT_NE(audio_provider_, nullptr);
+ audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
+ } else {
+ // Hardware offloading is optional
+ ASSERT_TRUE(
+ session_type == SessionType::UNKNOWN ||
+ session_type ==
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type ==
+ SessionType::
+ LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ ASSERT_EQ(audio_provider_, nullptr);
+ }
+ }
+
+ bool IsPcmConfigSupported(const PcmConfiguration& pcm_config) {
+ if (temp_provider_capabilities_.size() != 1 ||
+ temp_provider_capabilities_[0].getTag() !=
+ AudioCapabilities::pcmCapabilities) {
+ return false;
+ }
+ auto pcm_capability = temp_provider_capabilities_[0]
+ .get<AudioCapabilities::pcmCapabilities>();
+ return (contained_in_vector(pcm_capability.channelMode,
+ pcm_config.channelMode) &&
+ contained_in_vector(pcm_capability.sampleRateHz,
+ pcm_config.sampleRateHz) &&
+ contained_in_vector(pcm_capability.bitsPerSample,
+ pcm_config.bitsPerSample));
+ }
+
+ std::shared_ptr<IBluetoothAudioProviderFactory> provider_factory_;
+ std::shared_ptr<IBluetoothAudioProvider> audio_provider_;
+ std::shared_ptr<IBluetoothAudioPort> audio_port_;
+ std::vector<AudioCapabilities> temp_provider_capabilities_;
+
+ static constexpr SessionType kSessionTypes[] = {
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ };
+};
+
+/**
+ * Test whether we can get the FactoryService from HIDL
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, GetProviderFactoryService) {}
+
+/**
+ * Test whether we can open a provider for each provider returned by
+ * getProviderCapabilities() with non-empty capabalities
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl,
+ OpenProviderAndCheckCapabilitiesBySession) {
+ for (auto session_type : kSessionTypes) {
+ GetProviderCapabilitiesHelper(session_type);
+ OpenProviderHelper(session_type);
+ // We must be able to open a provider if its getProviderCapabilities()
+ // returns non-empty list.
+ EXPECT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+}
+
+/**
+ * openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderA2dpSoftwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpSoftwareAidl, OpenA2dpSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderA2dpSoftwareAidl,
+ StartAndEndA2dpSoftwareSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : a2dp_sample_rates) {
+ for (auto bits_per_sample : a2dp_bits_per_samples) {
+ for (auto channel_mode : a2dp_channel_modes) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .bitsPerSample = bits_per_sample,
+ .channelMode = channel_mode,
+ };
+ bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes,
+ &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(data_mq.isValid());
+ }
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+}
+
+/**
+ * openProvider A2DP_HARDWARE_OFFLOAD_DATAPATH
+ */
+class BluetoothAudioProviderA2dpHardwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool IsOffloadSupported() { return (temp_provider_capabilities_.size() > 0); }
+
+ void GetA2dpOffloadCapabilityHelper(const CodecType& codec_type) {
+ temp_codec_capabilities_ = nullptr;
+ for (auto& codec_capability : temp_provider_capabilities_) {
+ auto& a2dp_capabilities =
+ codec_capability.get<AudioCapabilities::a2dpCapabilities>();
+ if (a2dp_capabilities.codecType != codec_type) {
+ continue;
+ }
+ temp_codec_capabilities_ = &a2dp_capabilities;
+ }
+ }
+
+ std::vector<CodecConfiguration::CodecSpecific>
+ GetSbcCodecSpecificSupportedList(bool supported) {
+ std::vector<CodecConfiguration::CodecSpecific> sbc_codec_specifics;
+ if (!supported) {
+ SbcConfiguration sbc_config{.sampleRateHz = 0, .bitsPerSample = 0};
+ sbc_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(sbc_config));
+ return sbc_codec_specifics;
+ }
+ GetA2dpOffloadCapabilityHelper(CodecType::SBC);
+ if (temp_codec_capabilities_ == nullptr ||
+ temp_codec_capabilities_->codecType != CodecType::SBC) {
+ return sbc_codec_specifics;
+ }
+ // parse the capability
+ auto& sbc_capability =
+ temp_codec_capabilities_->capabilities
+ .get<CodecCapabilities::Capabilities::sbcCapabilities>();
+ if (sbc_capability.minBitpool > sbc_capability.maxBitpool) {
+ return sbc_codec_specifics;
+ }
+
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ for (int32_t sample_rate : sbc_capability.sampleRateHz) {
+ for (int8_t block_length : sbc_capability.blockLength) {
+ for (int8_t num_subbands : sbc_capability.numSubbands) {
+ for (int8_t bits_per_sample : sbc_capability.bitsPerSample) {
+ for (auto channel_mode : sbc_capability.channelMode) {
+ for (auto alloc_method : sbc_capability.allocMethod) {
+ SbcConfiguration sbc_data = {
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .blockLength = block_length,
+ .numSubbands = num_subbands,
+ .allocMethod = alloc_method,
+ .bitsPerSample = bits_per_sample,
+ .minBitpool = sbc_capability.minBitpool,
+ .maxBitpool = sbc_capability.maxBitpool};
+ sbc_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(sbc_data));
+ }
+ }
+ }
+ }
+ }
+ }
+ return sbc_codec_specifics;
+ }
+
+ std::vector<CodecConfiguration::CodecSpecific>
+ GetAacCodecSpecificSupportedList(bool supported) {
+ std::vector<CodecConfiguration::CodecSpecific> aac_codec_specifics;
+ if (!supported) {
+ AacConfiguration aac_config{.sampleRateHz = 0, .bitsPerSample = 0};
+ aac_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(aac_config));
+ return aac_codec_specifics;
+ }
+ GetA2dpOffloadCapabilityHelper(CodecType::AAC);
+ if (temp_codec_capabilities_ == nullptr ||
+ temp_codec_capabilities_->codecType != CodecType::AAC) {
+ return aac_codec_specifics;
+ }
+ // parse the capability
+ auto& aac_capability =
+ temp_codec_capabilities_->capabilities
+ .get<CodecCapabilities::Capabilities::aacCapabilities>();
+
+ std::vector<bool> variable_bit_rate_enableds = {false};
+ if (aac_capability.variableBitRateSupported) {
+ variable_bit_rate_enableds.push_back(true);
+ }
+
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ for (auto object_type : aac_capability.objectType) {
+ for (int32_t sample_rate : aac_capability.sampleRateHz) {
+ for (auto channel_mode : aac_capability.channelMode) {
+ for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
+ for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
+ AacConfiguration aac_data{
+ .objectType = object_type,
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .variableBitRateEnabled = variable_bit_rate_enabled,
+ .bitsPerSample = bits_per_sample};
+ aac_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(aac_data));
+ }
+ }
+ }
+ }
+ }
+ return aac_codec_specifics;
+ }
+
+ std::vector<CodecConfiguration::CodecSpecific>
+ GetLdacCodecSpecificSupportedList(bool supported) {
+ std::vector<CodecConfiguration::CodecSpecific> ldac_codec_specifics;
+ if (!supported) {
+ LdacConfiguration ldac_config{.sampleRateHz = 0, .bitsPerSample = 0};
+ ldac_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(ldac_config));
+ return ldac_codec_specifics;
+ }
+ GetA2dpOffloadCapabilityHelper(CodecType::LDAC);
+ if (temp_codec_capabilities_ == nullptr ||
+ temp_codec_capabilities_->codecType != CodecType::LDAC) {
+ return ldac_codec_specifics;
+ }
+ // parse the capability
+ auto& ldac_capability =
+ temp_codec_capabilities_->capabilities
+ .get<CodecCapabilities::Capabilities::ldacCapabilities>();
+
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ for (int32_t sample_rate : ldac_capability.sampleRateHz) {
+ for (int8_t bits_per_sample : ldac_capability.bitsPerSample) {
+ for (auto channel_mode : ldac_capability.channelMode) {
+ for (auto quality_index : ldac_capability.qualityIndex) {
+ LdacConfiguration ldac_data{.sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .qualityIndex = quality_index,
+ .bitsPerSample = bits_per_sample};
+ ldac_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(ldac_data));
+ }
+ }
+ }
+ }
+ return ldac_codec_specifics;
+ }
+
+ std::vector<CodecConfiguration::CodecSpecific>
+ GetAptxCodecSpecificSupportedList(bool is_hd, bool supported) {
+ std::vector<CodecConfiguration::CodecSpecific> aptx_codec_specifics;
+ if (!supported) {
+ AptxConfiguration aptx_config{.sampleRateHz = 0, .bitsPerSample = 0};
+ aptx_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(aptx_config));
+ return aptx_codec_specifics;
+ }
+ GetA2dpOffloadCapabilityHelper(
+ (is_hd ? CodecType::APTX_HD : CodecType::APTX));
+ if (temp_codec_capabilities_ == nullptr) {
+ return aptx_codec_specifics;
+ }
+ if ((is_hd && temp_codec_capabilities_->codecType != CodecType::APTX_HD) ||
+ (!is_hd && temp_codec_capabilities_->codecType != CodecType::APTX)) {
+ return aptx_codec_specifics;
+ }
+
+ // parse the capability
+ auto& aptx_capability =
+ temp_codec_capabilities_->capabilities
+ .get<CodecCapabilities::Capabilities::aptxCapabilities>();
+
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ for (int8_t bits_per_sample : aptx_capability.bitsPerSample) {
+ for (int32_t sample_rate : aptx_capability.sampleRateHz) {
+ for (auto channel_mode : aptx_capability.channelMode) {
+ AptxConfiguration aptx_data{.sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample};
+ aptx_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(aptx_data));
+ }
+ }
+ }
+ return aptx_codec_specifics;
+ }
+
+ std::vector<CodecConfiguration::CodecSpecific>
+ GetLc3CodecSpecificSupportedList(bool supported) {
+ std::vector<CodecConfiguration::CodecSpecific> lc3_codec_specifics;
+ if (!supported) {
+ Lc3Configuration lc3_config{.samplingFrequencyHz = 0,
+ .frameDurationUs = 0};
+ lc3_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(lc3_config));
+ return lc3_codec_specifics;
+ }
+ GetA2dpOffloadCapabilityHelper(CodecType::LC3);
+ if (temp_codec_capabilities_ == nullptr ||
+ temp_codec_capabilities_->codecType != CodecType::LC3) {
+ return lc3_codec_specifics;
+ }
+ // parse the capability
+ auto& lc3_capability =
+ temp_codec_capabilities_->capabilities
+ .get<CodecCapabilities::Capabilities::lc3Capabilities>();
+
+ // combine those parameters into one list of
+ // CodecConfiguration::CodecSpecific
+ for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
+ for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
+ for (auto channel_mode : lc3_capability.channelMode) {
+ Lc3Configuration lc3_data{.samplingFrequencyHz = samplingFrequencyHz,
+ .channelMode = channel_mode,
+ .frameDurationUs = frameDurationUs};
+ lc3_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(lc3_data));
+ }
+ }
+ }
+ return lc3_codec_specifics;
+ }
+
+ // temp storage saves the specified codec capability by
+ // GetOffloadCodecCapabilityHelper()
+ CodecCapabilities* temp_codec_capabilities_;
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl, OpenA2dpHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * SBC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+ StartAndEndA2dpSbcHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ CodecConfiguration codec_config = {
+ .codecType = CodecType::SBC,
+ .encodedAudioBitrate = 328000,
+ .peerMtu = 1005,
+ .isScmstEnabled = false,
+ };
+ auto sbc_codec_specifics = GetSbcCodecSpecificSupportedList(true);
+
+ for (auto& codec_specific : sbc_codec_specifics) {
+ copy_codec_specific(codec_config.config, codec_specific);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * AAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+ StartAndEndA2dpAacHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ CodecConfiguration codec_config = {
+ .codecType = CodecType::AAC,
+ .encodedAudioBitrate = 320000,
+ .peerMtu = 1005,
+ .isScmstEnabled = false,
+ };
+ auto aac_codec_specifics = GetAacCodecSpecificSupportedList(true);
+
+ for (auto& codec_specific : aac_codec_specifics) {
+ copy_codec_specific(codec_config.config, codec_specific);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * LDAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+ StartAndEndA2dpLdacHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ CodecConfiguration codec_config = {
+ .codecType = CodecType::LDAC,
+ .encodedAudioBitrate = 990000,
+ .peerMtu = 1005,
+ .isScmstEnabled = false,
+ };
+ auto ldac_codec_specifics = GetLdacCodecSpecificSupportedList(true);
+
+ for (auto& codec_specific : ldac_codec_specifics) {
+ copy_codec_specific(codec_config.config, codec_specific);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * LDAC hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+ StartAndEndA2dpLc3HardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ CodecConfiguration codec_config = {
+ .codecType = CodecType::LC3,
+ .encodedAudioBitrate = 990000,
+ .peerMtu = 1005,
+ .isScmstEnabled = false,
+ };
+ auto lc3_codec_specifics = GetLc3CodecSpecificSupportedList(true);
+
+ for (auto& codec_specific : lc3_codec_specifics) {
+ copy_codec_specific(codec_config.config, codec_specific);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(codec_config), latency_modes, &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * AptX hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+ StartAndEndA2dpAptxHardwareSession) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+
+ for (auto codec_type : {CodecType::APTX, CodecType::APTX_HD}) {
+ CodecConfiguration codec_config = {
+ .codecType = codec_type,
+ .encodedAudioBitrate =
+ (codec_type == CodecType::APTX ? 352000 : 576000),
+ .peerMtu = 1005,
+ .isScmstEnabled = false,
+ };
+
+ auto aptx_codec_specifics = GetAptxCodecSpecificSupportedList(
+ (codec_type == CodecType::APTX_HD ? true : false), true);
+
+ for (auto& codec_specific : aptx_codec_specifics) {
+ copy_codec_specific(codec_config.config, codec_specific);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(codec_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::A2DP_HARDWARE_ENCODING_DATAPATH can be started and stopped with
+ * an invalid codec config
+ */
+TEST_P(BluetoothAudioProviderA2dpHardwareAidl,
+ StartAndEndA2dpHardwareSessionInvalidCodecConfig) {
+ if (!IsOffloadSupported()) {
+ return;
+ }
+ ASSERT_NE(audio_provider_, nullptr);
+
+ std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
+ for (auto codec_type : a2dp_codec_types) {
+ switch (codec_type) {
+ case CodecType::SBC:
+ codec_specifics = GetSbcCodecSpecificSupportedList(false);
+ break;
+ case CodecType::AAC:
+ codec_specifics = GetAacCodecSpecificSupportedList(false);
+ break;
+ case CodecType::LDAC:
+ codec_specifics = GetLdacCodecSpecificSupportedList(false);
+ break;
+ case CodecType::APTX:
+ codec_specifics = GetAptxCodecSpecificSupportedList(false, false);
+ break;
+ case CodecType::APTX_HD:
+ codec_specifics = GetAptxCodecSpecificSupportedList(true, false);
+ break;
+ case CodecType::LC3:
+ codec_specifics = GetLc3CodecSpecificSupportedList(false);
+ continue;
+ case CodecType::APTX_ADAPTIVE:
+ case CodecType::VENDOR:
+ case CodecType::UNKNOWN:
+ codec_specifics.clear();
+ break;
+ }
+ if (codec_specifics.empty()) {
+ continue;
+ }
+
+ CodecConfiguration codec_config = {
+ .codecType = codec_type,
+ .encodedAudioBitrate = 328000,
+ .peerMtu = 1005,
+ .isScmstEnabled = false,
+ };
+ for (auto codec_specific : codec_specifics) {
+ copy_codec_specific(codec_config.config, codec_specific);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(codec_config), latency_modes,
+ &mq_desc);
+
+ // AIDL call should fail on invalid codec
+ ASSERT_FALSE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+}
+
+/**
+ * openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderHearingAidSoftwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ static constexpr int32_t hearing_aid_sample_rates_[] = {0, 16000, 24000};
+ static constexpr int8_t hearing_aid_bits_per_samples_[] = {0, 16, 24};
+ static constexpr ChannelMode hearing_aid_channel_modes_[] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
+ OpenHearingAidSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderHearingAidSoftwareAidl,
+ StartAndEndHearingAidSessionWithPossiblePcmConfig) {
+ for (int32_t sample_rate : hearing_aid_sample_rates_) {
+ for (int8_t bits_per_sample : hearing_aid_bits_per_samples_) {
+ for (auto channel_mode : hearing_aid_channel_modes_) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .bitsPerSample = bits_per_sample,
+ .channelMode = channel_mode,
+ };
+ bool is_codec_config_valid = IsPcmConfigSupported(pcm_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes,
+ &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(data_mq.isValid());
+ }
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+}
+
+/**
+ * openProvider LE_AUDIO_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioOutputSoftwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ static constexpr int32_t le_audio_output_sample_rates_[] = {
+ 0, 8000, 16000, 24000, 32000, 44100, 48000,
+ };
+ static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
+ static constexpr ChannelMode le_audio_output_channel_modes_[] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+ static constexpr int32_t le_audio_output_data_interval_us_[] = {
+ 0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
+ OpenLeAudioOutputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputSoftwareAidl,
+ StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : le_audio_output_sample_rates_) {
+ for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
+ for (auto channel_mode : le_audio_output_channel_modes_) {
+ for (auto data_interval_us : le_audio_output_data_interval_us_) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .bitsPerSample = bits_per_sample,
+ .channelMode = channel_mode,
+ .dataIntervalUs = data_interval_us,
+ };
+ bool is_codec_config_valid =
+ IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes,
+ &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(data_mq.isValid());
+ }
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
+ * openProvider LE_AUDIO_SOFTWARE_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioInputSoftwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
+ OpenProviderHelper(SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ static constexpr int32_t le_audio_input_sample_rates_[] = {
+ 0, 8000, 16000, 24000, 32000, 44100, 48000};
+ static constexpr int8_t le_audio_input_bits_per_samples_[] = {0, 16, 24};
+ static constexpr ChannelMode le_audio_input_channel_modes_[] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+ static constexpr int32_t le_audio_input_data_interval_us_[] = {
+ 0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
+ OpenLeAudioInputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputSoftwareAidl,
+ StartAndEndLeAudioInputSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : le_audio_input_sample_rates_) {
+ for (auto bits_per_sample : le_audio_input_bits_per_samples_) {
+ for (auto channel_mode : le_audio_input_channel_modes_) {
+ for (auto data_interval_us : le_audio_input_data_interval_us_) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .bitsPerSample = bits_per_sample,
+ .channelMode = channel_mode,
+ .dataIntervalUs = data_interval_us,
+ };
+ bool is_codec_config_valid =
+ IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes,
+ &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(data_mq.isValid());
+ }
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
+ * openProvider LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioOutputHardwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ OpenProviderHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool IsOffloadOutputSupported() {
+ for (auto& capability : temp_provider_capabilities_) {
+ if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+ continue;
+ }
+ auto& le_audio_capability =
+ capability.get<AudioCapabilities::leAudioCapabilities>();
+ if (le_audio_capability.unicastEncodeCapability.codecType !=
+ CodecType::UNKNOWN)
+ return true;
+ }
+ return false;
+ }
+
+ std::vector<Lc3Configuration> GetUnicastLc3SupportedList(bool decoding,
+ bool supported) {
+ std::vector<Lc3Configuration> le_audio_codec_configs;
+ if (!supported) {
+ Lc3Configuration lc3_config{.samplingFrequencyHz = 0, .pcmBitDepth = 0};
+ le_audio_codec_configs.push_back(lc3_config);
+ return le_audio_codec_configs;
+ }
+
+ // There might be more than one LeAudioCodecCapabilitiesSetting
+ std::vector<Lc3Capabilities> lc3_capabilities;
+ for (auto& capability : temp_provider_capabilities_) {
+ if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+ continue;
+ }
+ auto& le_audio_capability =
+ capability.get<AudioCapabilities::leAudioCapabilities>();
+ auto& unicast_capability =
+ decoding ? le_audio_capability.unicastDecodeCapability
+ : le_audio_capability.unicastEncodeCapability;
+ if (unicast_capability.codecType != CodecType::LC3) {
+ continue;
+ }
+ auto& lc3_capability = unicast_capability.leAudioCodecCapabilities.get<
+ UnicastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
+ lc3_capabilities.push_back(lc3_capability);
+ }
+
+ // Combine those parameters into one list of LeAudioCodecConfiguration
+ // This seems horrible, but usually each Lc3Capability only contains a
+ // single Lc3Configuration, which means every array has a length of 1.
+ for (auto& lc3_capability : lc3_capabilities) {
+ for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
+ for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
+ for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
+ Lc3Configuration lc3_config = {
+ .samplingFrequencyHz = samplingFrequencyHz,
+ .frameDurationUs = frameDurationUs,
+ .octetsPerFrame = octetsPerFrame,
+ };
+ le_audio_codec_configs.push_back(lc3_config);
+ }
+ }
+ }
+ }
+
+ return le_audio_codec_configs;
+ }
+
+ LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ OpenLeAudioOutputHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ StartAndEndLeAudioOutputSessionWithPossibleUnicastConfig) {
+ if (!IsOffloadOutputSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs =
+ GetUnicastLc3SupportedList(false /* decoding */, true /* supported */);
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ *
+ * Disabled since offload codec checking is not ready
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ DISABLED_StartAndEndLeAudioOutputSessionWithInvalidAudioConfiguration) {
+ if (!IsOffloadOutputSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs =
+ GetUnicastLc3SupportedList(false /* decoding */, false /* supported */);
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ // AIDL call should fail on invalid codec
+ ASSERT_FALSE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioInputHardwareAidl
+ : public BluetoothAudioProviderLeAudioOutputHardwareAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+ OpenProviderHelper(
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ bool IsOffloadInputSupported() {
+ for (auto& capability : temp_provider_capabilities_) {
+ if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+ continue;
+ }
+ auto& le_audio_capability =
+ capability.get<AudioCapabilities::leAudioCapabilities>();
+ if (le_audio_capability.unicastDecodeCapability.codecType !=
+ CodecType::UNKNOWN)
+ return true;
+ }
+ return false;
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+ OpenLeAudioInputHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+ StartAndEndLeAudioInputSessionWithPossibleUnicastConfig) {
+ if (!IsOffloadInputSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs =
+ GetUnicastLc3SupportedList(true /* decoding */, true /* supported */);
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ *
+ * Disabled since offload codec checking is not ready
+ */
+TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl,
+ DISABLED_StartAndEndLeAudioInputSessionWithInvalidAudioConfiguration) {
+ if (!IsOffloadInputSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs =
+ GetUnicastLc3SupportedList(true /* decoding */, false /* supported */);
+ LeAudioConfiguration le_audio_config = {
+ .codecType = CodecType::LC3,
+ .peerDelayUs = 0,
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::lc3Config>(lc3_config);
+
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ // AIDL call should fail on invalid codec
+ ASSERT_FALSE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * openProvider LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioBroadcastSoftwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ static constexpr int32_t le_audio_output_sample_rates_[] = {
+ 0, 8000, 16000, 24000, 32000, 44100, 48000,
+ };
+ static constexpr int8_t le_audio_output_bits_per_samples_[] = {0, 16, 24};
+ static constexpr ChannelMode le_audio_output_channel_modes_[] = {
+ ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
+ static constexpr int32_t le_audio_output_data_interval_us_[] = {
+ 0 /* Invalid */, 10000 /* Valid 10ms */};
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
+ OpenLeAudioOutputSoftwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH can be started and
+ * stopped with different PCM config
+ */
+TEST_P(BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
+ StartAndEndLeAudioOutputSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : le_audio_output_sample_rates_) {
+ for (auto bits_per_sample : le_audio_output_bits_per_samples_) {
+ for (auto channel_mode : le_audio_output_channel_modes_) {
+ for (auto data_interval_us : le_audio_output_data_interval_us_) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .bitsPerSample = bits_per_sample,
+ .channelMode = channel_mode,
+ .dataIntervalUs = data_interval_us,
+ };
+ bool is_codec_config_valid =
+ IsPcmConfigSupported(pcm_config) && pcm_config.dataIntervalUs > 0;
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes,
+ &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ EXPECT_EQ(aidl_retval.isOk(), is_codec_config_valid);
+ if (is_codec_config_valid) {
+ EXPECT_TRUE(data_mq.isValid());
+ }
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
+ * openProvider LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderLeAudioBroadcastHardwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ OpenProviderHelper(
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool IsBroadcastOffloadSupported() {
+ for (auto& capability : temp_provider_capabilities_) {
+ if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+ continue;
+ }
+ auto& le_audio_capability =
+ capability.get<AudioCapabilities::leAudioCapabilities>();
+ if (le_audio_capability.broadcastCapability.codecType !=
+ CodecType::UNKNOWN)
+ return true;
+ }
+ return false;
+ }
+
+ std::vector<Lc3Configuration> GetBroadcastLc3SupportedList(bool supported) {
+ std::vector<Lc3Configuration> le_audio_codec_configs;
+ if (!supported) {
+ Lc3Configuration lc3_config{.samplingFrequencyHz = 0, .pcmBitDepth = 0};
+ le_audio_codec_configs.push_back(lc3_config);
+ return le_audio_codec_configs;
+ }
+
+ // There might be more than one LeAudioCodecCapabilitiesSetting
+ std::vector<Lc3Capabilities> lc3_capabilities;
+ for (auto& capability : temp_provider_capabilities_) {
+ if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+ continue;
+ }
+ auto& le_audio_capability =
+ capability.get<AudioCapabilities::leAudioCapabilities>();
+ auto& broadcast_capability = le_audio_capability.broadcastCapability;
+ if (broadcast_capability.codecType != CodecType::LC3) {
+ continue;
+ }
+ auto& lc3_capability = broadcast_capability.leAudioCodecCapabilities.get<
+ BroadcastCapability::LeAudioCodecCapabilities::lc3Capabilities>();
+ for (int idx = 0; idx < lc3_capability->size(); idx++)
+ lc3_capabilities.push_back(*lc3_capability->at(idx));
+ }
+
+ // Combine those parameters into one list of LeAudioCodecConfiguration
+ // This seems horrible, but usually each Lc3Capability only contains a
+ // single Lc3Configuration, which means every array has a length of 1.
+ for (auto& lc3_capability : lc3_capabilities) {
+ for (int32_t samplingFrequencyHz : lc3_capability.samplingFrequencyHz) {
+ for (int32_t frameDurationUs : lc3_capability.frameDurationUs) {
+ for (int32_t octetsPerFrame : lc3_capability.octetsPerFrame) {
+ Lc3Configuration lc3_config = {
+ .samplingFrequencyHz = samplingFrequencyHz,
+ .frameDurationUs = frameDurationUs,
+ .octetsPerFrame = octetsPerFrame,
+ };
+ le_audio_codec_configs.push_back(lc3_config);
+ }
+ }
+ }
+ }
+
+ return le_audio_codec_configs;
+ }
+
+ LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
+};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
+ * started and stopped
+ */
+TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ OpenLeAudioOutputHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
+ * started and stopped with broadcast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ StartAndEndLeAudioBroadcastSessionWithPossibleBroadcastConfig) {
+ if (!IsBroadcastOffloadSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs = GetBroadcastLc3SupportedList(true /* supported */);
+ LeAudioBroadcastConfiguration le_audio_broadcast_config = {
+ .codecType = CodecType::LC3,
+ .streamMap = {},
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_broadcast_config.streamMap[0]
+ .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
+ lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_broadcast_config),
+ latency_modes, &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be
+ * started and stopped with Broadcast hardware encoding config
+ *
+ * Disabled since offload codec checking is not ready
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ DISABLED_StartAndEndLeAudioBroadcastSessionWithInvalidAudioConfiguration) {
+ if (!IsBroadcastOffloadSupported()) {
+ return;
+ }
+
+ auto lc3_codec_configs = GetBroadcastLc3SupportedList(false /* supported */);
+ LeAudioBroadcastConfiguration le_audio_broadcast_config = {
+ .codecType = CodecType::LC3,
+ .streamMap = {},
+ };
+
+ for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_broadcast_config.streamMap[0]
+ .leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
+ lc3_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_broadcast_config),
+ latency_modes, &mq_desc);
+
+ // AIDL call should fail on invalid codec
+ ASSERT_FALSE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderFactoryAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderFactoryAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderA2dpSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpSoftwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderA2dpHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderA2dpHardwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHearingAidSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHearingAidSoftwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioOutputSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioOutputSoftwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioInputSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioInputSoftwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioOutputHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioInputHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioInputHardwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioBroadcastSoftwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioBroadcastSoftwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderLeAudioBroadcastHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderLeAudioBroadcastHardwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 974357e..42f9455 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -14,10 +14,8 @@
srcs: [
"session/BluetoothAudioSession.cpp",
"session/BluetoothAudioSession_2_1.cpp",
- "session/BluetoothAudioSession_2_2.cpp",
"session/BluetoothAudioSupportedCodecsDB.cpp",
"session/BluetoothAudioSupportedCodecsDB_2_1.cpp",
- "session/BluetoothAudioSupportedCodecsDB_2_2.cpp",
],
export_include_dirs: ["session/"],
header_libs: ["libhardware_headers"],
@@ -25,7 +23,6 @@
"android.hardware.audio.common@5.0",
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"libbase",
"libcutils",
"libfmq",
@@ -49,7 +46,6 @@
shared_libs: [
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
- "android.hardware.bluetooth.audio@2.2",
"libbase",
"libcutils",
"libbinder_ndk",
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index a8d8817..8fd1ab5 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -132,9 +132,13 @@
// Stores the supported setting of audio location, connected device, and the
// channel count for each device
std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
- supportedDeviceSetting = {std::make_tuple(stereoAudio, 2, 1),
- std::make_tuple(monoAudio, 1, 2),
- std::make_tuple(monoAudio, 1, 1)};
+ supportedDeviceSetting = {
+ // Stereo, two connected device, one for L one for R
+ std::make_tuple(stereoAudio, 2, 1),
+ // Stereo, one connected device for both L and R
+ std::make_tuple(stereoAudio, 1, 2),
+ // Mono
+ std::make_tuple(monoAudio, 1, 1)};
template <class T>
bool BluetoothAudioCodecs::ContainedInVector(
@@ -303,7 +307,9 @@
if (session_type !=
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
session_type !=
- SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
+ session_type !=
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
return false;
}
return true;
@@ -447,7 +453,9 @@
if (session_type !=
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
session_type !=
- SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
+ session_type !=
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
return std::vector<LeAudioCodecCapabilitiesSetting>(0);
}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index 96cd9ef..e700e7e 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -94,6 +94,8 @@
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
+ case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+ return AudioConfiguration(LeAudioBroadcastConfiguration{});
default:
return AudioConfiguration(PcmConfiguration{});
}
@@ -137,6 +139,8 @@
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ ==
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
(data_mq_ != nullptr && data_mq_->isValid()));
return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
}
@@ -194,7 +198,7 @@
<< " has NO session";
return false;
}
- auto hal_retval = stack_iface_->startStream();
+ auto hal_retval = stack_iface_->startStream(false);
if (!hal_retval.isOk()) {
LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
<< toString(session_type_) << " failed";
@@ -259,7 +263,9 @@
(session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
- session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
+ session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ ==
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH);
bool is_offload_a2dp_session =
(session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
bool is_offload_le_audio_session =
@@ -410,6 +416,22 @@
}
}
+void BluetoothAudioSession::ReportLowLatencyModeAllowedChanged(bool allowed) {
+ std::lock_guard<std::recursive_mutex> guard(mutex_);
+ if (observers_.empty()) {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO port state observer";
+ return;
+ }
+ for (auto& observer : observers_) {
+ uint16_t cookie = observer.first;
+ std::shared_ptr<PortStatusCallbacks> callback = observer.second;
+ LOG(INFO) << __func__
+ << " - allowed=" << (allowed ? " allowed" : " disallowed");
+ callback->low_latency_mode_allowed_cb_(cookie, allowed);
+ }
+}
+
bool BluetoothAudioSession::GetPresentationPosition(
PresentationPosition& presentation_position) {
std::lock_guard<std::recursive_mutex> guard(mutex_);
@@ -523,21 +545,6 @@
}
}
-void BluetoothAudioSession::SetCodecType(CodecType codec_type) {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- return;
- }
-
- auto hal_retval = stack_iface_->setCodecType(codec_type);
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_) << " failed";
- }
-}
-
bool BluetoothAudioSession::IsAidlAvailable() {
if (is_aidl_checked) return is_aidl_available;
is_aidl_available =
@@ -577,4 +584,4 @@
} // namespace bluetooth
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
index 5adc0e2..6e390cc 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.h
@@ -92,6 +92,15 @@
* @param: cookie - indicates which bluetooth_audio output should handle
***/
std::function<void(uint16_t cookie)> audio_configuration_changed_cb_;
+ /***
+ * low_latency_mode_allowed_cb_ - when the Bluetooth stack low latency mode
+ * allowed or disallowed, the BluetoothAudioProvider will invoke
+ * this callback to report to the bluetooth_audio module.
+ * @param: cookie - indicates which bluetooth_audio output should handle
+ * @param: allowed - indicates if low latency mode is allowed
+ ***/
+ std::function<void(uint16_t cookie, bool allowed)>
+ low_latency_mode_allowed_cb_;
};
class BluetoothAudioSession {
@@ -156,6 +165,13 @@
void ReportAudioConfigChanged(const AudioConfiguration& audio_config);
/***
+ * The report function is used to report that the Bluetooth stack has notified
+ * the low latency mode allowed changed, and will invoke
+ * low_latency_mode_allowed_changed_cb to notify registered bluetooth_audio
+ * outputs
+ ***/
+ void ReportLowLatencyModeAllowedChanged(bool allowed);
+ /***
* Those control functions are for the bluetooth_audio module to start,
* suspend, stop stream, to check position, and to update metadata.
***/
@@ -166,7 +182,6 @@
void UpdateSourceMetadata(const struct source_metadata& source_metadata);
void UpdateSinkMetadata(const struct sink_metadata& sink_metadata);
void SetLatencyMode(LatencyMode latency_mode);
- void SetCodecType(CodecType codec_type);
// The control function writes stream to FMQ
size_t OutWritePcmData(const void* buffer, size_t bytes);
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
index aff01e5..451a31f 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
@@ -86,6 +86,8 @@
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
+ case SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
+ return AudioConfiguration(LeAudioBroadcastConfiguration{});
default:
return AudioConfiguration(PcmConfiguration{});
}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
index 18569c3..03776b5 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionReport.h
@@ -78,6 +78,18 @@
session_ptr->ReportAudioConfigChanged(audio_config);
}
}
+ /***
+ * The API reports the Bluetooth stack has replied the changed of the low
+ * latency audio allowed, and will inform registered bluetooth_audio outputs
+ ***/
+ static void ReportLowLatencyModeAllowedChanged(
+ const SessionType& session_type, bool allowed) {
+ std::shared_ptr<BluetoothAudioSession> session_ptr =
+ BluetoothAudioSessionInstance::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->ReportLowLatencyModeAllowedChanged(allowed);
+ }
+ }
};
} // namespace audio
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
index 632a389..a4664f1 100644
--- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
@@ -28,7 +28,6 @@
#include "../aidl_session/BluetoothAudioSessionControl.h"
#include "HidlToAidlMiddleware_2_0.h"
#include "HidlToAidlMiddleware_2_1.h"
-#include "HidlToAidlMiddleware_2_2.h"
namespace aidl {
namespace android {
@@ -82,15 +81,10 @@
using Lc3FrameDuration_2_1 =
::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
-using LeAudioConfig_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
-using LeAudioMode_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
-
std::mutex legacy_callback_lock;
std::unordered_map<
SessionType,
- std::unordered_map<uint16_t, std::shared_ptr<PortStatusCallbacks_2_2>>>
+ std::unordered_map<uint16_t, std::shared_ptr<PortStatusCallbacks_2_0>>>
legacy_callback_table;
const static std::unordered_map<SessionType_2_1, SessionType>
@@ -418,102 +412,47 @@
}
inline Lc3CodecConfig_2_1 to_hidl_leaudio_config_2_1(
- const LeAudioConfiguration& leaudio_config) {
+ const LeAudioConfiguration& unicast_config) {
Lc3CodecConfig_2_1 hidl_lc3_codec_config = {
.audioChannelAllocation = 0,
};
- if (leaudio_config.modeConfig.getTag() ==
- LeAudioConfiguration::LeAudioModeConfig::unicastConfig) {
- auto& unicast_config =
- leaudio_config.modeConfig
- .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>();
- if (unicast_config.leAudioCodecConfig.getTag() ==
- LeAudioCodecConfiguration::lc3Config) {
- LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)";
- }
- auto& le_codec_config = unicast_config.leAudioCodecConfig
- .get<LeAudioCodecConfiguration::lc3Config>();
-
- hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config);
-
- for (const auto& map : unicast_config.streamMap) {
- hidl_lc3_codec_config.audioChannelAllocation |=
- map.audioChannelAllocation;
- }
- } else {
- // NOTE: Broadcast is not officially supported in HIDL
- auto& bcast_config =
- leaudio_config.modeConfig
- .get<LeAudioConfiguration::LeAudioModeConfig::broadcastConfig>();
- if (bcast_config.streamMap.empty()) {
- return hidl_lc3_codec_config;
- }
- if (bcast_config.streamMap[0].leAudioCodecConfig.getTag() !=
- LeAudioCodecConfiguration::lc3Config) {
- LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)";
- }
- auto& le_codec_config =
- bcast_config.streamMap[0]
- .leAudioCodecConfig.get<LeAudioCodecConfiguration::lc3Config>();
- hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config);
-
- for (const auto& map : bcast_config.streamMap) {
- hidl_lc3_codec_config.audioChannelAllocation |=
- map.audioChannelAllocation;
- }
+ if (unicast_config.leAudioCodecConfig.getTag() ==
+ LeAudioCodecConfiguration::lc3Config) {
+ LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)";
}
+ auto& le_codec_config = unicast_config.leAudioCodecConfig
+ .get<LeAudioCodecConfiguration::lc3Config>();
+ hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config);
+
+ for (const auto& map : unicast_config.streamMap) {
+ hidl_lc3_codec_config.audioChannelAllocation |= map.audioChannelAllocation;
+ }
return hidl_lc3_codec_config;
}
-inline LeAudioConfig_2_2 to_hidl_leaudio_config_2_2(
- const LeAudioConfiguration& leaudio_config) {
- LeAudioConfig_2_2 hidl_leaudio_config;
-
- if (leaudio_config.modeConfig.getTag() ==
- LeAudioConfiguration::LeAudioModeConfig::unicastConfig) {
- hidl_leaudio_config.mode = LeAudioMode_2_2::UNICAST;
- auto& unicast_config =
- leaudio_config.modeConfig
- .get<LeAudioConfiguration::LeAudioModeConfig::unicastConfig>();
- ::android::hardware::bluetooth::audio::V2_2::UnicastConfig
- hidl_unicast_config;
- hidl_unicast_config.peerDelay =
- static_cast<uint32_t>(unicast_config.peerDelay);
-
- auto& lc3_config = unicast_config.leAudioCodecConfig
- .get<LeAudioCodecConfiguration::lc3Config>();
- hidl_unicast_config.lc3Config = to_hidl_lc3_config_2_1(lc3_config);
-
- hidl_unicast_config.streamMap.resize(unicast_config.streamMap.size());
- for (int i = 0; i < unicast_config.streamMap.size(); i++) {
- hidl_unicast_config.streamMap[i].audioChannelAllocation =
- static_cast<uint32_t>(
- unicast_config.streamMap[i].audioChannelAllocation);
- hidl_unicast_config.streamMap[i].streamHandle =
- static_cast<uint16_t>(unicast_config.streamMap[i].streamHandle);
- }
- } else if (leaudio_config.modeConfig.getTag() ==
- LeAudioConfiguration::LeAudioModeConfig::broadcastConfig) {
- hidl_leaudio_config.mode = LeAudioMode_2_2::BROADCAST;
- auto bcast_config =
- leaudio_config.modeConfig
- .get<LeAudioConfiguration::LeAudioModeConfig::broadcastConfig>();
- ::android::hardware::bluetooth::audio::V2_2::BroadcastConfig
- hidl_bcast_config;
- hidl_bcast_config.streamMap.resize(bcast_config.streamMap.size());
- for (int i = 0; i < bcast_config.streamMap.size(); i++) {
- hidl_bcast_config.streamMap[i].audioChannelAllocation =
- static_cast<uint32_t>(
- bcast_config.streamMap[i].audioChannelAllocation);
- hidl_bcast_config.streamMap[i].streamHandle =
- static_cast<uint16_t>(bcast_config.streamMap[i].streamHandle);
- hidl_bcast_config.streamMap[i].lc3Config = to_hidl_lc3_config_2_1(
- bcast_config.streamMap[i]
- .leAudioCodecConfig.get<LeAudioCodecConfiguration::lc3Config>());
- }
+inline Lc3CodecConfig_2_1 to_hidl_leaudio_broadcast_config_2_1(
+ const LeAudioBroadcastConfiguration& broadcast_config) {
+ Lc3CodecConfig_2_1 hidl_lc3_codec_config = {
+ .audioChannelAllocation = 0,
+ };
+ // NOTE: Broadcast is not officially supported in HIDL
+ if (broadcast_config.streamMap.empty()) {
+ return hidl_lc3_codec_config;
}
- return hidl_leaudio_config;
+ if (broadcast_config.streamMap[0].leAudioCodecConfig.getTag() !=
+ LeAudioCodecConfiguration::lc3Config) {
+ LOG(FATAL) << __func__ << ": unexpected codec type(vendor?)";
+ }
+ auto& le_codec_config =
+ broadcast_config.streamMap[0]
+ .leAudioCodecConfig.get<LeAudioCodecConfiguration::lc3Config>();
+ hidl_lc3_codec_config.lc3Config = to_hidl_lc3_config_2_1(le_codec_config);
+
+ for (const auto& map : broadcast_config.streamMap) {
+ hidl_lc3_codec_config.audioChannelAllocation |= map.audioChannelAllocation;
+ }
+ return hidl_lc3_codec_config;
}
inline AudioConfig_2_1 to_hidl_audio_config_2_1(
@@ -532,25 +471,9 @@
hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1(
audio_config.get<AudioConfiguration::leAudioConfig>()));
break;
- }
- return hidl_audio_config;
-}
-
-inline AudioConfig_2_2 to_hidl_audio_config_2_2(
- const AudioConfiguration& audio_config) {
- AudioConfig_2_2 hidl_audio_config;
- switch (audio_config.getTag()) {
- case AudioConfiguration::pcmConfig:
- hidl_audio_config.pcmConfig(to_hidl_pcm_config_2_1(
- audio_config.get<AudioConfiguration::pcmConfig>()));
- break;
- case AudioConfiguration::a2dpConfig:
- hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
- audio_config.get<AudioConfiguration::a2dpConfig>()));
- break;
- case AudioConfiguration::leAudioConfig:
- hidl_audio_config.leAudioConfig(to_hidl_leaudio_config_2_2(
- audio_config.get<AudioConfiguration::leAudioConfig>()));
+ case AudioConfiguration::leAudioBroadcastConfig:
+ hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_broadcast_config_2_1(
+ audio_config.get<AudioConfiguration::leAudioBroadcastConfig>()));
break;
}
return hidl_audio_config;
@@ -571,18 +494,58 @@
uint16_t HidlToAidlMiddleware_2_0::RegisterControlResultCback(
const SessionType_2_0& session_type,
const PortStatusCallbacks_2_0& cbacks) {
- PortStatusCallbacks_2_2 callback_2_2{
- .control_result_cb_ = cbacks.control_result_cb_,
- .session_changed_cb_ = cbacks.session_changed_cb_,
+ LOG(INFO) << __func__ << ": " << toString(session_type);
+ auto aidl_session_type = from_session_type_2_0(session_type);
+ // Pass the exact reference to the lambda
+ auto& session_legacy_callback_table =
+ legacy_callback_table[aidl_session_type];
+ PortStatusCallbacks aidl_callbacks{};
+ if (cbacks.control_result_cb_) {
+ aidl_callbacks.control_result_cb_ =
+ [&session_legacy_callback_table](uint16_t cookie, bool start_resp,
+ const BluetoothAudioStatus& status) {
+ if (session_legacy_callback_table.find(cookie) ==
+ session_legacy_callback_table.end()) {
+ LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+ return;
+ }
+ auto& cback = session_legacy_callback_table[cookie];
+ cback->control_result_cb_(cookie, start_resp, to_hidl_status(status));
+ };
+ }
+ if (cbacks.session_changed_cb_) {
+ aidl_callbacks.session_changed_cb_ =
+ [&session_legacy_callback_table](uint16_t cookie) {
+ if (session_legacy_callback_table.find(cookie) ==
+ session_legacy_callback_table.end()) {
+ LOG(ERROR) << __func__ << ": Unknown callback invoked!";
+ return;
+ }
+ auto& cback = session_legacy_callback_table[cookie];
+ cback->session_changed_cb_(cookie);
+ };
};
- return HidlToAidlMiddleware_2_2::RegisterControlResultCback(
- static_cast<SessionType_2_1>(session_type), callback_2_2);
+ auto cookie = BluetoothAudioSessionControl::RegisterControlResultCback(
+ aidl_session_type, aidl_callbacks);
+ {
+ std::lock_guard<std::mutex> guard(legacy_callback_lock);
+ session_legacy_callback_table[cookie] =
+ std::make_shared<PortStatusCallbacks_2_0>(cbacks);
+ }
+ return cookie;
}
void HidlToAidlMiddleware_2_0::UnregisterControlResultCback(
const SessionType_2_0& session_type, uint16_t cookie) {
- HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
- static_cast<SessionType_2_1>(session_type), cookie);
+ LOG(INFO) << __func__ << ": " << toString(session_type);
+ auto aidl_session_type = from_session_type_2_0(session_type);
+ BluetoothAudioSessionControl::UnregisterControlResultCback(aidl_session_type,
+ cookie);
+ auto& session_callback_table = legacy_callback_table[aidl_session_type];
+ if (session_callback_table.find(cookie) != session_callback_table.end()) {
+ std::lock_guard<std::mutex> guard(legacy_callback_lock);
+ session_callback_table.erase(cookie);
+ }
}
const AudioConfig_2_0 HidlToAidlMiddleware_2_0::GetAudioConfig(
@@ -662,124 +625,6 @@
from_session_type_2_1(session_type)));
}
-/***
- *
- * 2.2
- *
- ***/
-
-bool HidlToAidlMiddleware_2_2::IsSessionReady(
- const SessionType_2_1& session_type) {
- return BluetoothAudioSessionControl::IsSessionReady(
- from_session_type_2_1(session_type));
-}
-
-uint16_t HidlToAidlMiddleware_2_2::RegisterControlResultCback(
- const SessionType_2_1& session_type,
- const PortStatusCallbacks_2_2& cbacks) {
- LOG(INFO) << __func__ << ": " << toString(session_type);
- auto aidl_session_type = from_session_type_2_1(session_type);
- // Pass the exact reference to the lambda
- auto& session_legacy_callback_table =
- legacy_callback_table[aidl_session_type];
- PortStatusCallbacks aidl_callbacks{};
- if (cbacks.control_result_cb_) {
- aidl_callbacks.control_result_cb_ =
- [&session_legacy_callback_table](uint16_t cookie, bool start_resp,
- const BluetoothAudioStatus& status) {
- if (session_legacy_callback_table.find(cookie) ==
- session_legacy_callback_table.end()) {
- LOG(ERROR) << __func__ << ": Unknown callback invoked!";
- return;
- }
- auto& cback = session_legacy_callback_table[cookie];
- cback->control_result_cb_(cookie, start_resp, to_hidl_status(status));
- };
- }
- if (cbacks.session_changed_cb_) {
- aidl_callbacks.session_changed_cb_ =
- [&session_legacy_callback_table](uint16_t cookie) {
- if (session_legacy_callback_table.find(cookie) ==
- session_legacy_callback_table.end()) {
- LOG(ERROR) << __func__ << ": Unknown callback invoked!";
- return;
- }
- auto& cback = session_legacy_callback_table[cookie];
- cback->session_changed_cb_(cookie);
- };
- };
- if (cbacks.audio_configuration_changed_cb_) {
- aidl_callbacks.audio_configuration_changed_cb_ =
- [&session_legacy_callback_table](uint16_t cookie) {
- if (session_legacy_callback_table.find(cookie) ==
- session_legacy_callback_table.end()) {
- LOG(ERROR) << __func__ << ": Unknown callback invoked!";
- return;
- }
- auto& cback = session_legacy_callback_table[cookie];
- cback->audio_configuration_changed_cb_(cookie);
- };
- };
- auto cookie = BluetoothAudioSessionControl::RegisterControlResultCback(
- aidl_session_type, aidl_callbacks);
- {
- std::lock_guard<std::mutex> guard(legacy_callback_lock);
- session_legacy_callback_table[cookie] =
- std::make_shared<PortStatusCallbacks_2_2>(cbacks);
- }
- return cookie;
-}
-
-void HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
- const SessionType_2_1& session_type, uint16_t cookie) {
- LOG(INFO) << __func__ << ": " << toString(session_type);
- auto aidl_session_type = from_session_type_2_1(session_type);
- BluetoothAudioSessionControl::UnregisterControlResultCback(aidl_session_type,
- cookie);
- auto& session_callback_table = legacy_callback_table[aidl_session_type];
- if (session_callback_table.find(cookie) != session_callback_table.end()) {
- std::lock_guard<std::mutex> guard(legacy_callback_lock);
- session_callback_table.erase(cookie);
- }
-}
-
-const AudioConfig_2_2 HidlToAidlMiddleware_2_2::GetAudioConfig(
- const SessionType_2_1& session_type) {
- return to_hidl_audio_config_2_2(BluetoothAudioSessionControl::GetAudioConfig(
- from_session_type_2_1(session_type)));
-}
-
-bool HidlToAidlMiddleware_2_2::StartStream(
- const SessionType_2_1& session_type) {
- return BluetoothAudioSessionControl::StartStream(
- from_session_type_2_1(session_type));
-}
-
-bool HidlToAidlMiddleware_2_2::SuspendStream(
- const SessionType_2_1& session_type) {
- return BluetoothAudioSessionControl::SuspendStream(
- from_session_type_2_1(session_type));
-}
-
-void HidlToAidlMiddleware_2_2::StopStream(const SessionType_2_1& session_type) {
- return BluetoothAudioSessionControl::StopStream(
- from_session_type_2_1(session_type));
-}
-
-void HidlToAidlMiddleware_2_2::UpdateTracksMetadata(
- const SessionType_2_1& session_type,
- const struct source_metadata* source_metadata) {
- return BluetoothAudioSessionControl::UpdateSourceMetadata(
- from_session_type_2_1(session_type), *source_metadata);
-}
-
-void HidlToAidlMiddleware_2_2::UpdateSinkMetadata(
- const SessionType_2_1& session_type,
- const struct sink_metadata* sink_metadata) {
- return BluetoothAudioSessionControl::UpdateSinkMetadata(
- from_session_type_2_1(session_type), *sink_metadata);
-}
-
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h
deleted file mode 100644
index f6c3e5c..0000000
--- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware_2_2.h
+++ /dev/null
@@ -1,69 +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.
- */
-
-#include <android/hardware/bluetooth/audio/2.2/types.h>
-
-#include "../session/BluetoothAudioSession.h"
-#include "../session/BluetoothAudioSession_2_2.h"
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace bluetooth {
-namespace audio {
-
-using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
-using PortStatusCallbacks_2_0 =
- ::android::bluetooth::audio::PortStatusCallbacks;
-using PortStatusCallbacks_2_2 =
- ::android::bluetooth::audio::PortStatusCallbacks_2_2;
-using AudioConfig_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration;
-
-class HidlToAidlMiddleware_2_2 {
- public:
- static bool IsSessionReady(const SessionType_2_1& session_type);
-
- static uint16_t RegisterControlResultCback(
- const SessionType_2_1& session_type,
- const PortStatusCallbacks_2_2& cbacks);
-
- static void UnregisterControlResultCback(const SessionType_2_1& session_type,
- uint16_t cookie);
-
- static const AudioConfig_2_2 GetAudioConfig(
- const SessionType_2_1& session_type);
-
- static bool StartStream(const SessionType_2_1& session_type);
-
- static bool SuspendStream(const SessionType_2_1& session_type);
-
- static void StopStream(const SessionType_2_1& session_type);
-
- static void UpdateTracksMetadata(
- const SessionType_2_1& session_type,
- const struct source_metadata* source_metadata);
-
- static void UpdateSinkMetadata(const SessionType_2_1& session_type,
- const struct sink_metadata* sink_metadata);
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
deleted file mode 100644
index c270ef0..0000000
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BluetoothAudioSession_2_2.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-class BluetoothAudioSessionControl_2_2 {
- using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
- using AudioConfiguration_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration;
-
- public:
- // The control API helps to check if session is ready or not
- // @return: true if the Bluetooth stack has started th specified session
- static bool IsSessionReady(const SessionType_2_1& session_type) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->IsSessionReady();
- }
- return false;
- }
-
- // The control API helps the bluetooth_audio module to register
- // PortStatusCallbacks
- // @return: cookie - the assigned number to this bluetooth_audio output
- static uint16_t RegisterControlResultCback(
- const SessionType_2_1& session_type, const PortStatusCallbacks& cbacks) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- PortStatusCallbacks_2_2 cb = {
- .control_result_cb_ = cbacks.control_result_cb_,
- .session_changed_cb_ = cbacks.session_changed_cb_,
- .audio_configuration_changed_cb_ = nullptr};
- return session_ptr->RegisterStatusCback(cb);
- }
- return kObserversCookieUndefined;
- }
-
- // The control API helps the bluetooth_audio module to register
- // PortStatusCallbacks_2_2
- // @return: cookie - the assigned number to this bluetooth_audio output
- static uint16_t RegisterControlResultCback(
- const SessionType_2_1& session_type,
- const PortStatusCallbacks_2_2& cbacks) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->RegisterStatusCback(cbacks);
- }
- return kObserversCookieUndefined;
- }
-
- // The control API helps the bluetooth_audio module to unregister
- // PortStatusCallbacks and PortStatusCallbacks_2_2
- // @param: cookie - indicates which bluetooth_audio output is
- static void UnregisterControlResultCback(const SessionType_2_1& session_type,
- uint16_t cookie) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->UnregisterStatusCback(cookie);
- }
- }
-
- // The control API for the bluetooth_audio module to get current
- // AudioConfiguration
- static const AudioConfiguration_2_2 GetAudioConfig(
- const SessionType_2_1& session_type) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->GetAudioConfig();
- } else if (session_type ==
- SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return BluetoothAudioSession_2_2::kInvalidOffloadAudioConfiguration;
- } else if (
- session_type ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- session_type ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return BluetoothAudioSession_2_2::kInvalidLeOffloadAudioConfiguration;
- } else {
- return BluetoothAudioSession_2_2::kInvalidSoftwareAudioConfiguration;
- }
- }
-
- // Those control APIs for the bluetooth_audio module to start / suspend / stop
- // stream, to check position, and to update metadata.
- static bool StartStream(const SessionType_2_1& session_type) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->StartStream();
- }
- return false;
- }
-
- static bool SuspendStream(const SessionType_2_1& session_type) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->SuspendStream();
- }
- return false;
- }
-
- static void StopStream(const SessionType_2_1& session_type) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->StopStream();
- }
- }
-
- static bool GetPresentationPosition(const SessionType_2_1& session_type,
- uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->GetAudioSession()->GetPresentationPosition(
- remote_delay_report_ns, total_bytes_readed, data_position);
- }
- return false;
- }
-
- static void UpdateTracksMetadata(
- const SessionType_2_1& session_type,
- const struct source_metadata* source_metadata) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->UpdateTracksMetadata(source_metadata);
- }
- }
-
- static void UpdateSinkMetadata(const SessionType_2_1& session_type,
- const struct sink_metadata* sink_metadata) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->UpdateSinkMetadata(sink_metadata);
- }
- }
-
- // The control API writes stream to FMQ
- static size_t OutWritePcmData(const SessionType_2_1& session_type,
- const void* buffer, size_t bytes) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->GetAudioSession()->OutWritePcmData(buffer, bytes);
- }
- return 0;
- }
-
- // The control API reads stream from FMQ
- static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer,
- size_t bytes) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes);
- }
- return 0;
- }
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
deleted file mode 100644
index 17e140e..0000000
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BluetoothAudioSession_2_2.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-class BluetoothAudioSessionReport_2_2 {
- public:
- // The API reports the Bluetooth stack has started the session, and will
- // inform registered bluetooth_audio outputs
- static void OnSessionStarted(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type,
- const sp<IBluetoothAudioPort> host_iface,
- const DataMQ::Descriptor* dataMQ,
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->OnSessionStarted(host_iface, dataMQ, audio_config);
- }
- }
-
- // The API reports the Bluetooth stack has ended the session, and will
- // inform registered bluetooth_audio outputs
- static void OnSessionEnded(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->OnSessionEnded();
- }
- }
- // The API reports the Bluetooth stack has replied the result of startStream
- // or suspendStream, and will inform registered bluetooth_audio outputs
- static void ReportControlStatus(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type,
- const bool& start_resp, const BluetoothAudioStatus& status) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->ReportControlStatus(start_resp, status);
- }
- }
- // The API reports the Bluetooth stack has replied the changed of the audio
- // configuration, and will inform registered bluetooth_audio outputs
- static void ReportAudioConfigChanged(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type,
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config) {
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->ReportAudioConfigChanged(audio_config);
- }
- }
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
deleted file mode 100644
index ceb0662..0000000
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderSession_2_2"
-
-#include "BluetoothAudioSession_2_2.h"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioPort.h>
-
-#include "../aidl_session/HidlToAidlMiddleware_2_0.h"
-#include "../aidl_session/HidlToAidlMiddleware_2_2.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_0;
-using ::aidl::android::hardware::bluetooth::audio::HidlToAidlMiddleware_2_2;
-using ::android::hardware::audio::common::V5_0::AudioContentType;
-using ::android::hardware::audio::common::V5_0::AudioSource;
-using ::android::hardware::audio::common::V5_0::AudioUsage;
-using ::android::hardware::audio::common::V5_0::PlaybackTrackMetadata;
-using ::android::hardware::audio::common::V5_0::RecordTrackMetadata;
-using ::android::hardware::audio::common::V5_0::SinkMetadata;
-using ::android::hardware::audio::common::V5_0::SourceMetadata;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
-using PcmParameters_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-
-using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
-using SessionType_2_0 =
- ::android::hardware::bluetooth::audio::V2_0::SessionType;
-
-using AudioConfiguration_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
-
-static constexpr PcmParameters_2_1 kInvalidPcmParameters = {
- .sampleRate = SampleRate_2_1::RATE_UNKNOWN,
- .channelMode = ChannelMode::UNKNOWN,
- .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
- .dataIntervalUs = 0,
-};
-
-static LeAudioConfiguration kInvalidLeAudioConfig = {
- .mode = LeAudioMode::UNKNOWN,
- .config = {},
-};
-
-::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- BluetoothAudioSession_2_2::invalidSoftwareAudioConfiguration = {};
-::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- BluetoothAudioSession_2_2::invalidOffloadAudioConfiguration = {};
-::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- BluetoothAudioSession_2_2::invalidLeOffloadAudioConfiguration = {};
-
-using IBluetoothAudioPort_2_2 =
- ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
-
-namespace {
-bool is_2_0_session_type(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type) {
- if (session_type == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH ||
- session_type == SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH) {
- return true;
- } else {
- return false;
- }
-}
-} // namespace
-
-BluetoothAudioSession_2_2::BluetoothAudioSession_2_2(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type)
- : audio_session(BluetoothAudioSessionInstance::GetSessionInstance(
- static_cast<SessionType_2_0>(session_type))),
- audio_session_2_1(
- BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type)) {
- if (is_2_0_session_type(session_type)) {
- session_type_2_1_ = (SessionType_2_1::UNKNOWN);
- } else {
- session_type_2_1_ = (session_type);
- }
- raw_session_type_ = session_type;
- invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters);
- invalidOffloadAudioConfiguration.codecConfig(
- audio_session->kInvalidCodecConfiguration);
- invalidLeOffloadAudioConfiguration.leAudioConfig(kInvalidLeAudioConfig);
-}
-
-bool BluetoothAudioSession_2_2::IsSessionReady() {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::IsSessionReady(raw_session_type_);
- if (session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return audio_session->IsSessionReady();
- }
-
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- return audio_session->stack_iface_ != nullptr;
-}
-
-std::shared_ptr<BluetoothAudioSession>
-BluetoothAudioSession_2_2::GetAudioSession() {
- return audio_session;
-}
-std::shared_ptr<BluetoothAudioSession_2_1>
-BluetoothAudioSession_2_2::GetAudioSession_2_1() {
- return audio_session_2_1;
-}
-
-void BluetoothAudioSession_2_2::UpdateTracksMetadata(
- const struct source_metadata* source_metadata) {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::UpdateTracksMetadata(raw_session_type_,
- source_metadata);
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has NO session";
- return;
- }
-
- ssize_t track_count = source_metadata->track_count;
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << ", " << track_count << " track(s)";
-
- if (session_type_2_1_ == SessionType_2_1::UNKNOWN) {
- audio_session->UpdateTracksMetadata(source_metadata);
- return;
- }
-
- struct playback_track_metadata* track = source_metadata->tracks;
- SourceMetadata sourceMetadata;
- PlaybackTrackMetadata* halMetadata;
-
- sourceMetadata.tracks.resize(track_count);
- halMetadata = sourceMetadata.tracks.data();
- while (track_count && track) {
- halMetadata->usage = static_cast<AudioUsage>(track->usage);
- halMetadata->contentType =
- static_cast<AudioContentType>(track->content_type);
- halMetadata->gain = track->gain;
- LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << ", usage=" << toString(halMetadata->usage)
- << ", content=" << toString(halMetadata->contentType)
- << ", gain=" << halMetadata->gain;
- --track_count;
- ++track;
- ++halMetadata;
- }
- auto hal_retval = audio_session->stack_iface_->updateMetadata(sourceMetadata);
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_2_1_) << " failed";
- }
-}
-
-void BluetoothAudioSession_2_2::UpdateSinkMetadata(
- const struct sink_metadata* sink_metadata) {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::UpdateSinkMetadata(raw_session_type_,
- sink_metadata);
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has NO session";
- return;
- }
-
- ssize_t track_count = sink_metadata->track_count;
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << ", " << track_count << " track(s)";
- if (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return;
- }
-
- struct record_track_metadata* track = sink_metadata->tracks;
- SinkMetadata sinkMetadata;
- RecordTrackMetadata* halMetadata;
-
- sinkMetadata.tracks.resize(track_count);
- halMetadata = sinkMetadata.tracks.data();
- while (track_count && track) {
- halMetadata->source = static_cast<AudioSource>(track->source);
- halMetadata->gain = track->gain;
- // halMetadata->destination leave unspecified
- LOG(INFO) << __func__
- << " - SessionType=" << toString(GetAudioSession()->session_type_)
- << ", source=" << track->source
- << ", dest_device=" << track->dest_device
- << ", gain=" << track->gain
- << ", dest_device_address=" << track->dest_device_address;
- --track_count;
- ++track;
- ++halMetadata;
- }
-
- /* This is called just for 2.2 sessions, so it's safe to do this casting*/
- IBluetoothAudioPort_2_2* stack_iface_2_2_ =
- static_cast<IBluetoothAudioPort_2_2*>(audio_session->stack_iface_.get());
- auto hal_retval = stack_iface_2_2_->updateSinkMetadata(sinkMetadata);
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_2_1_) << " failed";
- }
-}
-
-// The control function is for the bluetooth_audio module to get the current
-// AudioConfiguration
-const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
-BluetoothAudioSession_2_2::GetAudioConfig() {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::GetAudioConfig(raw_session_type_);
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (IsSessionReady()) {
- auto audio_config_discriminator = audio_config_2_2_.getDiscriminator();
- // If session is unknown it means it should be 2.0 type
- if (session_type_2_1_ != SessionType_2_1::UNKNOWN) {
- if ((audio_config_discriminator ==
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::pcmConfig &&
- audio_config_2_2_ != kInvalidSoftwareAudioConfiguration) ||
- (audio_config_discriminator ==
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::leAudioConfig &&
- audio_config_2_2_ != kInvalidLeOffloadAudioConfiguration))
- return audio_config_2_2_;
-
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
- const AudioConfiguration_2_1 fromConf =
- GetAudioSession_2_1()->GetAudioConfig();
- if (fromConf.getDiscriminator() ==
- AudioConfiguration_2_1::hidl_discriminator::pcmConfig) {
- toConf.pcmConfig(fromConf.pcmConfig());
- return toConf;
- }
- }
-
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
- const AudioConfiguration fromConf = GetAudioSession()->GetAudioConfig();
- // pcmConfig only differs between 2.0 and 2.1 in AudioConfiguration
- if (fromConf.getDiscriminator() ==
- AudioConfiguration::hidl_discriminator::codecConfig) {
- toConf.codecConfig(fromConf.codecConfig());
- } else {
- toConf.pcmConfig() = {
- .sampleRate = static_cast<
- ::android::hardware::bluetooth::audio::V2_1::SampleRate>(
- fromConf.pcmConfig().sampleRate),
- .channelMode = fromConf.pcmConfig().channelMode,
- .bitsPerSample = fromConf.pcmConfig().bitsPerSample,
- .dataIntervalUs = 0};
- }
- return toConf;
- } else if (session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return kInvalidLeOffloadAudioConfiguration;
- } else {
- return kInvalidSoftwareAudioConfiguration;
- }
-}
-
-// Those control functions are for the bluetooth_audio module to start, suspend,
-// stop stream, to check position, and to update metadata.
-bool BluetoothAudioSession_2_2::StartStream() {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::StartStream(raw_session_type_);
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has NO session";
- return false;
- }
- auto hal_retval = audio_session->stack_iface_->startStream();
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_2_1_) << " failed";
- return false;
- }
- return true;
-}
-
-bool BluetoothAudioSession_2_2::SuspendStream() {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::SuspendStream(raw_session_type_);
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has NO session";
- return false;
- }
- auto hal_retval = audio_session->stack_iface_->suspendStream();
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_2_1_) << " failed";
- return false;
- }
- return true;
-}
-
-void BluetoothAudioSession_2_2::StopStream() {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::StopStream(raw_session_type_);
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (!IsSessionReady()) {
- return;
- }
- auto hal_retval = audio_session->stack_iface_->stopStream();
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_2_1_) << " failed";
- }
-}
-
-bool BluetoothAudioSession_2_2::UpdateAudioConfig(
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config) {
- bool is_software_session =
- (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type_2_1_ ==
- SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
- session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
- session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
- bool is_offload_a2dp_session =
- (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- bool is_offload_le_audio_session =
- (session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
- auto audio_config_discriminator = audio_config.getDiscriminator();
- bool is_software_audio_config =
- (is_software_session &&
- audio_config_discriminator ==
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::pcmConfig);
- bool is_a2dp_offload_audio_config =
- (is_offload_a2dp_session &&
- audio_config_discriminator ==
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::codecConfig);
- bool is_le_audio_offload_audio_config =
- (is_offload_le_audio_session &&
- audio_config_discriminator ==
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::leAudioConfig);
- if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
- !is_le_audio_offload_audio_config) {
- return false;
- }
- audio_config_2_2_ = audio_config;
- return true;
-}
-
-// The report function is used to report that the Bluetooth stack has started
-// this session without any failure, and will invoke session_changed_cb_ to
-// notify those registered bluetooth_audio outputs
-void BluetoothAudioSession_2_2::OnSessionStarted(
- const sp<IBluetoothAudioPort> stack_iface, const DataMQ::Descriptor* dataMQ,
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config) {
- if (session_type_2_1_ == SessionType_2_1::UNKNOWN) {
- ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration config;
- if (audio_config.getDiscriminator() ==
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
- hidl_discriminator::codecConfig) {
- config.codecConfig(audio_config.codecConfig());
- } else {
- auto& tmpPcm = audio_config.pcmConfig();
- config.pcmConfig(
- ::android::hardware::bluetooth::audio::V2_0::PcmParameters{
- .sampleRate = static_cast<SampleRate>(tmpPcm.sampleRate),
- .channelMode = tmpPcm.channelMode,
- .bitsPerSample = tmpPcm.bitsPerSample
- /*dataIntervalUs is not passed to 2.0 */
- });
- }
-
- audio_session->OnSessionStarted(stack_iface, dataMQ, config);
- } else {
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (stack_iface == nullptr) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << ", IBluetoothAudioPort Invalid";
- } else if (!UpdateAudioConfig(audio_config)) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << ", AudioConfiguration=" << toString(audio_config)
- << " Invalid";
- } else if (!audio_session->UpdateDataPath(dataMQ)) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " DataMQ Invalid";
- audio_config_2_2_ =
- ((session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH)
- ? kInvalidLeOffloadAudioConfiguration
- : kInvalidSoftwareAudioConfiguration);
- } else {
- audio_session->stack_iface_ = stack_iface;
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << ", AudioConfiguration=" << toString(audio_config);
- ReportSessionStatus();
- };
- }
-}
-
-// The report function is used to report that the Bluetooth stack has ended the
-// session, and will invoke session_changed_cb_ to notify registered
-// bluetooth_audio outputs
-void BluetoothAudioSession_2_2::OnSessionEnded() {
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- bool toggled = IsSessionReady();
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_);
- if (session_type_2_1_ == SessionType_2_1::UNKNOWN) {
- audio_session->OnSessionEnded();
- return;
- }
-
- audio_config_2_2_ =
- ((session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
- session_type_2_1_ ==
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH)
- ? kInvalidLeOffloadAudioConfiguration
- : kInvalidSoftwareAudioConfiguration);
- audio_session->stack_iface_ = nullptr;
- audio_session->UpdateDataPath(nullptr);
- if (toggled) {
- ReportSessionStatus();
- }
-}
-
-// The control function helps the bluetooth_audio module to register
-// PortStatusCallbacks_2_2
-// @return: cookie - the assigned number to this bluetooth_audio output
-uint16_t BluetoothAudioSession_2_2::RegisterStatusCback(
- const PortStatusCallbacks_2_2& cbacks) {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::RegisterControlResultCback(
- raw_session_type_, cbacks);
- if (session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- PortStatusCallbacks cb = {
- .control_result_cb_ = cbacks.control_result_cb_,
- .session_changed_cb_ = cbacks.session_changed_cb_};
- return audio_session->RegisterStatusCback(cb);
- }
-
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- uint16_t cookie = ObserversCookieGetInitValue(session_type_2_1_);
- uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_2_1_);
-
- while (cookie < cookie_upper_bound) {
- if (observers_.find(cookie) == observers_.end()) {
- break;
- }
- ++cookie;
- }
- if (cookie >= cookie_upper_bound) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has " << observers_.size()
- << " observers already (No Resource)";
- return kObserversCookieUndefined;
- }
- std::shared_ptr<struct PortStatusCallbacks_2_2> cb =
- std::make_shared<struct PortStatusCallbacks_2_2>();
- *cb = cbacks;
- observers_[cookie] = cb;
- return cookie;
-}
-
-// The control function helps the bluetooth_audio module to unregister
-// PortStatusCallbacks_2_2
-// @param: cookie - indicates which bluetooth_audio output is
-void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) {
- if (HidlToAidlMiddleware_2_0::IsAidlAvailable())
- return HidlToAidlMiddleware_2_2::UnregisterControlResultCback(
- raw_session_type_, cookie);
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- audio_session->UnregisterStatusCback(cookie);
- return;
- }
- if (observers_.erase(cookie) != 1) {
- LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " no such provider=0x"
- << android::base::StringPrintf("%04x", cookie);
- }
-}
-
-// invoking the registered session_changed_cb_
-void BluetoothAudioSession_2_2::ReportSessionStatus() {
- // This is locked already by OnSessionStarted / OnSessionEnded
- if (session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- audio_session->ReportSessionStatus();
- return;
- }
- if (observers_.empty()) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has NO port state observer";
- return;
- }
- for (auto& observer : observers_) {
- uint16_t cookie = observer.first;
- std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " notify to bluetooth_audio=0x"
- << android::base::StringPrintf("%04x", cookie);
- cb->session_changed_cb_(cookie);
- }
-}
-
-// The report function is used to report that the Bluetooth stack has notified
-// the result of startStream or suspendStream, and will invoke
-// control_result_cb_ to notify registered bluetooth_audio outputs
-void BluetoothAudioSession_2_2::ReportControlStatus(
- bool start_resp, const BluetoothAudioStatus& status) {
- if (session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- audio_session->ReportControlStatus(start_resp, status);
- return;
- }
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- if (observers_.empty()) {
- LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has NO port state observer";
- return;
- }
- for (auto& observer : observers_) {
- uint16_t cookie = observer.first;
- std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
- LOG(INFO) << __func__ << " - status=" << toString(status)
- << " for SessionType=" << toString(session_type_2_1_)
- << ", bluetooth_audio=0x"
- << android::base::StringPrintf("%04x", cookie)
- << (start_resp ? " started" : " suspended");
- cb->control_result_cb_(cookie, start_resp, status);
- }
-}
-
-// The report function is used to report that the Bluetooth stack has notified
-// the result of startStream or suspendStream, and will invoke
-// control_result_cb_ to notify registered bluetooth_audio outputs
-void BluetoothAudioSession_2_2::ReportAudioConfigChanged(
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config) {
- if (session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_2_1_ !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return;
- }
- std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
- audio_config_2_2_ = audio_config;
- if (observers_.empty()) {
- LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
- << " has NO port state observer";
- return;
- }
- for (auto& observer : observers_) {
- uint16_t cookie = observer.first;
- std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
- LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_2_1_)
- << ", bluetooth_audio=0x"
- << android::base::StringPrintf("%04x", cookie);
- if (cb->audio_configuration_changed_cb_ != nullptr) {
- cb->audio_configuration_changed_cb_(cookie);
- }
- }
-}
-
-std::unique_ptr<BluetoothAudioSessionInstance_2_2>
- BluetoothAudioSessionInstance_2_2::instance_ptr =
- std::unique_ptr<BluetoothAudioSessionInstance_2_2>(
- new BluetoothAudioSessionInstance_2_2());
-
-// API to fetch the session of A2DP / Hearing Aid
-std::shared_ptr<BluetoothAudioSession_2_2>
-BluetoothAudioSessionInstance_2_2::GetSessionInstance(
- const SessionType_2_1& session_type) {
- std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
- if (!instance_ptr->sessions_map_.empty()) {
- auto entry = instance_ptr->sessions_map_.find(session_type);
- if (entry != instance_ptr->sessions_map_.end()) {
- return entry->second;
- }
- }
- std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
- std::make_shared<BluetoothAudioSession_2_2>(session_type);
- instance_ptr->sessions_map_[session_type] = session_ptr;
- return session_ptr;
-}
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
deleted file mode 100644
index e04ad80..0000000
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.2/types.h>
-
-#include <mutex>
-#include <unordered_map>
-
-#include "BluetoothAudioSession.h"
-#include "BluetoothAudioSession_2_1.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-inline uint16_t ObserversCookieGetInitValue(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type) {
- return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
-}
-inline uint16_t ObserversCookieGetUpperBound(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type) {
- return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
- kObserversCookieSize;
-}
-
-struct PortStatusCallbacks_2_2 {
- // control_result_cb_ - when the Bluetooth stack reports results of
- // streamStarted or streamSuspended, the BluetoothAudioProvider will invoke
- // this callback to report to the bluetooth_audio module.
- // @param: cookie - indicates which bluetooth_audio output should handle
- // @param: start_resp - this report is for startStream or not
- // @param: status - the result of startStream
- std::function<void(uint16_t cookie, bool start_resp,
- const BluetoothAudioStatus& status)>
- control_result_cb_;
- // session_changed_cb_ - when the Bluetooth stack start / end session, the
- // BluetoothAudioProvider will invoke this callback to notify to the
- // bluetooth_audio module.
- // @param: cookie - indicates which bluetooth_audio output should handle
- std::function<void(uint16_t cookie)> session_changed_cb_;
- // audio_configuration_changed_cb_ - when the Bluetooth stack change the audio
- // configuration, the BluetoothAudioProvider will invoke this callback to
- // notify to the bluetooth_audio module.
- // @param: cookie - indicates which bluetooth_audio output should handle
- std::function<void(uint16_t cookie)> audio_configuration_changed_cb_;
-};
-
-class BluetoothAudioSession_2_2 {
- private:
- std::shared_ptr<BluetoothAudioSession> audio_session;
- std::shared_ptr<BluetoothAudioSession_2_1> audio_session_2_1;
-
- ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_;
- ::android::hardware::bluetooth::audio::V2_1::SessionType raw_session_type_;
-
- // audio data configuration for both software and offloading
- ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- audio_config_2_2_;
-
- bool UpdateAudioConfig(
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config);
-
- static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- invalidSoftwareAudioConfiguration;
- static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- invalidOffloadAudioConfiguration;
- static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- invalidLeOffloadAudioConfiguration;
-
- // saving those registered bluetooth_audio's callbacks
- std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks_2_2>>
- observers_;
-
- // invoking the registered session_changed_cb_
- void ReportSessionStatus();
-
- public:
- BluetoothAudioSession_2_2(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type);
-
- // The function helps to check if this session is ready or not
- // @return: true if the Bluetooth stack has started the specified session
- bool IsSessionReady();
-
- std::shared_ptr<BluetoothAudioSession> GetAudioSession();
- std::shared_ptr<BluetoothAudioSession_2_1> GetAudioSession_2_1();
-
- // The report function is used to report that the Bluetooth stack has started
- // this session without any failure, and will invoke session_changed_cb_ to
- // notify those registered bluetooth_audio outputs
- void OnSessionStarted(
- const sp<IBluetoothAudioPort> stack_iface,
- const DataMQ::Descriptor* dataMQ,
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config);
-
- // The report function is used to report that the Bluetooth stack has ended
- // the session, and will invoke session_changed_cb_ to notify registered
- // bluetooth_audio outputs
- void OnSessionEnded();
-
- // Those control functions are for the bluetooth_audio module to start,
- // suspend, stop stream, to check position, and to update metadata.
- bool StartStream();
- bool SuspendStream();
- void StopStream();
-
- // The control function helps the bluetooth_audio module to register
- // PortStatusCallbacks_2_2
- // @return: cookie - the assigned number to this bluetooth_audio output
- uint16_t RegisterStatusCback(const PortStatusCallbacks_2_2& cbacks);
-
- // The control function helps the bluetooth_audio module to unregister
- // PortStatusCallbacks_2_2
- // @param: cookie - indicates which bluetooth_audio output is
- void UnregisterStatusCback(uint16_t cookie);
-
- // The report function is used to report that the Bluetooth stack has notified
- // the result of startStream or suspendStream, and will invoke
- // control_result_cb_ to notify registered bluetooth_audio outputs
- void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status);
-
- // The report function is used to report that the Bluetooth stack has notified
- // the audio configuration changed, and will invoke
- // audio_configuration_changed_cb_ to notify registered bluetooth_audio
- // outputs
- void ReportAudioConfigChanged(
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
- audio_config);
-
- // The control function is for the bluetooth_audio module to get the current
- // AudioConfiguration
- const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
- GetAudioConfig();
-
- void UpdateTracksMetadata(const struct source_metadata* source_metadata);
- void UpdateSinkMetadata(const struct sink_metadata* sink_metadata);
-
- static constexpr ::android::hardware::bluetooth::audio::V2_2::
- AudioConfiguration& kInvalidSoftwareAudioConfiguration =
- invalidSoftwareAudioConfiguration;
- static constexpr ::android::hardware::bluetooth::audio::V2_2::
- AudioConfiguration& kInvalidOffloadAudioConfiguration =
- invalidOffloadAudioConfiguration;
- static constexpr ::android::hardware::bluetooth::audio::V2_2::
- AudioConfiguration& kInvalidLeOffloadAudioConfiguration =
- invalidLeOffloadAudioConfiguration;
-};
-
-class BluetoothAudioSessionInstance_2_2 {
- public:
- // The API is to fetch the specified session of A2DP / Hearing Aid
- static std::shared_ptr<BluetoothAudioSession_2_2> GetSessionInstance(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type);
-
- private:
- static std::unique_ptr<BluetoothAudioSessionInstance_2_2> instance_ptr;
- std::mutex mutex_;
- std::unordered_map<::android::hardware::bluetooth::audio::V2_1::SessionType,
- std::shared_ptr<BluetoothAudioSession_2_2>>
- sessions_map_;
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
deleted file mode 100644
index decff70..0000000
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderSessionCodecsDB_2_2"
-
-#include "BluetoothAudioSupportedCodecsDB_2_2.h"
-
-#include <android-base/logging.h>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_1::CodecType;
-using ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
-using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
-using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
-using ::android::hardware::bluetooth::audio::V2_2::BroadcastCapability;
-using ::android::hardware::bluetooth::audio::V2_2::
- LeAudioCodecCapabilitiesSetting;
-using ::android::hardware::bluetooth::audio::V2_2::UnicastCapability;
-using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
-
-// Stores the list of offload supported capability
-std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
-
-static const UnicastCapability kInvalidUnicastCapability = {
- .codecType = CodecType::UNKNOWN};
-
-static const BroadcastCapability kInvalidBroadcastCapability = {
- .codecType = CodecType::UNKNOWN};
-
-// Default Supported Codecs
-// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
-static const Lc3Parameters kLc3Capability_16_1 = {
- .samplingFrequency = SampleRate::RATE_16000,
- .frameDuration = Lc3FrameDuration::DURATION_7500US,
- .octetsPerFrame = 30};
-
-// Default Supported Codecs
-// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
-static const Lc3Parameters kLc3Capability_16_2 = {
- .samplingFrequency = SampleRate::RATE_16000,
- .frameDuration = Lc3FrameDuration::DURATION_10000US,
- .octetsPerFrame = 40};
-
-// Default Supported Codecs
-// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
-static const Lc3Parameters kLc3Capability_48_4 = {
- .samplingFrequency = SampleRate::RATE_48000,
- .frameDuration = Lc3FrameDuration::DURATION_10000US,
- .octetsPerFrame = 120};
-
-static const std::vector<Lc3Parameters> supportedLc3CapabilityList = {
- kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
-
-static AudioLocation stereoAudio = static_cast<AudioLocation>(
- AudioLocation::FRONT_LEFT | AudioLocation::FRONT_RIGHT);
-static AudioLocation monoAudio = AudioLocation::UNKNOWN;
-
-// Stores the supported setting of audio location, connected device, and the
-// channel count for each device
-std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
- supportedDeviceSetting = {
- // Stereo, two connected device, one for L one for R
- std::make_tuple(stereoAudio, 2, 1),
- // Stereo, one connected device for both L and R
- std::make_tuple(stereoAudio, 1, 2),
- // Mono
- std::make_tuple(monoAudio, 1, 1)};
-
-bool IsOffloadLeAudioConfigurationValid(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type,
- const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration&) {
- if (session_type !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return false;
- }
-
- // TODO: perform checks on le_audio_codec_config once we know supported
- // parameters
-
- return true;
-}
-
-UnicastCapability composeUnicastLc3Capability(AudioLocation audioLocation,
- uint8_t deviceCnt,
- uint8_t channelCount,
- Lc3Parameters capability) {
- return UnicastCapability{.codecType = CodecType::LC3,
- .supportedChannel = audioLocation,
- .deviceCount = deviceCnt,
- .channelCountPerDevice = channelCount,
- .capabilities = capability};
-}
-
-std::vector<LeAudioCodecCapabilitiesSetting> GetLeAudioOffloadCodecCapabilities(
- const SessionType_2_1& session_type) {
- if (session_type !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type !=
- SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return std::vector<LeAudioCodecCapabilitiesSetting>(0);
- }
-
- if (kDefaultOffloadLeAudioCapabilities.empty()) {
- for (auto [audioLocation, deviceCnt, channelCount] :
- supportedDeviceSetting) {
- for (auto capability : supportedLc3CapabilityList) {
- UnicastCapability lc3Capability = composeUnicastLc3Capability(
- audioLocation, deviceCnt, channelCount, capability);
- UnicastCapability lc3MonoDecodeCapability =
- composeUnicastLc3Capability(monoAudio, 1, 1, capability);
-
- // Adds the capability for encode only
- kDefaultOffloadLeAudioCapabilities.push_back(
- {.unicastEncodeCapability = lc3Capability,
- .unicastDecodeCapability = kInvalidUnicastCapability,
- .broadcastCapability = kInvalidBroadcastCapability});
-
- // Adds the capability for decode only
- kDefaultOffloadLeAudioCapabilities.push_back(
- {.unicastEncodeCapability = kInvalidUnicastCapability,
- .unicastDecodeCapability = lc3Capability,
- .broadcastCapability = kInvalidBroadcastCapability});
-
- // Adds the capability for the case that encode and decode exist at the
- // same time
- kDefaultOffloadLeAudioCapabilities.push_back(
- {.unicastEncodeCapability = lc3Capability,
- .unicastDecodeCapability = lc3MonoDecodeCapability,
- .broadcastCapability = kInvalidBroadcastCapability});
- }
- }
- }
-
- return kDefaultOffloadLeAudioCapabilities;
-}
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
deleted file mode 100644
index 34bba5f..0000000
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.2/types.h>
-
-#include "BluetoothAudioSupportedCodecsDB.h"
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-bool IsOffloadLeAudioConfigurationValid(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type,
- const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration&
- le_audio_codec_config);
-
-std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesSetting>
-GetLeAudioOffloadCodecCapabilities(
- const ::android::hardware::bluetooth::audio::V2_1::SessionType&
- session_type);
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/broadcastradio/1.1/vts/functional/Android.bp b/broadcastradio/1.1/vts/functional/Android.bp
index f0dfe96..0fb4eb0 100644
--- a/broadcastradio/1.1/vts/functional/Android.bp
+++ b/broadcastradio/1.1/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalBroadcastradioV1_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalBroadcastradioV1_1TargetTest.cpp"],
srcs: ["VtsHalBroadcastradioV1_1TargetTest.cpp"],
static_libs: [
"android.hardware.broadcastradio@1.0",
diff --git a/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc b/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
index dd8c9c6..d58ba53 100644
--- a/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
+++ b/broadcastradio/2.0/default/android.hardware.broadcastradio@2.0-service.rc
@@ -1,5 +1,6 @@
service broadcastradio-hal2 /vendor/bin/hw/android.hardware.broadcastradio@2.0-service
- interface android.hardware.broadcastradio@2.0::IBroadcastRadio default
+ interface android.hardware.broadcastradio@2.0::IBroadcastRadio amfm
+ interface android.hardware.broadcastradio@2.0::IBroadcastRadio dab
class hal
user audioserver
group audio
diff --git a/broadcastradio/2.0/vts/functional/Android.bp b/broadcastradio/2.0/vts/functional/Android.bp
index e26486d..cb50c5e 100644
--- a/broadcastradio/2.0/vts/functional/Android.bp
+++ b/broadcastradio/2.0/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalBroadcastradioV2_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalBroadcastradioV2_0TargetTest.cpp"],
srcs: ["VtsHalBroadcastradioV2_0TargetTest.cpp"],
static_libs: [
"android.hardware.broadcastradio@2.0",
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 8886ee1..d2f61a5 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalCameraProviderV2_4TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp"],
srcs: ["VtsHalCameraProviderV2_4TargetTest.cpp"],
// TODO(b/64437680): Assume these are always available on the device.
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index b65b159..8c5a812 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -131,14 +131,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.bluetooth.audio</name>
- <version>2.0-2</version>
- <interface>
- <name>IBluetoothAudioProvidersFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.bluetooth.audio</name>
<interface>
diff --git a/drm/1.0/vts/functional/Android.bp b/drm/1.0/vts/functional/Android.bp
index 5ea6ad3..8ca6a65 100644
--- a/drm/1.0/vts/functional/Android.bp
+++ b/drm/1.0/vts/functional/Android.bp
@@ -44,6 +44,10 @@
local_include_dirs: [
"include",
],
+ tidy_timeout_srcs: [
+ "drm_hal_clearkey_test.cpp",
+ "drm_hal_vendor_test.cpp",
+ ],
srcs: [
"drm_hal_clearkey_test.cpp",
"drm_hal_vendor_test.cpp",
diff --git a/drm/1.1/vts/functional/Android.bp b/drm/1.1/vts/functional/Android.bp
index 656ec50..760b67e 100644
--- a/drm/1.1/vts/functional/Android.bp
+++ b/drm/1.1/vts/functional/Android.bp
@@ -32,6 +32,9 @@
local_include_dirs: [
"include",
],
+ tidy_timeout_srcs: [
+ "drm_hal_clearkey_test.cpp",
+ ],
srcs: [
"drm_hal_clearkey_test.cpp",
],
diff --git a/drm/1.2/vts/functional/Android.bp b/drm/1.2/vts/functional/Android.bp
index ca90ee9..dd22ebe 100644
--- a/drm/1.2/vts/functional/Android.bp
+++ b/drm/1.2/vts/functional/Android.bp
@@ -29,6 +29,9 @@
local_include_dirs: [
"include",
],
+ tidy_timeout_srcs: [
+ "drm_hal_test.cpp",
+ ],
srcs: [
"drm_hal_clearkey_module.cpp",
"drm_hal_common.cpp",
diff --git a/drm/aidl/OWNERS b/drm/aidl/OWNERS
new file mode 100644
index 0000000..fa8fd20
--- /dev/null
+++ b/drm/aidl/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 49079
+edwinwong@google.com
+kelzhan@google.com
+robertshih@google.com
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
index eb67d34..9ffd7d5 100644
--- a/graphics/composer/2.1/vts/functional/Android.bp
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalGraphicsComposerV2_1TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalGraphicsComposerV2_1TargetTest.cpp"],
srcs: ["VtsHalGraphicsComposerV2_1TargetTest.cpp"],
// TODO(b/64437680): Assume these libs are always available on the device.
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 36f3c00..e45696d 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -30,6 +30,10 @@
// Needed for librenderengine
"skia_deps",
],
+ tidy_timeout_srcs: [
+ "VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
+ "VtsHalGraphicsComposerV2_2TargetTest.cpp",
+ ],
srcs: [
"VtsHalGraphicsComposerV2_2ReadbackTest.cpp",
"VtsHalGraphicsComposerV2_2TargetTest.cpp",
diff --git a/graphics/composer/2.3/vts/functional/Android.bp b/graphics/composer/2.3/vts/functional/Android.bp
index d27a151..70384ac 100644
--- a/graphics/composer/2.3/vts/functional/Android.bp
+++ b/graphics/composer/2.3/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalGraphicsComposerV2_3TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalGraphicsComposerV2_3TargetTest.cpp"],
srcs: ["VtsHalGraphicsComposerV2_3TargetTest.cpp"],
// TODO(b/64437680): Assume these libs are always available on the device.
diff --git a/graphics/composer/2.4/vts/functional/Android.bp b/graphics/composer/2.4/vts/functional/Android.bp
index 6089e2d..22ae7c4 100644
--- a/graphics/composer/2.4/vts/functional/Android.bp
+++ b/graphics/composer/2.4/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalGraphicsComposerV2_4TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalGraphicsComposerV2_4TargetTest.cpp"],
srcs: ["VtsHalGraphicsComposerV2_4TargetTest.cpp"],
// TODO(b/64437680): Assume these libs are always available on the device.
diff --git a/health/2.0/vts/functional/Android.bp b/health/2.0/vts/functional/Android.bp
index 0fcac19..597fb50 100644
--- a/health/2.0/vts/functional/Android.bp
+++ b/health/2.0/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalHealthV2_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalHealthV2_0TargetTest.cpp"],
srcs: ["VtsHalHealthV2_0TargetTest.cpp"],
static_libs: [
"libgflags",
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index e1d1982..d41d01a 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -130,12 +130,7 @@
ndk::ScopedAStatus Health::getHealthInfo(HealthInfo* out) {
battery_monitor_.updateValues();
- // TODO(b/177269435): BatteryMonitor should store AIDL HealthInfo instead.
- auto health_info_2_1 = battery_monitor_.getHealthInfo_2_1();
- if (!::android::h2a::translate(health_info_2_1, out)) {
- return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
- IHealth::STATUS_UNKNOWN, "Cannot translate HIDL HealthInfo to AIDL");
- }
+ *out = battery_monitor_.getHealthInfo();
// Fill in storage infos; these aren't retrieved by BatteryMonitor.
if (auto res = getStorageInfo(&out->storageInfos); !res.isOk()) {
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index d315c60..f9da79f 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -29,6 +29,9 @@
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
+ tidy_timeout_srcs: [
+ "VtsHalHealthTargetTest.cpp",
+ ],
srcs: [
"VtsHalHealthTargetTest.cpp",
],
diff --git a/health/utils/libhealthloop/HealthLoop.cpp b/health/utils/libhealthloop/HealthLoop.cpp
index 3f4b5bc..4190769 100644
--- a/health/utils/libhealthloop/HealthLoop.cpp
+++ b/health/utils/libhealthloop/HealthLoop.cpp
@@ -40,8 +40,6 @@
using namespace android;
using namespace std::chrono_literals;
-#define POWER_SUPPLY_SUBSYSTEM "power_supply"
-
namespace android {
namespace hardware {
namespace health {
@@ -143,7 +141,7 @@
cp = msg;
while (*cp) {
- if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) {
+ if (!strcmp(cp, "SUBSYSTEM=power_supply")) {
ScheduleBatteryUpdate();
break;
}
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
index 42e4ea7..3a1415f 100644
--- a/health/utils/libhealthshim/Android.bp
+++ b/health/utils/libhealthshim/Android.bp
@@ -70,6 +70,9 @@
"libhealthshim",
"libgmock",
],
+ tidy_timeout_srcs: [
+ "test.cpp",
+ ],
srcs: [
"test.cpp",
],
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index db1a945..4e3d1f7 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -86,6 +86,9 @@
cc_test {
name: "cppbor_test",
+ tidy_timeout_srcs: [
+ "tests/cppbor_test.cpp",
+ ],
srcs: [
"tests/cppbor_test.cpp",
],
@@ -101,6 +104,9 @@
cc_test_host {
name: "cppbor_host_test",
+ tidy_timeout_srcs: [
+ "tests/cppbor_test.cpp",
+ ],
srcs: [
"tests/cppbor_test.cpp",
],
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
index 82746d6..952b69a 100644
--- a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -407,6 +407,10 @@
// may be smaller than |maxChunkSize|.
vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize);
+// Extract the issuer subject name from the leaf cert in the given chain,
+// returning it as DER-encoded bytes.
+optional<vector<uint8_t>> extractDerSubjectFromCertificate(const vector<uint8_t>& certificate);
+
} // namespace support
} // namespace identity
} // namespace hardware
diff --git a/identity/support/include/cppbor/cppbor.h b/identity/support/include/cppbor/cppbor.h
index a755db1..af5d82e 100644
--- a/identity/support/include/cppbor/cppbor.h
+++ b/identity/support/include/cppbor/cppbor.h
@@ -274,7 +274,7 @@
virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Nint>(mValue); }
private:
- uint64_t addlInfo() const { return -1ll - mValue; }
+ uint64_t addlInfo() const { return -1LL - mValue; }
int64_t mValue;
};
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 36ecdb0..4c2f186 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -209,38 +209,6 @@
return keyPair;
}
-// Extract the issuer subject name from the leaf cert in the given chain,
-// returning it as DER-encoded bytes.
-optional<vector<uint8_t>> extractDerSubjectFromCertificate(const vector<uint8_t>& certificate) {
- const uint8_t* input = certificate.data();
- X509_Ptr cert(d2i_X509(/*cert=*/nullptr, &input, certificate.size()));
- if (!cert) {
- LOG(ERROR) << "Failed to parse certificate";
- return std::nullopt;
- }
-
- X509_NAME* subject = X509_get_subject_name(cert.get());
- if (!subject) {
- LOG(ERROR) << "Failed to retrieve subject name";
- return std::nullopt;
- }
-
- int encodedSubjectLength = i2d_X509_NAME(subject, /*out=*/nullptr);
- if (encodedSubjectLength < 0) {
- LOG(ERROR) << "Error obtaining encoded subject name length";
- return std::nullopt;
- }
-
- vector<uint8_t> encodedSubject(encodedSubjectLength);
- uint8_t* out = encodedSubject.data();
- if (encodedSubjectLength != i2d_X509_NAME(subject, &out)) {
- LOG(ERROR) << "Error encoding subject name";
- return std::nullopt;
- }
-
- return encodedSubject;
-}
-
// Generates the attestation certificate with the parameters passed in. Note
// that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
// milli seconds since epoch. We are setting them to milliseconds due to
@@ -900,7 +868,7 @@
}
optional<vector<uint8_t>> derIssuerSubject =
- extractDerSubjectFromCertificate(attestationKeyCert);
+ support::extractDerSubjectFromCertificate(attestationKeyCert);
if (!derIssuerSubject) {
LOG(ERROR) << "Error error extracting issuer name from the given certificate chain";
return std::nullopt;
@@ -2325,6 +2293,36 @@
return testHardwareBoundKey;
}
+optional<vector<uint8_t>> extractDerSubjectFromCertificate(const vector<uint8_t>& certificate) {
+ const uint8_t* input = certificate.data();
+ X509_Ptr cert(d2i_X509(/*cert=*/nullptr, &input, certificate.size()));
+ if (!cert) {
+ LOG(ERROR) << "Failed to parse certificate";
+ return std::nullopt;
+ }
+
+ X509_NAME* subject = X509_get_subject_name(cert.get());
+ if (!subject) {
+ LOG(ERROR) << "Failed to retrieve subject name";
+ return std::nullopt;
+ }
+
+ int encodedSubjectLength = i2d_X509_NAME(subject, /*out=*/nullptr);
+ if (encodedSubjectLength < 0) {
+ LOG(ERROR) << "Error obtaining encoded subject name length";
+ return std::nullopt;
+ }
+
+ vector<uint8_t> encodedSubject(encodedSubjectLength);
+ uint8_t* out = encodedSubject.data();
+ if (encodedSubjectLength != i2d_X509_NAME(subject, &out)) {
+ LOG(ERROR) << "Error encoding subject name";
+ return std::nullopt;
+ }
+
+ return encodedSubject;
+}
+
} // namespace support
} // namespace identity
} // namespace hardware
diff --git a/keymaster/3.0/vts/functional/Android.bp b/keymaster/3.0/vts/functional/Android.bp
index 39bec3f..fde32a7 100644
--- a/keymaster/3.0/vts/functional/Android.bp
+++ b/keymaster/3.0/vts/functional/Android.bp
@@ -26,6 +26,9 @@
cc_test {
name: "VtsHalKeymasterV3_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "keymaster_hidl_hal_test.cpp",
+ ],
srcs: [
"authorization_set.cpp",
"attestation_record.cpp",
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index 8e5a0ff..f9a02ba 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -26,6 +26,9 @@
cc_test {
name: "VtsHalKeymasterV4_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "keymaster_hidl_hal_test.cpp",
+ ],
srcs: [
"HmacKeySharingTest.cpp",
"VerificationTokenTest.cpp",
@@ -50,6 +53,9 @@
cc_test_library {
name: "libkeymaster4vtstest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "KeymasterHidlTest.cpp",
+ ],
srcs: [
"KeymasterHidlTest.cpp",
],
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
index eddf83f..6caac63 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -203,9 +203,8 @@
}
int64_t delayUs = finishBy - android::ALooper::GetNowUs();
if (delayUs < 0) return toStatus(android::TIMED_OUT);
- (timeoutUs < 0)
- ? msgCondition.wait(msgLock)
- : msgCondition.waitRelative(msgLock, delayUs * 1000ll);
+ (timeoutUs < 0) ? msgCondition.wait(msgLock)
+ : msgCondition.waitRelative(msgLock, delayUs * 1000LL);
}
}
diff --git a/media/omx/1.0/vts/functional/component/Android.bp b/media/omx/1.0/vts/functional/component/Android.bp
index 9d4d092..7b8ec9d 100644
--- a/media/omx/1.0/vts/functional/component/Android.bp
+++ b/media/omx/1.0/vts/functional/component/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalMediaOmxV1_0TargetComponentTest",
defaults: ["VtsHalMediaOmxV1_0Defaults"],
+ tidy_timeout_srcs: ["VtsHalMediaOmxV1_0TargetComponentTest.cpp"],
srcs: ["VtsHalMediaOmxV1_0TargetComponentTest.cpp"],
test_suites: [
"vts",
diff --git a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
index 8699de3..d9a6363 100644
--- a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
+++ b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
@@ -20,7 +20,9 @@
#endif
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android-base/strings.h>
+#include <android/api-level.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
@@ -371,6 +373,31 @@
}
}
+static int getFirstApiLevel() {
+ return android::base::GetIntProperty("ro.product.first_api_level", __ANDROID_API_T__);
+}
+
+// list components and roles.
+TEST_P(StoreHidlTest, OmxCodecAllowedTest) {
+ hidl_vec<IOmx::ComponentInfo> componentInfos = getComponentInfoList(omx);
+ for (IOmx::ComponentInfo info : componentInfos) {
+ for (std::string role : info.mRoles) {
+ if (role.find("video_decoder") != std::string::npos ||
+ role.find("video_encoder") != std::string::npos) {
+ ASSERT_LT(getFirstApiLevel(), __ANDROID_API_S__)
+ << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
+ << " not allowed for devices launching with Android S and above";
+ }
+ if (role.find("audio_decoder") != std::string::npos ||
+ role.find("audio_encoder") != std::string::npos) {
+ ASSERT_LT(getFirstApiLevel(), __ANDROID_API_T__)
+ << " Component: " << info.mName.c_str() << " Role: " << role.c_str()
+ << " not allowed for devices launching with Android T and above";
+ }
+ }
+ }
+}
+
// list components and roles.
TEST_P(StoreHidlTest, ListNodes) {
description("enumerate component and roles");
diff --git a/neuralnetworks/1.2/utils/Android.bp b/neuralnetworks/1.2/utils/Android.bp
index 4c5f065..e7d514f 100644
--- a/neuralnetworks/1.2/utils/Android.bp
+++ b/neuralnetworks/1.2/utils/Android.bp
@@ -45,21 +45,15 @@
cflags: ["-DNN_DEBUGGABLE"],
},
},
- target: {
- host: {
- cflags: [
- "-D__INTRODUCED_IN(x)=",
- "-D__assert(a,b,c)=",
- // We want all the APIs to be available on the host.
- "-D__ANDROID_API__=10000",
- ],
- },
- },
}
cc_test {
name: "neuralnetworks_utils_hal_1_2_test",
host_supported: true,
+ tidy_timeout_srcs: [
+ "test/DeviceTest.cpp",
+ "test/PreparedModelTest.cpp",
+ ],
srcs: ["test/*.cpp"],
static_libs: [
"android.hardware.neuralnetworks@1.0",
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 52d51e2..2177924 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -44,6 +44,9 @@
cc_test {
name: "VtsHalNeuralnetworksV1_2TargetTest",
defaults: ["neuralnetworks_vts_functional_defaults"],
+ tidy_timeout_srcs: [
+ "CompilationCachingTests.cpp",
+ ],
srcs: [
"BasicTests.cpp",
"CompilationCachingTests.cpp",
diff --git a/neuralnetworks/1.3/utils/Android.bp b/neuralnetworks/1.3/utils/Android.bp
index c512dda..05413e6 100644
--- a/neuralnetworks/1.3/utils/Android.bp
+++ b/neuralnetworks/1.3/utils/Android.bp
@@ -42,21 +42,15 @@
"neuralnetworks_utils_hal_1_1",
"neuralnetworks_utils_hal_1_2",
],
- target: {
- host: {
- cflags: [
- "-D__INTRODUCED_IN(x)=",
- "-D__assert(a,b,c)=",
- // We want all the APIs to be available on the host.
- "-D__ANDROID_API__=10000",
- ],
- },
- },
}
cc_test {
name: "neuralnetworks_utils_hal_1_3_test",
host_supported: true,
+ tidy_timeout_srcs: [
+ "test/DeviceTest.cpp",
+ "test/PreparedModelTest.cpp",
+ ],
srcs: ["test/*.cpp"],
static_libs: [
"android.hardware.neuralnetworks@1.0",
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
index 8951760..9fa0f0a 100644
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ b/neuralnetworks/1.3/vts/functional/Android.bp
@@ -45,6 +45,10 @@
cc_test {
name: "VtsHalNeuralnetworksV1_3TargetTest",
defaults: ["neuralnetworks_vts_functional_defaults"],
+ tidy_timeout_srcs: [
+ "CompilationCachingTests.cpp",
+ "MemoryDomainTests.cpp",
+ ],
srcs: [
"BasicTests.cpp",
"CompilationCachingTests.cpp",
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index 41eae85..2b7b787 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -105,6 +105,10 @@
"neuralnetworks_use_latest_utils_hal_aidl",
"neuralnetworks_utils_defaults",
],
+ tidy_timeout_srcs: [
+ "test/DeviceTest.cpp",
+ "test/PreparedModelTest.cpp",
+ ],
srcs: [
"test/*.cpp",
],
@@ -123,14 +127,6 @@
android: {
shared_libs: ["libnativewindow"],
},
- host: {
- cflags: [
- "-D__INTRODUCED_IN(x)=",
- "-D__assert(a,b,c)=",
- // We want all the APIs to be available on the host.
- "-D__ANDROID_API__=10000",
- ],
- },
},
cflags: [
/* GMOCK defines functions for printing all MOCK_DEVICE arguments and
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
index cb6ff4b..f229165b 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Service.h
@@ -25,7 +25,8 @@
namespace aidl::android::hardware::neuralnetworks::utils {
-::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(const std::string& name);
+::android::nn::GeneralResult<::android::nn::SharedDevice> getDevice(
+ const std::string& name, ::android::nn::Version::Level maxFeatureLevelAllowed);
} // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
index beca38b..7ed5437 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
@@ -26,6 +26,8 @@
#include <nnapi/Types.h>
#include <nnapi/Validation.h>
+#include <type_traits>
+
namespace aidl::android::hardware::neuralnetworks::utils {
constexpr auto kDefaultPriority = Priority::MEDIUM;
@@ -80,6 +82,11 @@
return convert(NN_TRY(nn::convert(nonCanonicalObject)));
}
+template <typename Type>
+constexpr std::underlying_type_t<Type> underlyingType(Type value) {
+ return static_cast<std::underlying_type_t<Type>>(value);
+}
+
nn::GeneralResult<Memory> clone(const Memory& memory);
nn::GeneralResult<Request> clone(const Request& request);
nn::GeneralResult<RequestMemoryPool> clone(const RequestMemoryPool& requestPool);
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index 83fda10..081e3d7 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -57,10 +57,6 @@
while (UNLIKELY(value > std::numeric_limits<int32_t>::max())) return NN_ERROR()
namespace {
-template <typename Type>
-constexpr std::underlying_type_t<Type> underlyingType(Type value) {
- return static_cast<std::underlying_type_t<Type>>(value);
-}
constexpr int64_t kNoTiming = -1;
@@ -70,6 +66,7 @@
namespace {
using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::neuralnetworks::utils::underlyingType;
template <typename Input>
using UnvalidatedConvertOutput =
@@ -404,7 +401,7 @@
#endif // __ANDROID__
}
}
- return NN_ERROR() << "Unrecognized Memory::Tag: " << memory.getTag();
+ return NN_ERROR() << "Unrecognized Memory::Tag: " << underlyingType(memory.getTag());
}
GeneralResult<Timing> unvalidatedConvert(const aidl_hal::Timing& timing) {
diff --git a/neuralnetworks/aidl/utils/src/Service.cpp b/neuralnetworks/aidl/utils/src/Service.cpp
index e48593c..24fbb53 100644
--- a/neuralnetworks/aidl/utils/src/Service.cpp
+++ b/neuralnetworks/aidl/utils/src/Service.cpp
@@ -55,11 +55,12 @@
} // namespace
-nn::GeneralResult<nn::SharedDevice> getDevice(const std::string& instanceName) {
+nn::GeneralResult<nn::SharedDevice> getDevice(
+ const std::string& instanceName, ::android::nn::Version::Level maxFeatureLevelAllowed) {
auto fullName = std::string(IDevice::descriptor) + "/" + instanceName;
hal::utils::ResilientDevice::Factory makeDevice =
- [instanceName,
- name = std::move(fullName)](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
+ [instanceName, name = std::move(fullName),
+ maxFeatureLevelAllowed](bool blocking) -> nn::GeneralResult<nn::SharedDevice> {
std::add_pointer_t<AIBinder*(const char*)> getService;
if (blocking) {
if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
@@ -79,7 +80,8 @@
<< " returned nullptr";
}
ABinderProcess_startThreadPool();
- const auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get()));
+ auto featureLevel = NN_TRY(getAidlServiceFeatureLevel(service.get()));
+ featureLevel.level = std::min(featureLevel.level, maxFeatureLevelAllowed);
return Device::create(instanceName, std::move(service), featureLevel);
};
diff --git a/neuralnetworks/aidl/utils/src/Utils.cpp b/neuralnetworks/aidl/utils/src/Utils.cpp
index 03407be..76a0b07 100644
--- a/neuralnetworks/aidl/utils/src/Utils.cpp
+++ b/neuralnetworks/aidl/utils/src/Utils.cpp
@@ -88,7 +88,7 @@
return Memory::make<Memory::Tag::hardwareBuffer>(std::move(handle));
}
}
- return (NN_ERROR() << "Unrecognized Memory::Tag: " << memory.getTag())
+ return (NN_ERROR() << "Unrecognized Memory::Tag: " << underlyingType(memory.getTag()))
.
operator nn::GeneralResult<Memory>();
}
@@ -103,7 +103,7 @@
}
// Using explicit type conversion because std::variant inside the RequestMemoryPool confuses the
// compiler.
- return (NN_ERROR() << "Unrecognized request pool tag: " << requestPool.getTag())
+ return (NN_ERROR() << "Unrecognized request pool tag: " << underlyingType(requestPool.getTag()))
.
operator nn::GeneralResult<RequestMemoryPool>();
}
diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp
index 356cdb0..04b4a45 100644
--- a/neuralnetworks/aidl/vts/functional/Android.bp
+++ b/neuralnetworks/aidl/vts/functional/Android.bp
@@ -31,6 +31,10 @@
"use_libaidlvintf_gtest_helper_static",
],
host_supported: true,
+ tidy_timeout_srcs: [
+ "CompilationCachingTests.cpp",
+ "MemoryDomainTests.cpp",
+ ],
srcs: [
"BasicTests.cpp",
"Callbacks.cpp",
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
index 4c0b328..80ed41d 100644
--- a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
@@ -46,9 +46,6 @@
/**
* Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object.
*
- * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
- * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
- *
* @param device NNAPI canonical IDevice interface object to be adapted.
* @param executor Type-erased executor to handle executing tasks asynchronously.
* @return AIDL NN HAL IDevice interface object.
@@ -58,9 +55,6 @@
/**
* Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object.
*
- * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
- * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
- *
* This function uses a default executor, which will execute tasks from a detached thread.
*
* @param device NNAPI canonical IDevice interface object to be adapted.
diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
index 6fba4ab..3bd93e0 100644
--- a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
+++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
@@ -46,9 +46,6 @@
/**
* Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
*
- * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
- * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
- *
* @param device NNAPI canonical IDevice interface object to be adapted.
* @param executor Type-erased executor to handle executing tasks asynchronously.
* @return HIDL NN HAL IDevice interface object.
@@ -58,9 +55,6 @@
/**
* Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
*
- * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
- * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
- *
* This function uses a default executor, which will execute tasks from a detached thread.
*
* @param device NNAPI canonical IDevice interface object to be adapted.
diff --git a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
index 9482b0d..01cd4bc 100644
--- a/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
+++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
@@ -39,7 +39,7 @@
// Class that adapts nn::IPreparedModel to V1_3::IPreparedModel.
class PreparedModel final : public V1_3::IPreparedModel {
public:
- PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor);
+ explicit PreparedModel(nn::SharedPreparedModel preparedModel);
Return<V1_0::ErrorStatus> execute(const V1_0::Request& request,
const sp<V1_0::IExecutionCallback>& callback) override;
@@ -70,7 +70,6 @@
private:
const nn::SharedPreparedModel kPreparedModel;
- const Executor kExecutor;
};
} // namespace android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/hidl/src/Device.cpp b/neuralnetworks/utils/adapter/hidl/src/Device.cpp
index 0f44638..305a1b4 100644
--- a/neuralnetworks/utils/adapter/hidl/src/Device.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/Device.cpp
@@ -62,11 +62,11 @@
using PrepareModelResult = nn::GeneralResult<nn::SharedPreparedModel>;
-sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor) {
+sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel) {
if (preparedModel == nullptr) {
return nullptr;
}
- return sp<PreparedModel>::make(std::move(preparedModel), std::move(executor));
+ return sp<PreparedModel>::make(std::move(preparedModel));
}
void notify(V1_0::IPreparedModelCallback* callback, nn::ErrorStatus status,
@@ -105,14 +105,14 @@
}
template <typename CallbackType>
-void notify(CallbackType* callback, PrepareModelResult result, Executor executor) {
+void notify(CallbackType* callback, PrepareModelResult result) {
if (!result.has_value()) {
const auto [message, status] = std::move(result).error();
LOG(ERROR) << message;
notify(callback, status, nullptr);
} else {
auto preparedModel = std::move(result).value();
- auto hidlPreparedModel = adaptPreparedModel(std::move(preparedModel), std::move(executor));
+ auto hidlPreparedModel = adaptPreparedModel(std::move(preparedModel));
notify(callback, nn::ErrorStatus::NONE, std::move(hidlPreparedModel));
}
}
@@ -133,10 +133,10 @@
auto nnModel = NN_TRY(convertInput(model));
- Task task = [device, nnModel = std::move(nnModel), executor, callback] {
+ Task task = [device, nnModel = std::move(nnModel), callback] {
auto result = device->prepareModel(nnModel, nn::ExecutionPreference::DEFAULT,
nn::Priority::DEFAULT, {}, {}, {}, {}, {}, {});
- notify(callback.get(), std::move(result), executor);
+ notify(callback.get(), std::move(result));
};
executor(std::move(task), {});
@@ -154,10 +154,10 @@
auto nnModel = NN_TRY(convertInput(model));
const auto nnPreference = NN_TRY(convertInput(preference));
- Task task = [device, nnModel = std::move(nnModel), nnPreference, executor, callback] {
+ Task task = [device, nnModel = std::move(nnModel), nnPreference, callback] {
auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, {}, {},
{}, {}, {});
- notify(callback.get(), std::move(result), executor);
+ notify(callback.get(), std::move(result));
};
executor(std::move(task), {});
@@ -183,10 +183,10 @@
Task task = [device, nnModel = std::move(nnModel), nnPreference,
nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
- nnToken, executor, callback] {
+ nnToken, callback] {
auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {},
nnModelCache, nnDataCache, nnToken, {}, {});
- notify(callback.get(), std::move(result), executor);
+ notify(callback.get(), std::move(result));
};
executor(std::move(task), {});
@@ -213,10 +213,10 @@
Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline,
nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
- nnToken, executor, callback] {
+ nnToken, callback] {
auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline,
nnModelCache, nnDataCache, nnToken, {}, {});
- notify(callback.get(), std::move(result), executor);
+ notify(callback.get(), std::move(result));
};
executor(std::move(task), nnDeadline);
@@ -238,9 +238,9 @@
const auto nnToken = nn::CacheToken(token);
Task task = [device, nnModelCache = std::move(nnModelCache),
- nnDataCache = std::move(nnDataCache), nnToken, executor, callback] {
+ nnDataCache = std::move(nnDataCache), nnToken, callback] {
auto result = device->prepareModelFromCache({}, nnModelCache, nnDataCache, nnToken);
- notify(callback.get(), std::move(result), executor);
+ notify(callback.get(), std::move(result));
};
executor(std::move(task), {});
@@ -262,9 +262,9 @@
const auto nnToken = nn::CacheToken(token);
auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache),
- nnDataCache = std::move(nnDataCache), nnToken, executor, callback] {
+ nnDataCache = std::move(nnDataCache), nnToken, callback] {
auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken);
- notify(callback.get(), std::move(result), executor);
+ notify(callback.get(), std::move(result));
};
executor(std::move(task), nnDeadline);
diff --git a/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
index c6055a6..3570a74 100644
--- a/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
@@ -55,15 +55,6 @@
return result;
}
-nn::GeneralResult<nn::Version> validateRequestForModel(const nn::Request& request,
- const nn::Model& model) {
- nn::GeneralResult<nn::Version> version = nn::validateRequestForModel(request, model);
- if (!version.ok()) {
- version.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
- }
- return version;
-}
-
class FencedExecutionCallback final : public V1_3::IFencedExecutionCallback {
public:
explicit FencedExecutionCallback(const nn::ExecuteFencedInfoCallback& callback)
@@ -144,58 +135,48 @@
}
nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel,
- const Executor& executor, const V1_0::Request& request,
+ const V1_0::Request& request,
const sp<V1_0::IExecutionCallback>& callback) {
if (callback.get() == nullptr) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback";
}
- auto nnRequest = NN_TRY(convertInput(request));
+ const auto nnRequest = NN_TRY(convertInput(request));
- const std::any resource = preparedModel->getUnderlyingResource();
- if (const auto* model = std::any_cast<const nn::Model*>(&resource)) {
- CHECK(*model != nullptr);
- NN_TRY(adapter::validateRequestForModel(nnRequest, **model));
+ auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {}, {}, {});
+
+ if (!result.ok() && result.error().code == nn::ErrorStatus::INVALID_ARGUMENT) {
+ const auto& [message, code, outputShapes] = result.error();
+ return nn::error(code) << message;
}
- Task task = [preparedModel, nnRequest = std::move(nnRequest), callback] {
- auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {}, {}, {});
- notify(callback.get(), std::move(result));
- };
- executor(std::move(task), {});
-
+ notify(callback.get(), std::move(result));
return {};
}
nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel,
- const Executor& executor, const V1_0::Request& request,
- V1_2::MeasureTiming measure,
+ const V1_0::Request& request, V1_2::MeasureTiming measure,
const sp<V1_2::IExecutionCallback>& callback) {
if (callback.get() == nullptr) {
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback";
}
- auto nnRequest = NN_TRY(convertInput(request));
+ const auto nnRequest = NN_TRY(convertInput(request));
const auto nnMeasure = NN_TRY(convertInput(measure));
- const std::any resource = preparedModel->getUnderlyingResource();
- if (const auto* model = std::any_cast<const nn::Model*>(&resource)) {
- CHECK(*model != nullptr);
- NN_TRY(adapter::validateRequestForModel(nnRequest, **model));
+ auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {}, {}, {});
+
+ if (!result.ok() && result.error().code == nn::ErrorStatus::INVALID_ARGUMENT) {
+ const auto& [message, code, outputShapes] = result.error();
+ return nn::error(code) << message;
}
- Task task = [preparedModel, nnRequest = std::move(nnRequest), nnMeasure, callback] {
- auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {}, {}, {});
- notify(callback.get(), std::move(result));
- };
- executor(std::move(task), {});
-
+ notify(callback.get(), std::move(result));
return {};
}
nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel,
- const Executor& executor, const V1_3::Request& request,
- V1_2::MeasureTiming measure,
+ const V1_3::Request& request, V1_2::MeasureTiming measure,
const V1_3::OptionalTimePoint& deadline,
const V1_3::OptionalTimeoutDuration& loopTimeoutDuration,
const sp<V1_3::IExecutionCallback>& callback) {
@@ -203,25 +184,20 @@
return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback";
}
- auto nnRequest = NN_TRY(convertInput(request));
+ const auto nnRequest = NN_TRY(convertInput(request));
const auto nnMeasure = NN_TRY(convertInput(measure));
const auto nnDeadline = NN_TRY(convertInput(deadline));
const auto nnLoopTimeoutDuration = NN_TRY(convertInput(loopTimeoutDuration));
- const std::any resource = preparedModel->getUnderlyingResource();
- if (const auto* model = std::any_cast<const nn::Model*>(&resource)) {
- CHECK(*model != nullptr);
- NN_TRY(adapter::validateRequestForModel(nnRequest, **model));
+ auto result =
+ preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration, {}, {});
+
+ if (!result.ok() && result.error().code == nn::ErrorStatus::INVALID_ARGUMENT) {
+ const auto& [message, code, outputShapes] = result.error();
+ return nn::error(code) << message;
}
- Task task = [preparedModel, nnRequest = std::move(nnRequest), nnMeasure, nnDeadline,
- nnLoopTimeoutDuration, callback] {
- auto result = preparedModel->execute(nnRequest, nnMeasure, nnDeadline,
- nnLoopTimeoutDuration, {}, {});
- notify(callback.get(), std::move(result));
- };
- executor(std::move(task), nnDeadline);
-
+ notify(callback.get(), std::move(result));
return {};
}
@@ -304,10 +280,9 @@
} // namespace
-PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor)
- : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)) {
+PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel)
+ : kPreparedModel(std::move(preparedModel)) {
CHECK(kPreparedModel != nullptr);
- CHECK(kExecutor != nullptr);
}
nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const {
@@ -316,7 +291,7 @@
Return<V1_0::ErrorStatus> PreparedModel::execute(const V1_0::Request& request,
const sp<V1_0::IExecutionCallback>& callback) {
- auto result = adapter::execute(kPreparedModel, kExecutor, request, callback);
+ auto result = adapter::execute(kPreparedModel, request, callback);
if (!result.has_value()) {
auto [message, code] = std::move(result).error();
LOG(ERROR) << "adapter::PreparedModel::execute failed with " << code << ": " << message;
@@ -329,7 +304,7 @@
Return<V1_0::ErrorStatus> PreparedModel::execute_1_2(const V1_0::Request& request,
V1_2::MeasureTiming measure,
const sp<V1_2::IExecutionCallback>& callback) {
- auto result = adapter::execute_1_2(kPreparedModel, kExecutor, request, measure, callback);
+ auto result = adapter::execute_1_2(kPreparedModel, request, measure, callback);
if (!result.has_value()) {
auto [message, code] = std::move(result).error();
LOG(ERROR) << "adapter::PreparedModel::execute_1_2 failed with " << code << ": " << message;
@@ -344,7 +319,7 @@
const V1_3::OptionalTimePoint& deadline,
const V1_3::OptionalTimeoutDuration& loopTimeoutDuration,
const sp<V1_3::IExecutionCallback>& callback) {
- auto result = adapter::execute_1_3(kPreparedModel, kExecutor, request, measure, deadline,
+ auto result = adapter::execute_1_3(kPreparedModel, request, measure, deadline,
loopTimeoutDuration, callback);
if (!result.has_value()) {
auto [message, code] = std::move(result).error();
@@ -405,8 +380,8 @@
cb(V1_2::utils::convert(code).value(), nullptr);
return Void();
}
- auto burstContext = std::move(result).value();
- cb(V1_0::ErrorStatus::NONE, std::move(burstContext));
+ const auto burstContext = std::move(result).value();
+ cb(V1_0::ErrorStatus::NONE, burstContext);
return Void();
}
diff --git a/neuralnetworks/utils/common/Android.bp b/neuralnetworks/utils/common/Android.bp
index bfba24f..91fca2f 100644
--- a/neuralnetworks/utils/common/Android.bp
+++ b/neuralnetworks/utils/common/Android.bp
@@ -36,6 +36,7 @@
cc_test {
name: "neuralnetworks_utils_hal_common_test",
host_supported: true,
+ tidy_timeout_srcs: ["test/ResilientDeviceTest.cpp"],
srcs: ["test/*.cpp"],
static_libs: [
"libgmock",
diff --git a/neuralnetworks/utils/service/include/nnapi/hal/Service.h b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
index 2fd5237..38d2a54 100644
--- a/neuralnetworks/utils/service/include/nnapi/hal/Service.h
+++ b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
@@ -24,12 +24,16 @@
namespace android::hardware::neuralnetworks::service {
-struct SharedDeviceAndUpdatability {
- nn::SharedDevice device;
- bool isDeviceUpdatable = false;
-};
-
-std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers);
+/**
+ * @brief Get the NNAPI sAIDL and HIDL services declared in the VINTF.
+ *
+ * @pre maxFeatureLevelAllowed >= Version::Level::FEATURE_LEVEL_5
+ *
+ * @param maxFeatureLevelAllowed Maximum version of driver allowed to be used. Any driver version
+ * exceeding this must be clamped to `maxFeatureLevelAllowed`.
+ * @return A list of devices and whether each device is updatable or not.
+ */
+std::vector<nn::SharedDevice> getDevices(nn::Version::Level maxFeatureLevelAllowed);
} // namespace android::hardware::neuralnetworks::service
diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp
index 2286288..dd37dae 100644
--- a/neuralnetworks/utils/service/src/Service.cpp
+++ b/neuralnetworks/utils/service/src/Service.cpp
@@ -51,7 +51,7 @@
using getDeviceFn = std::add_pointer_t<nn::GeneralResult<nn::SharedDevice>(const std::string&)>;
void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
- std::vector<SharedDeviceAndUpdatability>* devices,
+ std::vector<nn::SharedDevice>* devices,
std::unordered_set<std::string>* registeredDevices) {
CHECK(devices != nullptr);
CHECK(registeredDevices != nullptr);
@@ -63,7 +63,7 @@
if (maybeDevice.has_value()) {
auto device = std::move(maybeDevice).value();
CHECK(device != nullptr);
- devices->push_back({.device = std::move(device)});
+ devices->push_back(std::move(device));
} else {
LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
<< ": " << maybeDevice.error().message;
@@ -72,9 +72,9 @@
}
}
-void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
+void getAidlDevices(std::vector<nn::SharedDevice>* devices,
std::unordered_set<std::string>* registeredDevices,
- bool includeUpdatableDrivers) {
+ nn::Version::Level maxFeatureLevelAllowed) {
CHECK(devices != nullptr);
CHECK(registeredDevices != nullptr);
@@ -91,21 +91,12 @@
}
for (const auto& name : names) {
- bool isDeviceUpdatable = false;
- if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
- const auto instance = std::string(aidl_hal::IDevice::descriptor) + '/' + name;
- isDeviceUpdatable = AServiceManager_isUpdatableViaApex(instance.c_str());
- }
- if (isDeviceUpdatable && !includeUpdatableDrivers) {
- continue;
- }
if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
- auto maybeDevice = aidl_hal::utils::getDevice(name);
+ auto maybeDevice = aidl_hal::utils::getDevice(name, maxFeatureLevelAllowed);
if (maybeDevice.has_value()) {
auto device = std::move(maybeDevice).value();
CHECK(device != nullptr);
- devices->push_back(
- {.device = std::move(device), .isDeviceUpdatable = isDeviceUpdatable});
+ devices->push_back(std::move(device));
} else {
LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
<< ": " << maybeDevice.error().message;
@@ -116,11 +107,13 @@
} // namespace
-std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers) {
- std::vector<SharedDeviceAndUpdatability> devices;
+std::vector<nn::SharedDevice> getDevices(nn::Version::Level maxFeatureLevelAllowed) {
+ std::vector<nn::SharedDevice> devices;
std::unordered_set<std::string> registeredDevices;
- getAidlDevices(&devices, ®isteredDevices, includeUpdatableDrivers);
+ CHECK_GE(maxFeatureLevelAllowed, nn::Version::Level::FEATURE_LEVEL_5);
+
+ getAidlDevices(&devices, ®isteredDevices, maxFeatureLevelAllowed);
getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
®isteredDevices);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
index fe10587..5224624 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
+++ b/radio/1.0/vts/functional/sap_hidl_hal_test.cpp
@@ -16,8 +16,37 @@
#include <sap_hidl_hal_utils.h>
+bool isServiceValidForDeviceConfiguration(hidl_string& serviceName) {
+ if (isSsSsEnabled()) {
+ // Device is configured as SSSS.
+ if (serviceName != SAP_SERVICE_SLOT1_NAME) {
+ LOG(DEBUG) << "Not valid for SSSS device.";
+ return false;
+ }
+ } else if (isDsDsEnabled()) {
+ // Device is configured as DSDS.
+ if (serviceName != SAP_SERVICE_SLOT1_NAME && serviceName != SAP_SERVICE_SLOT2_NAME) {
+ LOG(DEBUG) << "Not valid for DSDS device.";
+ return false;
+ }
+ } else if (isTsTsEnabled()) {
+ // Device is configured as TSTS.
+ if (serviceName != SAP_SERVICE_SLOT1_NAME && serviceName != SAP_SERVICE_SLOT2_NAME &&
+ serviceName != SAP_SERVICE_SLOT3_NAME) {
+ LOG(DEBUG) << "Not valid for TSTS device.";
+ return false;
+ }
+ }
+ return true;
+}
+
void SapHidlTest::SetUp() {
- sap = ISap::getService(GetParam());
+ hidl_string serviceName = GetParam();
+ if (!isServiceValidForDeviceConfiguration(serviceName)) {
+ LOG(DEBUG) << "Skipped the test due to device configuration.";
+ GTEST_SKIP();
+ }
+ sap = ISap::getService(serviceName);
ASSERT_NE(sap, nullptr);
sapCb = new SapCallback(*this);
diff --git a/radio/1.0/vts/functional/sap_hidl_hal_utils.h b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
index 2fc9ae3..8e86591 100644
--- a/radio/1.0/vts/functional/sap_hidl_hal_utils.h
+++ b/radio/1.0/vts/functional/sap_hidl_hal_utils.h
@@ -36,7 +36,15 @@
using ::android::sp;
#define TIMEOUT_PERIOD 40
-#define SAP_SERVICE_NAME "slot1"
+
+// HAL instance name for SIM slot 1 or single SIM device
+#define SAP_SERVICE_SLOT1_NAME "slot1"
+
+// HAL instance name for SIM slot 2 on dual SIM device
+#define SAP_SERVICE_SLOT2_NAME "slot2"
+
+// HAL instance name for SIM slot 3 on triple SIM device
+#define SAP_SERVICE_SLOT3_NAME "slot3"
class SapHidlTest;
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index 8060e4b..8f28255 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -27,6 +27,12 @@
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
+ tidy_timeout_srcs: [
+ "radio_messaging_test.cpp",
+ "radio_network_test.cpp",
+ "radio_sim_test.cpp",
+ "radio_voice_test.cpp",
+ ],
srcs: [
"radio_aidl_hal_utils.cpp",
"radio_config_indication.cpp",
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
index eec28b1..249ee63 100644
--- a/radio/aidl/vts/radio_voice_test.cpp
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -943,3 +943,37 @@
}
LOG(DEBUG) << "cancelPendingUssd finished";
}
+
+/*
+ * Test IRadioVoice.isVoNrEnabled() for the response returned.
+ */
+TEST_P(RadioVoiceTest, isVoNrEnabled) {
+ LOG(DEBUG) << "isVoNrEnabled";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->isVoNrEnabled(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+ LOG(DEBUG) << "isVoNrEnabled finished";
+}
+
+/*
+ * Test IRadioVoice.setVoNrEnabled() for the response returned.
+ */
+TEST_P(RadioVoiceTest, setVoNrEnabled) {
+ LOG(DEBUG) << "setVoNrEnabled";
+ serial = GetRandomSerialNumber();
+
+ radio_voice->setVoNrEnabled(serial, true);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
+ {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+ LOG(DEBUG) << "setVoNrEnabled finished";
+}
diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp
index 01bc91e..8c31e26 100644
--- a/security/dice/aidl/Android.bp
+++ b/security/dice/aidl/Android.bp
@@ -38,6 +38,10 @@
enabled: true,
},
apps_enabled: false,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.compos",
+ ],
},
rust: {
enabled: true,
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
index fa643fc..dcc22c4 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -49,5 +49,8 @@
void earlyBootEnded();
byte[] convertStorageKeyToEphemeral(in byte[] storageKeyBlob);
android.hardware.security.keymint.KeyCharacteristics[] getKeyCharacteristics(in byte[] keyBlob, in byte[] appId, in byte[] appData);
+ byte[16] getRootOfTrustChallenge();
+ byte[] getRootOfTrust(in byte[16] challenge);
+ void sendRootOfTrust(in byte[] rootOfTrust);
const int AUTH_TOKEN_MAC_LENGTH = 32;
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 4b63799..da02d54 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -851,4 +851,82 @@
*/
KeyCharacteristics[] getKeyCharacteristics(
in byte[] keyBlob, in byte[] appId, in byte[] appData);
+
+ /**
+ * Returns a 16-byte random challenge nonce, used to prove freshness when exchanging root of
+ * trust data.
+ *
+ * This method may only be implemented by StrongBox KeyMint. TEE KeyMint implementations must
+ * return ErrorCode::UNIMPLEMENTED. StrongBox KeyMint implementations MAY return UNIMPLEMENTED,
+ * to indicate that they have an alternative mechanism for getting the data. If the StrongBox
+ * implementation returns UNIMPLEMENTED, the client should not call `getRootofTrust()` or
+ * `sendRootOfTrust()`.
+ */
+ byte[16] getRootOfTrustChallenge();
+
+ /**
+ * Returns the TEE KeyMint Root of Trust data.
+ *
+ * This method is required for TEE KeyMint. StrongBox KeyMint implementations MUST return
+ * ErrorCode::UNIMPLEMENTED.
+ *
+ * The returned data is an encoded COSE_Mac0 structure, denoted MacedRootOfTrust in the
+ * following CDDL schema. Note that K_mac is the shared HMAC key used for auth tokens, etc.:
+ *
+ * MacedRootOfTrust = [ ; COSE_Mac0 (untagged)
+ * protected: bstr .cbor {
+ * 1 : 5, ; Algorithm : HMAC-256
+ * },
+ * unprotected : {},
+ * payload : bstr .cbor RootOfTrust,
+ * tag : bstr HMAC-256(K_mac, MAC_structure)
+ * ]
+ *
+ * MAC_structure = [
+ * context : "MAC0",
+ * protected : bstr .cbor {
+ * 1 : 5, ; Algorithm : HMAC-256
+ * },
+ * external_aad : bstr .size 16 ; Value of challenge argument
+ * payload : bstr .cbor RootOfTrust,
+ * ]
+ *
+ * RootOfTrust = [
+ * verifiedBootKey : bstr .size 32,
+ * deviceLocked : bool,
+ * verifiedBootState : &VerifiedBootState,
+ * verifiedBootHash : bstr .size 32,
+ * bootPatchLevel : int, ; See Tag::BOOT_PATCHLEVEL
+ * ]
+ *
+ * VerifiedBootState = (
+ * Verified : 0,
+ * SelfSigned : 1,
+ * Unverified : 2,
+ * Failed : 3
+ * )
+ */
+ byte[] getRootOfTrust(in byte[16] challenge);
+
+ /**
+ * Delivers the TEE KeyMint Root of Trust data to StrongBox KeyMint. See `getRootOfTrust()`
+ * above for specification of the data format and cryptographic security structure.
+ *
+ * The implementation must verify the MAC on the RootOfTrust data. If it is valid, and if this
+ * is the first time since reboot that StrongBox KeyMint has received this data, it must store
+ * the RoT data for use in key attestation requests, then return ErrorCode::ERROR_OK.
+ *
+ * If the MAC on the Root of Trust data and challenge is incorrect, the implementation must
+ * return ErrorCode::VERIFICATION_FAILED.
+ *
+ * If the RootOfTrust data has already been received since the last boot, the implementation
+ * must validate the data and return ErrorCode::VERIFICATION_FAILED or ErrorCode::ERROR_OK
+ * according to the result, but must not store the data for use in key attestation requests,
+ * even if verification succeeds. On success, the challenge is invalidated and a new challenge
+ * must be requested before the RootOfTrust data may be sent again.
+ *
+ * This method is optional for StrongBox KeyMint, which MUST return ErrorCode::UNIMPLEMENTED if
+ * not implemented. TEE KeyMint implementations must return ErrorCode::UNIMPLEMENTED.
+ */
+ void sendRootOfTrust(in byte[] rootOfTrust);
}
diff --git a/security/keymint/aidl/default/TEST_MAPPING b/security/keymint/aidl/default/TEST_MAPPING
new file mode 100644
index 0000000..2400ccd
--- /dev/null
+++ b/security/keymint/aidl/default/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit" : [
+ {
+ "name" : "vts_treble_vintf_framework_test"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/security/keymint/aidl/default/android.hardware.security.keymint-service.xml b/security/keymint/aidl/default/android.hardware.security.keymint-service.xml
index 4aa05ef..a4d0302 100644
--- a/security/keymint/aidl/default/android.hardware.security.keymint-service.xml
+++ b/security/keymint/aidl/default/android.hardware.security.keymint-service.xml
@@ -1,10 +1,12 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.security.keymint</name>
+ <version>2</version>
<fqname>IKeyMintDevice/default</fqname>
</hal>
<hal format="aidl">
<name>android.hardware.security.keymint</name>
+ <version>2</version>
<fqname>IRemotelyProvisionedComponent/default</fqname>
</hal>
</manifest>
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 91db3c8..ef5b0bd 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -50,10 +50,14 @@
defaults: [
"keymint_vts_defaults",
],
+ tidy_timeout_srcs: [
+ "KeyMintTest.cpp",
+ ],
srcs: [
"AttestKeyTest.cpp",
"DeviceUniqueAttestationTest.cpp",
"KeyMintTest.cpp",
+ "SecureElementProvisioningTest.cpp",
],
static_libs: [
"libkeymint_vts_test_utils",
@@ -69,6 +73,9 @@
defaults: [
"keymint_vts_defaults",
],
+ tidy_timeout_srcs: [
+ "KeyMintAidlTestBase.cpp",
+ ],
srcs: [
"KeyMintAidlTestBase.cpp",
],
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 727c6b7..8a26b3c 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -219,18 +219,22 @@
AttestationKey attest_key;
vector<KeyCharacteristics> attest_key_characteristics;
vector<Certificate> attest_key_cert_chain;
- ASSERT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .RsaKey(2048, 65537)
- .AttestKey()
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- {} /* attestation signing key */, &attest_key.keyBlob,
- &attest_key_characteristics, &attest_key_cert_chain));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .RsaKey(2048, 65537)
+ .AttestKey()
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ {} /* attestation signing key */, &attest_key.keyBlob,
+ &attest_key_characteristics, &attest_key_cert_chain);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
EXPECT_GT(attest_key_cert_chain.size(), 1);
verify_subject_and_serial(attest_key_cert_chain[0], serial_int, subject, false);
@@ -319,18 +323,22 @@
attest_key_opt = attest_key;
}
- EXPECT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .RsaKey(2048, 65537)
- .AttestKey()
- .AttestationChallenge("foo")
- .AttestationApplicationId("bar")
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .SetDefaultValidity(),
- attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
- &cert_chain_list[i]));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .RsaKey(2048, 65537)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -392,18 +400,22 @@
attest_key_opt = attest_key;
}
- EXPECT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .EcdsaKey(EcCurve::P_256)
- .AttestKey()
- .AttestationChallenge("foo")
- .AttestationApplicationId("bar")
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
- &cert_chain_list[i]));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .EcdsaKey(EcCurve::P_256)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
@@ -484,34 +496,37 @@
attest_key.keyBlob = key_blob_list[i - 1];
attest_key_opt = attest_key;
}
-
+ ErrorCode result;
if ((i & 0x1) == 1) {
- EXPECT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .EcdsaKey(EcCurve::P_256)
- .AttestKey()
- .AttestationChallenge("foo")
- .AttestationApplicationId("bar")
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
- &cert_chain_list[i]));
+ result = GenerateKey(AuthorizationSetBuilder()
+ .EcdsaKey(EcCurve::P_256)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]);
} else {
- EXPECT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .RsaKey(2048, 65537)
- .AttestKey()
- .AttestationChallenge("foo")
- .AttestationApplicationId("bar")
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
- &cert_chain_list[i]));
+ result = GenerateKey(AuthorizationSetBuilder()
+ .RsaKey(2048, 65537)
+ .AttestKey()
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
+ &cert_chain_list[i]);
}
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index d4bbd69..1dc5df3 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -80,6 +80,7 @@
.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
.Authorization(TAG_INCLUDE_UNIQUE_ID)
.Authorization(TAG_CREATION_DATETIME, 1619621648000)
+ .SetDefaultValidity()
.AttestationChallenge("challenge")
.AttestationApplicationId("foo")
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -109,6 +110,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID)
.Authorization(TAG_CREATION_DATETIME, 1619621648000)
+ .SetDefaultValidity()
.AttestationChallenge("challenge")
.AttestationApplicationId("foo")
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -139,6 +141,7 @@
.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
.Authorization(TAG_INCLUDE_UNIQUE_ID)
.Authorization(TAG_CREATION_DATETIME, 1619621648000)
+ .SetDefaultValidity()
.AttestationChallenge("challenge")
.AttestationApplicationId("foo")
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -197,6 +200,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID)
.Authorization(TAG_CREATION_DATETIME, 1619621648000)
+ .SetDefaultValidity()
.AttestationChallenge("challenge")
.AttestationApplicationId("foo")
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
@@ -264,6 +268,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID)
.Authorization(TAG_CREATION_DATETIME, 1619621648000)
+ .SetDefaultValidity()
.AttestationChallenge("challenge")
.AttestationApplicationId("foo")
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
@@ -336,6 +341,7 @@
.Digest(Digest::SHA_2_256)
.Authorization(TAG_INCLUDE_UNIQUE_ID)
.Authorization(TAG_CREATION_DATETIME, 1619621648000)
+ .SetDefaultValidity()
.AttestationChallenge("challenge")
.AttestationApplicationId("foo")
.Authorization(TAG_DEVICE_UNIQUE_ATTESTATION);
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 146a527..ff4036c 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1228,6 +1228,14 @@
}
}
+vector<uint64_t> KeyMintAidlTestBase::ValidExponents() {
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ return {65537};
+ } else {
+ return {3, 65537};
+ }
+}
+
vector<Digest> KeyMintAidlTestBase::ValidDigests(bool withNone, bool withMD5) {
switch (SecLevel()) {
case SecurityLevel::SOFTWARE:
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 27cb99c..6fb5bf5 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -253,7 +253,10 @@
.SetDefaultValidity();
tagModifier(&rsaBuilder);
errorCode = GenerateKey(rsaBuilder, &rsaKeyData.blob, &rsaKeyData.characteristics);
- EXPECT_EQ(expectedReturn, errorCode);
+ if (!(SecLevel() == SecurityLevel::STRONGBOX &&
+ ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED == errorCode)) {
+ EXPECT_EQ(expectedReturn, errorCode);
+ }
/* ECDSA */
KeyData ecdsaKeyData;
@@ -265,7 +268,10 @@
.SetDefaultValidity();
tagModifier(&ecdsaBuilder);
errorCode = GenerateKey(ecdsaBuilder, &ecdsaKeyData.blob, &ecdsaKeyData.characteristics);
- EXPECT_EQ(expectedReturn, errorCode);
+ if (!(SecLevel() == SecurityLevel::STRONGBOX &&
+ ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED == errorCode)) {
+ EXPECT_EQ(expectedReturn, errorCode);
+ }
return {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData};
}
bool IsSecure() const { return securityLevel_ != SecurityLevel::SOFTWARE; }
@@ -282,6 +288,7 @@
vector<EcCurve> InvalidCurves();
vector<Digest> ValidDigests(bool withNone, bool withMD5);
+ vector<uint64_t> ValidExponents();
static vector<string> build_params() {
auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 62f22bb..767de2b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1018,6 +1018,37 @@
}
/*
+ * NewKeyGenerationTest.RsaWithMissingValidity
+ *
+ * Verifies that keymint returns an error while generating asymmetric key
+ * without providing NOT_BEFORE and NOT_AFTER parameters.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithMissingValidity) {
+ // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to
+ // GeneralizedTime 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
+ constexpr uint64_t kUndefinedExpirationDateTime = 253402300799000;
+
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ ASSERT_EQ(ErrorCode::MISSING_NOT_BEFORE,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_CERTIFICATE_NOT_AFTER,
+ kUndefinedExpirationDateTime),
+ &key_blob, &key_characteristics));
+
+ ASSERT_EQ(ErrorCode::MISSING_NOT_AFTER,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_CERTIFICATE_NOT_BEFORE, 0),
+ &key_blob, &key_characteristics));
+}
+
+/*
* NewKeyGenerationTest.RsaWithAttestation
*
* Verifies that keymint can generate all required RSA key sizes with attestation, and that the
@@ -1036,18 +1067,21 @@
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1169,17 +1203,21 @@
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .RsaEncryptionKey(key_size, 65537)
- .Padding(PaddingMode::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .RsaEncryptionKey(key_size, 65537)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
ASSERT_GT(key_blob.size(), 0U);
AuthorizationSet auths;
@@ -1281,15 +1319,19 @@
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
- GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .AttestationChallenge(challenge)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING, result);
}
/*
@@ -1399,19 +1441,23 @@
for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(key_size, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(key_size, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_USAGE_COUNT_LIMIT, 1)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
@@ -1583,6 +1629,35 @@
}
/*
+ * NewKeyGenerationTest.EcdsaWithMissingValidity
+ *
+ * Verifies that keymint returns an error while generating asymmetric key
+ * without providing NOT_BEFORE and NOT_AFTER parameters.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaWithMissingValidity) {
+ // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to
+ // GeneralizedTime 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
+ constexpr uint64_t kUndefinedExpirationDateTime = 253402300799000;
+
+ vector<uint8_t> key_blob;
+ vector<KeyCharacteristics> key_characteristics;
+ ASSERT_EQ(ErrorCode::MISSING_NOT_BEFORE,
+ GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::NONE)
+ .Authorization(TAG_CERTIFICATE_NOT_AFTER,
+ kUndefinedExpirationDateTime),
+ &key_blob, &key_characteristics));
+
+ ASSERT_EQ(ErrorCode::MISSING_NOT_AFTER,
+ GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::NONE)
+ .Authorization(TAG_CERTIFICATE_NOT_BEFORE, 0),
+ &key_blob, &key_characteristics));
+}
+
+/*
* NewKeyGenerationTest.EcdsaAttestation
*
* Verifies that for all Ecdsa key sizes, if challenge and app id is provided,
@@ -1601,17 +1676,21 @@
for (auto curve : ValidCurves()) {
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK,
- GenerateKey(AuthorizationSetBuilder()
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .EcdsaSigningKey(curve)
- .Digest(Digest::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
- .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(curve)
+ .Digest(Digest::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+ .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -1745,6 +1824,10 @@
// Tag not required to be supported by all KeyMint implementations.
continue;
}
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
ASSERT_EQ(result, ErrorCode::OK);
ASSERT_GT(key_blob.size(), 0U);
@@ -1840,6 +1923,10 @@
AuthorizationSetBuilder builder = base_builder;
builder.push_back(tag);
auto result = GenerateKey(builder, &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
if (result == ErrorCode::CANNOT_ATTEST_IDS) {
// Device ID attestation is optional; KeyMint may not support it at all.
continue;
@@ -1997,6 +2084,10 @@
.Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
.SetDefaultValidity(),
&key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
ASSERT_EQ(result, ErrorCode::OK);
ASSERT_GT(key_blob.size(), 0U);
@@ -2076,13 +2167,17 @@
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
- GenerateKey(AuthorizationSetBuilder()
- .EcdsaSigningKey(EcCurve::P_256)
- .Digest(Digest::NONE)
- .AttestationChallenge(challenge)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::NONE)
+ .AttestationChallenge(challenge)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING, result);
}
/*
@@ -2139,14 +2234,19 @@
const string app_id(length, 'a');
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .Authorization(TAG_NO_AUTH_REQUIRED)
- .EcdsaSigningKey(EcCurve::P_256)
- .Digest(Digest::NONE)
- .AttestationChallenge(challenge)
- .AttestationApplicationId(app_id)
- .SetDefaultValidity(),
- &key_blob, &key_characteristics));
+ auto result = GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::NONE)
+ .AttestationChallenge(challenge)
+ .AttestationApplicationId(app_id)
+ .SetDefaultValidity(),
+ &key_blob, &key_characteristics);
+ // Strongbox may not support factory provisioned attestation key.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
+ }
+ ASSERT_EQ(ErrorCode::OK, result);
ASSERT_GT(key_blob.size(), 0U);
CheckBaseParams(key_characteristics);
CheckCharacteristics(key_blob, key_characteristics);
@@ -4646,7 +4746,7 @@
* Verifies that raw RSA decryption works.
*/
TEST_P(EncryptionOperationsTest, RsaNoPaddingSuccess) {
- for (uint64_t exponent : {3, 65537}) {
+ for (uint64_t exponent : ValidExponents()) {
ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
.Authorization(TAG_NO_AUTH_REQUIRED)
.RsaEncryptionKey(2048, exponent)
@@ -7209,7 +7309,7 @@
size_t i;
for (i = 0; i < max_operations; i++) {
- result = Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params, op_handles[i]);
+ result = Begin(KeyPurpose::DECRYPT, key_blob_, params, &out_params, op_handles[i]);
if (ErrorCode::OK != result) {
break;
}
@@ -7217,12 +7317,12 @@
EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS, result);
// Try again just in case there's a weird overflow bug
EXPECT_EQ(ErrorCode::TOO_MANY_OPERATIONS,
- Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params));
+ Begin(KeyPurpose::DECRYPT, key_blob_, params, &out_params));
for (size_t j = 0; j < i; j++) {
EXPECT_EQ(ErrorCode::OK, Abort(op_handles[j]))
<< "Aboort failed for i = " << j << std::endl;
}
- EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, key_blob_, params, &out_params));
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, key_blob_, params, &out_params));
AbortIfNeeded();
}
@@ -7611,14 +7711,23 @@
});
for (const auto& keyData : {aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData}) {
+ // Strongbox may not support factory attestation. Key creation might fail with
+ // ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED
+ if (SecLevel() == SecurityLevel::STRONGBOX && keyData.blob.size() == 0U) {
+ continue;
+ }
ASSERT_GT(keyData.blob.size(), 0U);
AuthorizationSet crypto_params = SecLevelAuthorizations(keyData.characteristics);
EXPECT_TRUE(crypto_params.Contains(TAG_EARLY_BOOT_ONLY)) << crypto_params;
}
CheckedDeleteKey(&aesKeyData.blob);
CheckedDeleteKey(&hmacKeyData.blob);
- CheckedDeleteKey(&rsaKeyData.blob);
- CheckedDeleteKey(&ecdsaKeyData.blob);
+ if (rsaKeyData.blob.size() != 0U) {
+ CheckedDeleteKey(&rsaKeyData.blob);
+ }
+ if (ecdsaKeyData.blob.size() != 0U) {
+ CheckedDeleteKey(&ecdsaKeyData.blob);
+ }
}
/*
diff --git a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
new file mode 100644
index 0000000..83ee188
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "keymint_2_se_provisioning_test"
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include <cppbor_parse.h>
+#include <keymaster/cppcose/cppcose.h>
+#include <keymint_support/key_param_output.h>
+
+#include "KeyMintAidlTestBase.h"
+
+namespace aidl::android::hardware::security::keymint::test {
+
+using std::array;
+using std::map;
+using std::shared_ptr;
+using std::vector;
+
+class SecureElementProvisioningTest : public testing::Test {
+ protected:
+ static void SetUpTestSuite() {
+ auto params = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
+ for (auto& param : params) {
+ ASSERT_TRUE(AServiceManager_isDeclared(param.c_str()))
+ << "IKeyMintDevice instance " << param << " found but not declared.";
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService(param.c_str()));
+ auto keymint = IKeyMintDevice::fromBinder(binder);
+ ASSERT_NE(keymint, nullptr) << "Failed to get IKeyMintDevice instance " << param;
+
+ KeyMintHardwareInfo info;
+ ASSERT_TRUE(keymint->getHardwareInfo(&info).isOk());
+ ASSERT_EQ(keymints_.count(info.securityLevel), 0)
+ << "There must be exactly one IKeyMintDevice with security level "
+ << info.securityLevel;
+
+ keymints_[info.securityLevel] = std::move(keymint);
+ }
+ }
+
+ static map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
+};
+
+map<SecurityLevel, shared_ptr<IKeyMintDevice>> SecureElementProvisioningTest::keymints_;
+
+TEST_F(SecureElementProvisioningTest, ValidConfigurations) {
+ // TEE is required
+ ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
+ // StrongBox is optional
+ ASSERT_LE(keymints_.count(SecurityLevel::STRONGBOX), 1);
+}
+
+TEST_F(SecureElementProvisioningTest, TeeOnly) {
+ ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
+ auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+ ASSERT_NE(tee, nullptr);
+
+ array<uint8_t, 16> challenge1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ array<uint8_t, 16> challenge2 = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ vector<uint8_t> rootOfTrust1;
+ Status result = tee->getRootOfTrust(challenge1, &rootOfTrust1);
+
+ // TODO: Remove the next line to require TEEs to succeed.
+ if (!result.isOk()) return;
+
+ ASSERT_TRUE(result.isOk());
+
+ // TODO: Parse and validate rootOfTrust1 here
+
+ vector<uint8_t> rootOfTrust2;
+ result = tee->getRootOfTrust(challenge2, &rootOfTrust2);
+ ASSERT_TRUE(result.isOk());
+
+ // TODO: Parse and validate rootOfTrust2 here
+
+ ASSERT_NE(rootOfTrust1, rootOfTrust2);
+
+ vector<uint8_t> rootOfTrust3;
+ result = tee->getRootOfTrust(challenge1, &rootOfTrust3);
+ ASSERT_TRUE(result.isOk());
+
+ ASSERT_EQ(rootOfTrust1, rootOfTrust3);
+
+ // TODO: Parse and validate rootOfTrust3 here
+}
+
+TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
+ ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
+ auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+ ASSERT_NE(tee, nullptr);
+
+ array<uint8_t, 16> challenge;
+ Status result = tee->getRootOfTrustChallenge(&challenge);
+ ASSERT_FALSE(result.isOk());
+ ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
+
+ result = tee->sendRootOfTrust({});
+ ASSERT_FALSE(result.isOk());
+ ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
+}
+
+TEST_F(SecureElementProvisioningTest, StrongBoxDoesNotImplementTeeMethods) {
+ if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return;
+
+ auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
+ ASSERT_NE(sb, nullptr);
+
+ vector<uint8_t> rootOfTrust;
+ Status result = sb->getRootOfTrust({}, &rootOfTrust);
+ ASSERT_FALSE(result.isOk());
+ ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()), ErrorCode::UNIMPLEMENTED);
+}
+
+TEST_F(SecureElementProvisioningTest, UnimplementedTest) {
+ if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return; // Need a StrongBox to provision.
+
+ ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
+ auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+ ASSERT_NE(tee, nullptr);
+
+ ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+ auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
+ ASSERT_NE(sb, nullptr);
+
+ array<uint8_t, 16> challenge;
+ Status result = sb->getRootOfTrustChallenge(&challenge);
+ if (!result.isOk()) {
+ // Strongbox does not have to implement this feature if it has uses an alternative mechanism
+ // to provision the root of trust. In that case it MUST return UNIMPLEMENTED, both from
+ // getRootOfTrustChallenge() and from sendRootOfTrust().
+ ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
+ ErrorCode::UNIMPLEMENTED);
+
+ result = sb->sendRootOfTrust({});
+ ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
+ ErrorCode::UNIMPLEMENTED);
+
+ SUCCEED() << "This Strongbox implementation does not use late root of trust delivery.";
+ return;
+ }
+}
+
+TEST_F(SecureElementProvisioningTest, ChallengeQualityTest) {
+ if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return; // Need a StrongBox to provision.
+
+ ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+ auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
+ ASSERT_NE(sb, nullptr);
+
+ array<uint8_t, 16> challenge1;
+ Status result = sb->getRootOfTrustChallenge(&challenge1);
+ if (!result.isOk()) return;
+
+ array<uint8_t, 16> challenge2;
+ result = sb->getRootOfTrustChallenge(&challenge2);
+ ASSERT_TRUE(result.isOk());
+ ASSERT_NE(challenge1, challenge2);
+
+ // TODO: When we add entropy testing in other relevant places in these tests, add it here, too,
+ // to verify that challenges appear to have adequate entropy.
+}
+
+TEST_F(SecureElementProvisioningTest, ProvisioningTest) {
+ if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return; // Need a StrongBox to provision.
+
+ ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
+ auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+ ASSERT_NE(tee, nullptr);
+
+ ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+ auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
+ ASSERT_NE(sb, nullptr);
+
+ array<uint8_t, 16> challenge;
+ Status result = sb->getRootOfTrustChallenge(&challenge);
+ if (!result.isOk()) return;
+
+ vector<uint8_t> rootOfTrust;
+ result = tee->getRootOfTrust(challenge, &rootOfTrust);
+ ASSERT_TRUE(result.isOk());
+
+ // TODO: Verify COSE_Mac0 structure and content here.
+
+ result = sb->sendRootOfTrust(rootOfTrust);
+ ASSERT_TRUE(result.isOk());
+
+ // Sending again must fail, because a new challenge is required.
+ result = sb->sendRootOfTrust(rootOfTrust);
+ ASSERT_FALSE(result.isOk());
+}
+
+TEST_F(SecureElementProvisioningTest, InvalidProvisioningTest) {
+ if (keymints_.count(SecurityLevel::STRONGBOX) == 0) return; // Need a StrongBox to provision.
+
+ ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
+ auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+ ASSERT_NE(tee, nullptr);
+
+ ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+ auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
+ ASSERT_NE(sb, nullptr);
+
+ array<uint8_t, 16> challenge;
+ Status result = sb->getRootOfTrustChallenge(&challenge);
+ if (!result.isOk()) return;
+
+ result = sb->sendRootOfTrust({});
+ ASSERT_FALSE(result.isOk());
+ ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
+ ErrorCode::VERIFICATION_FAILED);
+
+ vector<uint8_t> rootOfTrust;
+ result = tee->getRootOfTrust(challenge, &rootOfTrust);
+ ASSERT_TRUE(result.isOk());
+
+ vector<uint8_t> corruptedRootOfTrust = rootOfTrust;
+ corruptedRootOfTrust[corruptedRootOfTrust.size() / 2]++;
+ result = sb->sendRootOfTrust(corruptedRootOfTrust);
+ ASSERT_FALSE(result.isOk());
+ ASSERT_EQ(result.getExceptionCode(), EX_SERVICE_SPECIFIC);
+ ASSERT_EQ(static_cast<ErrorCode>(result.getServiceSpecificError()),
+ ErrorCode::VERIFICATION_FAILED);
+
+ // Now try the correct RoT
+ result = sb->sendRootOfTrust(rootOfTrust);
+ ASSERT_TRUE(result.isOk());
+}
+
+} // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index e2d75ce..2e90e78 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -185,6 +185,7 @@
provisionable_ = IRemotelyProvisionedComponent::fromBinder(binder);
}
ASSERT_NE(provisionable_, nullptr);
+ ASSERT_TRUE(provisionable_->getHardwareInfo(&rpcHardwareInfo).isOk());
}
static vector<string> build_params() {
@@ -194,6 +195,7 @@
protected:
std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
+ RpcHardwareInfo rpcHardwareInfo;
};
/**
@@ -357,11 +359,10 @@
class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests {
protected:
CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(32)) {
- generateTestEekChain(3);
}
void generateTestEekChain(size_t eekLength) {
- auto chain = generateEekChain(eekLength, eekId_);
+ auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
EXPECT_TRUE(chain) << chain.message();
if (chain) testEekChain_ = chain.moveValue();
testEekLength_ = eekLength;
@@ -382,6 +383,17 @@
}
}
+ ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPubkey) {
+ if (rpcHardwareInfo.supportedEekCurve == RpcHardwareInfo::CURVE_25519 ||
+ rpcHardwareInfo.supportedEekCurve == RpcHardwareInfo::CURVE_NONE) {
+ return x25519_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey,
+ senderPubkey->first, false /* senderIsA */);
+ } else {
+ return ECDH_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey,
+ senderPubkey->first, false /* senderIsA */);
+ }
+ }
+
void checkProtectedData(const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
const bytevec& keysToSignMac, const ProtectedData& protectedData,
std::vector<BccEntryData>* bccOutput = nullptr) {
@@ -394,9 +406,7 @@
ASSERT_TRUE(senderPubkey) << senderPubkey.message();
EXPECT_EQ(senderPubkey->second, eekId_);
- auto sessionKey =
- x25519_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey,
- senderPubkey->first, false /* senderIsA */);
+ auto sessionKey = getSessionKey(senderPubkey);
ASSERT_TRUE(sessionKey) << sessionKey.message();
auto protectedDataPayload =
@@ -406,7 +416,8 @@
auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(*protectedDataPayload);
ASSERT_TRUE(parsedPayload) << "Failed to parse payload: " << payloadErrMsg;
ASSERT_TRUE(parsedPayload->asArray());
- EXPECT_EQ(parsedPayload->asArray()->size(), 2U);
+ // Strongbox may contain additional certificate chain.
+ EXPECT_LE(parsedPayload->asArray()->size(), 3U);
auto& signedMac = parsedPayload->asArray()->get(0);
auto& bcc = parsedPayload->asArray()->get(1);
@@ -566,6 +577,7 @@
bytevec keysToSignMac;
DeviceInfo deviceInfo;
ProtectedData protectedData;
+ generateTestEekChain(3);
auto status = provisionable_->generateCertificateRequest(
testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
@@ -605,8 +617,8 @@
DeviceInfo deviceInfo;
ProtectedData protectedData;
auto status = provisionable_->generateCertificateRequest(
- testMode, {} /* keysToSign */, getProdEekChain(), challenge_, &deviceInfo,
- &protectedData, &keysToSignMac);
+ testMode, {} /* keysToSign */, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
+ challenge_, &deviceInfo, &protectedData, &keysToSignMac);
EXPECT_TRUE(status.isOk());
}
@@ -646,8 +658,8 @@
DeviceInfo deviceInfo;
ProtectedData protectedData;
auto status = provisionable_->generateCertificateRequest(
- testMode, keysToSign_, getProdEekChain(), challenge_, &deviceInfo, &protectedData,
- &keysToSignMac);
+ testMode, keysToSign_, getProdEekChain(rpcHardwareInfo.supportedEekCurve), challenge_,
+ &deviceInfo, &protectedData, &keysToSignMac);
EXPECT_TRUE(status.isOk());
}
@@ -662,6 +674,7 @@
bytevec keysToSignMac;
DeviceInfo deviceInfo;
ProtectedData protectedData;
+ generateTestEekChain(3);
auto status = provisionable_->generateCertificateRequest(
testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
@@ -681,8 +694,8 @@
DeviceInfo deviceInfo;
ProtectedData protectedData;
auto status = provisionable_->generateCertificateRequest(
- testMode, {keyWithCorruptMac}, getProdEekChain(), challenge_, &deviceInfo,
- &protectedData, &keysToSignMac);
+ testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
+ challenge_, &deviceInfo, &protectedData, &keysToSignMac);
ASSERT_FALSE(status.isOk()) << status.getMessage();
EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
}
@@ -695,7 +708,7 @@
bool testMode = false;
generateKeys(testMode, 4 /* numKeys */);
- auto prodEekChain = getProdEekChain();
+ auto prodEekChain = getProdEekChain(rpcHardwareInfo.supportedEekCurve);
auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
ASSERT_NE(parsedChain, nullptr) << parseErr;
ASSERT_NE(parsedChain->asArray(), nullptr);
@@ -726,7 +739,7 @@
// Build an EEK chain that omits the first self-signed cert.
auto truncatedChain = cppbor::Array();
- auto [chain, _, parseErr] = cppbor::parse(getProdEekChain());
+ auto [chain, _, parseErr] = cppbor::parse(getProdEekChain(rpcHardwareInfo.supportedEekCurve));
ASSERT_TRUE(chain);
auto eekChain = chain->asArray();
ASSERT_NE(eekChain, nullptr);
@@ -754,6 +767,7 @@
bytevec keysToSignMac;
DeviceInfo deviceInfo;
ProtectedData protectedData;
+ generateTestEekChain(3);
auto status = provisionable_->generateCertificateRequest(
true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
@@ -772,6 +786,7 @@
bytevec keysToSignMac;
DeviceInfo deviceInfo;
ProtectedData protectedData;
+ generateTestEekChain(3);
auto status = provisionable_->generateCertificateRequest(
false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
&protectedData, &keysToSignMac);
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 36969bb..bf2ab02 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -60,11 +60,15 @@
export_include_dirs: [
"include",
],
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_shared",
+ ],
shared_libs: [
"libbase",
"libcppbor_external",
"libcppcose_rkp",
"libcrypto",
+ "libkeymaster_portable",
"libjsoncpp",
],
}
@@ -76,6 +80,9 @@
"libgmock",
"libgtest_main",
],
+ defaults: [
+ "keymint_use_latest_hal_aidl_ndk_shared",
+ ],
shared_libs: [
"libbase",
"libcppbor_external",
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index 406b7a9..1d3abe5 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -52,6 +52,34 @@
0x31, 0xbf, 0x6b, 0xe8, 0x1e, 0x35, 0xe2, 0xf0, 0x2d, 0xce, 0x6c, 0x2f, 0x4f, 0xf2,
0xf5, 0x4f, 0xa5, 0xd4, 0x83, 0xad, 0x96, 0xa2, 0xf1, 0x87, 0x58, 0x04};
+// The Google ECDSA P256 root key for the Endpoint Encryption Key chain, encoded as COSE_Sign1
+inline constexpr uint8_t kCoseEncodedEcdsa256RootCert[] = {
+ 0x84, 0x43, 0xa1, 0x01, 0x26, 0xa0, 0x58, 0x4d, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21,
+ 0x58, 0x20, 0xf7, 0x14, 0x8a, 0xdb, 0x97, 0xf4, 0xcc, 0x53, 0xef, 0xd2, 0x64, 0x11, 0xc4, 0xe3,
+ 0x75, 0x1f, 0x66, 0x1f, 0xa4, 0x71, 0x0c, 0x6c, 0xcf, 0xfa, 0x09, 0x46, 0x80, 0x74, 0x87, 0x54,
+ 0xf2, 0xad, 0x22, 0x58, 0x20, 0x5e, 0x7f, 0x5b, 0xf6, 0xec, 0xe4, 0xf6, 0x19, 0xcc, 0xff, 0x13,
+ 0x37, 0xfd, 0x0f, 0xa1, 0xc8, 0x93, 0xdb, 0x18, 0x06, 0x76, 0xc4, 0x5d, 0xe6, 0xd7, 0x6a, 0x77,
+ 0x86, 0xc3, 0x2d, 0xaf, 0x8f, 0x58, 0x40, 0x2f, 0x97, 0x8e, 0x42, 0xfb, 0xbe, 0x07, 0x2d, 0x95,
+ 0x47, 0x85, 0x47, 0x93, 0x40, 0xb0, 0x1f, 0xd4, 0x9b, 0x47, 0xa4, 0xc4, 0x44, 0xa9, 0xf2, 0xa1,
+ 0x07, 0x87, 0x10, 0xc7, 0x9f, 0xcb, 0x11, 0xf4, 0xbf, 0x9f, 0xe8, 0x3b, 0xe0, 0xe7, 0x34, 0x4c,
+ 0x15, 0xfc, 0x7b, 0xc3, 0x7e, 0x33, 0x05, 0xf4, 0xd1, 0x34, 0x3c, 0xed, 0x02, 0x04, 0x60, 0x7a,
+ 0x15, 0xe0, 0x79, 0xd3, 0x8a, 0xff, 0x24};
+
+// The Google ECDSA P256 Endpoint Encryption Key certificate, encoded as COSE_Sign1
+inline constexpr uint8_t kCoseEncodedEcdsa256GeekCert[] = {
+ 0x84, 0x43, 0xa1, 0x01, 0x26, 0xa0, 0x58, 0x71, 0xa6, 0x01, 0x02, 0x02, 0x58, 0x20, 0x35, 0x73,
+ 0xb7, 0x3f, 0xa0, 0x8a, 0x80, 0x89, 0xb1, 0x26, 0x67, 0xe9, 0xcb, 0x7c, 0x75, 0xa1, 0xaf, 0x02,
+ 0x61, 0xfc, 0x6e, 0x65, 0x03, 0x91, 0x3b, 0xd3, 0x4b, 0x7d, 0x14, 0x94, 0x3e, 0x46, 0x03, 0x38,
+ 0x18, 0x20, 0x01, 0x21, 0x58, 0x20, 0xe0, 0x41, 0xcf, 0x2f, 0x0f, 0x34, 0x0f, 0x1c, 0x33, 0x2c,
+ 0x41, 0xb0, 0xcf, 0xd7, 0x0c, 0x30, 0x55, 0x35, 0xd2, 0x1e, 0x6a, 0x47, 0x13, 0x4b, 0x2e, 0xd1,
+ 0x48, 0x96, 0x7e, 0x24, 0x9c, 0x68, 0x22, 0x58, 0x20, 0x1f, 0xce, 0x45, 0xc5, 0xfb, 0x61, 0xba,
+ 0x81, 0x21, 0xf9, 0xe5, 0x05, 0x9b, 0x9b, 0x39, 0x0e, 0x76, 0x86, 0x86, 0x47, 0xb8, 0x1e, 0x2f,
+ 0x45, 0xf1, 0xce, 0xaf, 0xda, 0x3f, 0x80, 0x68, 0xdb, 0x58, 0x40, 0x8c, 0xb3, 0xba, 0x7e, 0x20,
+ 0x3e, 0x32, 0xb0, 0x68, 0xdf, 0x60, 0xd1, 0x1d, 0x7d, 0xf0, 0xac, 0x38, 0x8e, 0x51, 0xbc, 0xff,
+ 0x6c, 0xe1, 0x67, 0x3b, 0x4a, 0x79, 0xbc, 0x56, 0x78, 0xb3, 0x99, 0xd8, 0x7c, 0x8a, 0x07, 0xd8,
+ 0xda, 0xb5, 0xb5, 0x7f, 0x71, 0xf4, 0xd8, 0x6b, 0xdf, 0x33, 0x27, 0x34, 0x7b, 0x65, 0xd1, 0x2a,
+ 0xeb, 0x86, 0x99, 0x98, 0xab, 0x3a, 0xb4, 0x80, 0xaa, 0xbd, 0x50};
+
/**
* Generates random bytes.
*/
@@ -64,15 +92,15 @@
};
/**
- * Generates an X25518 EEK with the specified eekId and an Ed25519 chain of the
- * specified length. All keys are generated randomly.
+ * Based on the supportedEekCurve, Generates an X25519/ECDH with the specified eekId
+ * and an Ed25519/ECDSA chain of the specified length. All keys are generated randomly.
*/
-ErrMsgOr<EekChain> generateEekChain(size_t length, const bytevec& eekId);
+ErrMsgOr<EekChain> generateEekChain(int32_t supportedEekCurve, size_t length, const bytevec& eekId);
/**
* Returns the CBOR-encoded, production Google Endpoint Encryption Key chain.
*/
-bytevec getProdEekChain();
+bytevec getProdEekChain(int32_t supportedEekCurve);
struct BccEntryData {
bytevec pubKey;
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 35cb891..0776282 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -17,10 +17,16 @@
#include <iterator>
#include <tuple>
+#include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
#include <android-base/properties.h>
#include <cppbor.h>
#include <json/json.h>
+#include <keymaster/km_openssl/ec_key.h>
+#include <keymaster/km_openssl/ecdsa_operation.h>
+#include <keymaster/km_openssl/openssl_err.h>
+#include <keymaster/km_openssl/openssl_utils.h>
#include <openssl/base64.h>
+#include <openssl/evp.h>
#include <openssl/rand.h>
#include <remote_prov/remote_prov_utils.h>
@@ -30,6 +36,166 @@
constexpr uint32_t kBccPayloadSubject = 2;
constexpr int32_t kBccPayloadSubjPubKey = -4670552;
constexpr int32_t kBccPayloadKeyUsage = -4670553;
+constexpr int kP256AffinePointSize = 32;
+
+using EC_KEY_Ptr = bssl::UniquePtr<EC_KEY>;
+using EVP_PKEY_Ptr = bssl::UniquePtr<EVP_PKEY>;
+using EVP_PKEY_CTX_Ptr = bssl::UniquePtr<EVP_PKEY_CTX>;
+
+ErrMsgOr<bytevec> ecKeyGetPrivateKey(const EC_KEY* ecKey) {
+ // Extract private key.
+ const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey);
+ if (bignum == nullptr) {
+ return "Error getting bignum from private key";
+ }
+ // Pad with zeros in case the length is lesser than 32.
+ bytevec privKey(32, 0);
+ BN_bn2binpad(bignum, privKey.data(), privKey.size());
+ return privKey;
+}
+
+ErrMsgOr<bytevec> ecKeyGetPublicKey(const EC_KEY* ecKey) {
+ // Extract public key.
+ auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ if (group.get() == nullptr) {
+ return "Error creating EC group by curve name";
+ }
+ const EC_POINT* point = EC_KEY_get0_public_key(ecKey);
+ if (point == nullptr) return "Error getting ecpoint from public key";
+
+ int size =
+ EC_POINT_point2oct(group.get(), point, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
+ if (size == 0) {
+ return "Error generating public key encoding";
+ }
+
+ bytevec publicKey;
+ publicKey.resize(size);
+ EC_POINT_point2oct(group.get(), point, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
+ publicKey.size(), nullptr);
+ return publicKey;
+}
+
+ErrMsgOr<std::tuple<bytevec, bytevec>> getAffineCoordinates(const bytevec& pubKey) {
+ auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ if (group.get() == nullptr) {
+ return "Error creating EC group by curve name";
+ }
+ auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+ if (EC_POINT_oct2point(group.get(), point.get(), pubKey.data(), pubKey.size(), nullptr) != 1) {
+ return "Error decoding publicKey";
+ }
+ BIGNUM_Ptr x(BN_new());
+ BIGNUM_Ptr y(BN_new());
+ BN_CTX_Ptr ctx(BN_CTX_new());
+ if (!ctx.get()) return "Failed to create BN_CTX instance";
+
+ if (!EC_POINT_get_affine_coordinates_GFp(group.get(), point.get(), x.get(), y.get(),
+ ctx.get())) {
+ return "Failed to get affine coordinates from ECPoint";
+ }
+ bytevec pubX(kP256AffinePointSize);
+ bytevec pubY(kP256AffinePointSize);
+ if (BN_bn2binpad(x.get(), pubX.data(), kP256AffinePointSize) != kP256AffinePointSize) {
+ return "Error in converting absolute value of x coordinate to big-endian";
+ }
+ if (BN_bn2binpad(y.get(), pubY.data(), kP256AffinePointSize) != kP256AffinePointSize) {
+ return "Error in converting absolute value of y coordinate to big-endian";
+ }
+ return std::make_tuple(std::move(pubX), std::move(pubY));
+}
+
+ErrMsgOr<std::tuple<bytevec, bytevec>> generateEc256KeyPair() {
+ auto ec_key = EC_KEY_Ptr(EC_KEY_new());
+ if (ec_key.get() == nullptr) {
+ return "Failed to allocate ec key";
+ }
+
+ auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ if (group.get() == nullptr) {
+ return "Error creating EC group by curve name";
+ }
+
+ if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+ EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+ return "Error generating key";
+ }
+
+ auto privKey = ecKeyGetPrivateKey(ec_key.get());
+ if (!privKey) return privKey.moveMessage();
+
+ auto pubKey = ecKeyGetPublicKey(ec_key.get());
+ if (!pubKey) return pubKey.moveMessage();
+
+ return std::make_tuple(pubKey.moveValue(), privKey.moveValue());
+}
+
+ErrMsgOr<std::tuple<bytevec, bytevec>> generateX25519KeyPair() {
+ /* Generate X25519 key pair */
+ bytevec pubKey(X25519_PUBLIC_VALUE_LEN);
+ bytevec privKey(X25519_PRIVATE_KEY_LEN);
+ X25519_keypair(pubKey.data(), privKey.data());
+ return std::make_tuple(std::move(pubKey), std::move(privKey));
+}
+
+ErrMsgOr<std::tuple<bytevec, bytevec>> generateED25519KeyPair() {
+ /* Generate ED25519 key pair */
+ bytevec pubKey(ED25519_PUBLIC_KEY_LEN);
+ bytevec privKey(ED25519_PRIVATE_KEY_LEN);
+ ED25519_keypair(pubKey.data(), privKey.data());
+ return std::make_tuple(std::move(pubKey), std::move(privKey));
+}
+
+ErrMsgOr<std::tuple<bytevec, bytevec>> generateKeyPair(int32_t supportedEekCurve, bool isEek) {
+ switch (supportedEekCurve) {
+ case RpcHardwareInfo::CURVE_25519:
+ if (isEek) {
+ return generateX25519KeyPair();
+ }
+ return generateED25519KeyPair();
+ case RpcHardwareInfo::CURVE_P256:
+ return generateEc256KeyPair();
+ default:
+ return "Unknown EEK Curve.";
+ }
+}
+
+ErrMsgOr<bytevec> constructCoseKey(int32_t supportedEekCurve, const bytevec& eekId,
+ const bytevec& pubKey) {
+ CoseKeyType keyType;
+ CoseKeyAlgorithm algorithm;
+ CoseKeyCurve curve;
+ bytevec pubX;
+ bytevec pubY;
+ switch (supportedEekCurve) {
+ case RpcHardwareInfo::CURVE_25519:
+ keyType = OCTET_KEY_PAIR;
+ algorithm = (eekId.empty()) ? EDDSA : ECDH_ES_HKDF_256;
+ curve = (eekId.empty()) ? ED25519 : cppcose::X25519;
+ pubX = pubKey;
+ break;
+ case RpcHardwareInfo::CURVE_P256: {
+ keyType = EC2;
+ algorithm = (eekId.empty()) ? ES256 : ECDH_ES_HKDF_256;
+ curve = P256;
+ auto affineCoordinates = getAffineCoordinates(pubKey);
+ if (!affineCoordinates) return affineCoordinates.moveMessage();
+ std::tie(pubX, pubY) = affineCoordinates.moveValue();
+ } break;
+ default:
+ return "Unknown EEK Curve.";
+ }
+ cppbor::Map coseKey = cppbor::Map()
+ .add(CoseKey::KEY_TYPE, keyType)
+ .add(CoseKey::ALGORITHM, algorithm)
+ .add(CoseKey::CURVE, curve)
+ .add(CoseKey::PUBKEY_X, pubX);
+
+ if (!pubY.empty()) coseKey.add(CoseKey::PUBKEY_Y, pubY);
+ if (!eekId.empty()) coseKey.add(CoseKey::KEY_ID, eekId);
+
+ return coseKey.canonicalize().encode();
+}
bytevec kTestMacKey(32 /* count */, 0 /* byte value */);
@@ -39,7 +205,17 @@
return retval;
}
-ErrMsgOr<EekChain> generateEekChain(size_t length, const bytevec& eekId) {
+ErrMsgOr<cppbor::Array> constructCoseSign1(int32_t supportedEekCurve, const bytevec& key,
+ const bytevec& payload, const bytevec& aad) {
+ if (supportedEekCurve == RpcHardwareInfo::CURVE_P256) {
+ return constructECDSACoseSign1(key, {} /* protectedParams */, payload, aad);
+ } else {
+ return cppcose::constructCoseSign1(key, payload, aad);
+ }
+}
+
+ErrMsgOr<EekChain> generateEekChain(int32_t supportedEekCurve, size_t length,
+ const bytevec& eekId) {
if (length < 2) {
return "EEK chain must contain at least 2 certs.";
}
@@ -48,59 +224,62 @@
bytevec prev_priv_key;
for (size_t i = 0; i < length - 1; ++i) {
- bytevec pub_key(ED25519_PUBLIC_KEY_LEN);
- bytevec priv_key(ED25519_PRIVATE_KEY_LEN);
-
- ED25519_keypair(pub_key.data(), priv_key.data());
+ auto keyPair = generateKeyPair(supportedEekCurve, false);
+ if (!keyPair) keyPair.moveMessage();
+ auto [pub_key, priv_key] = keyPair.moveValue();
// The first signing key is self-signed.
if (prev_priv_key.empty()) prev_priv_key = priv_key;
- auto coseSign1 = constructCoseSign1(prev_priv_key,
- cppbor::Map() /* payload CoseKey */
- .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
- .add(CoseKey::ALGORITHM, EDDSA)
- .add(CoseKey::CURVE, ED25519)
- .add(CoseKey::PUBKEY_X, pub_key)
- .canonicalize()
- .encode(),
- {} /* AAD */);
+ auto coseKey = constructCoseKey(supportedEekCurve, {}, pub_key);
+ if (!coseKey) return coseKey.moveMessage();
+
+ auto coseSign1 =
+ constructCoseSign1(supportedEekCurve, prev_priv_key, coseKey.moveValue(), {} /* AAD */);
if (!coseSign1) return coseSign1.moveMessage();
eekChain.add(coseSign1.moveValue());
prev_priv_key = priv_key;
}
+ auto keyPair = generateKeyPair(supportedEekCurve, true);
+ if (!keyPair) keyPair.moveMessage();
+ auto [pub_key, priv_key] = keyPair.moveValue();
- bytevec pub_key(X25519_PUBLIC_VALUE_LEN);
- bytevec priv_key(X25519_PRIVATE_KEY_LEN);
- X25519_keypair(pub_key.data(), priv_key.data());
+ auto coseKey = constructCoseKey(supportedEekCurve, eekId, pub_key);
+ if (!coseKey) return coseKey.moveMessage();
- auto coseSign1 = constructCoseSign1(prev_priv_key,
- cppbor::Map() /* payload CoseKey */
- .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
- .add(CoseKey::KEY_ID, eekId)
- .add(CoseKey::ALGORITHM, ECDH_ES_HKDF_256)
- .add(CoseKey::CURVE, cppcose::X25519)
- .add(CoseKey::PUBKEY_X, pub_key)
- .canonicalize()
- .encode(),
- {} /* AAD */);
+ auto coseSign1 =
+ constructCoseSign1(supportedEekCurve, prev_priv_key, coseKey.moveValue(), {} /* AAD */);
if (!coseSign1) return coseSign1.moveMessage();
eekChain.add(coseSign1.moveValue());
+ if (supportedEekCurve == RpcHardwareInfo::CURVE_P256) {
+ // convert ec public key to x and y co-ordinates.
+ auto affineCoordinates = getAffineCoordinates(pub_key);
+ if (!affineCoordinates) return affineCoordinates.moveMessage();
+ auto [pubX, pubY] = affineCoordinates.moveValue();
+ pub_key.clear();
+ pub_key.insert(pub_key.begin(), pubX.begin(), pubX.end());
+ pub_key.insert(pub_key.end(), pubY.begin(), pubY.end());
+ }
+
return EekChain{eekChain.encode(), pub_key, priv_key};
}
-bytevec getProdEekChain() {
- bytevec prodEek;
- prodEek.reserve(1 + sizeof(kCoseEncodedRootCert) + sizeof(kCoseEncodedGeekCert));
-
- // In CBOR encoding, 0x82 indicates an array of two items
- prodEek.push_back(0x82);
- prodEek.insert(prodEek.end(), std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert));
- prodEek.insert(prodEek.end(), std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert));
-
- return prodEek;
+bytevec getProdEekChain(int32_t supportedEekCurve) {
+ cppbor::Array chain;
+ if (supportedEekCurve == RpcHardwareInfo::CURVE_P256) {
+ chain.add(cppbor::EncodedItem(bytevec(std::begin(kCoseEncodedEcdsa256RootCert),
+ std::end(kCoseEncodedEcdsa256RootCert))));
+ chain.add(cppbor::EncodedItem(bytevec(std::begin(kCoseEncodedEcdsa256GeekCert),
+ std::end(kCoseEncodedEcdsa256GeekCert))));
+ } else {
+ chain.add(cppbor::EncodedItem(
+ bytevec(std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert))));
+ chain.add(cppbor::EncodedItem(
+ bytevec(std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert))));
+ }
+ return chain.encode();
}
ErrMsgOr<bytevec> validatePayloadAndFetchPubKey(const cppbor::Map* payload) {
@@ -139,7 +318,8 @@
}
auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
- if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != EDDSA) {
+ if (!algorithm || !algorithm->asInt() ||
+ (algorithm->asInt()->value() != EDDSA && algorithm->asInt()->value() != ES256)) {
return "Unsupported signature algorithm";
}
@@ -152,15 +332,36 @@
}
bool selfSigned = signingCoseKey.empty();
- auto key = CoseKey::parseEd25519(selfSigned ? *serializedKey : signingCoseKey);
- if (!key) return "Bad signing key: " + key.moveMessage();
-
bytevec signatureInput =
- cppbor::Array().add("Signature1").add(*protectedParams).add(aad).add(*payload).encode();
+ cppbor::Array().add("Signature1").add(*protectedParams).add(aad).add(*payload).encode();
- if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(),
- key->getBstrValue(CoseKey::PUBKEY_X)->data())) {
- return "Signature verification failed";
+ if (algorithm->asInt()->value() == EDDSA) {
+ auto key = CoseKey::parseEd25519(selfSigned ? *serializedKey : signingCoseKey);
+
+ if (!key) return "Bad signing key: " + key.moveMessage();
+
+ if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(),
+ key->getBstrValue(CoseKey::PUBKEY_X)->data())) {
+ return "Signature verification failed";
+ }
+ } else { // P256
+ auto key = CoseKey::parseP256(selfSigned ? *serializedKey : signingCoseKey);
+ if (!key || key->getBstrValue(CoseKey::PUBKEY_X)->empty() ||
+ key->getBstrValue(CoseKey::PUBKEY_Y)->empty()) {
+ return "Bad signing key: " + key.moveMessage();
+ }
+ auto publicKey = key->getEcPublicKey();
+ if (!publicKey) return publicKey.moveMessage();
+
+ auto ecdsaDerSignature = ecdsaCoseSignatureToDer(signature->value());
+ if (!ecdsaDerSignature) return ecdsaDerSignature.moveMessage();
+
+ // convert public key to uncompressed form.
+ publicKey->insert(publicKey->begin(), 0x04);
+
+ if (!verifyEcdsaDigest(publicKey.moveValue(), sha256(signatureInput), *ecdsaDerSignature)) {
+ return "Signature verification failed";
+ }
}
return serializedKey.moveValue();
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index 8697c51..e1c4467 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -14,8 +14,12 @@
* limitations under the License.
*/
+#include "cppbor.h"
+#include "keymaster/cppcose/cppcose.h"
+#include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
#include <android-base/properties.h>
#include <cppbor_parse.h>
+#include <cstdint>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <keymaster/android_keymaster_utils.h>
@@ -23,25 +27,120 @@
#include <keymaster/remote_provisioning_utils.h>
#include <openssl/curve25519.h>
#include <remote_prov/remote_prov_utils.h>
-#include <cstdint>
-#include "cppbor.h"
-#include "keymaster/cppcose/cppcose.h"
namespace aidl::android::hardware::security::keymint::remote_prov {
namespace {
using ::keymaster::KeymasterBlob;
-using ::keymaster::validateAndExtractEekPubAndId;
+using ::keymaster::kStatusFailed;
+using ::keymaster::kStatusInvalidEek;
+using ::keymaster::StatusOr;
using ::testing::ElementsAreArray;
+using byte_view = std::basic_string_view<uint8_t>;
+
+struct KeyInfoEcdsa {
+ CoseKeyCurve curve;
+ byte_view pubKeyX;
+ byte_view pubKeyY;
+
+ bool operator==(const KeyInfoEcdsa& other) const {
+ return curve == other.curve && pubKeyX == other.pubKeyX && pubKeyY == other.pubKeyY;
+ }
+};
+
+// The production root signing key for Google ECDSA P256 Endpoint Encryption Key cert chains.
+inline constexpr uint8_t kEcdsa256GeekRootX[] = {
+ 0xf7, 0x14, 0x8a, 0xdb, 0x97, 0xf4, 0xcc, 0x53, 0xef, 0xd2, 0x64, 0x11, 0xc4, 0xe3, 0x75, 0x1f,
+ 0x66, 0x1f, 0xa4, 0x71, 0x0c, 0x6c, 0xcf, 0xfa, 0x09, 0x46, 0x80, 0x74, 0x87, 0x54, 0xf2, 0xad};
+
+inline constexpr uint8_t kEcdsa256GeekRootY[] = {
+ 0x5e, 0x7f, 0x5b, 0xf6, 0xec, 0xe4, 0xf6, 0x19, 0xcc, 0xff, 0x13, 0x37, 0xfd, 0x0f, 0xa1, 0xc8,
+ 0x93, 0xdb, 0x18, 0x06, 0x76, 0xc4, 0x5d, 0xe6, 0xd7, 0x6a, 0x77, 0x86, 0xc3, 0x2d, 0xaf, 0x8f};
+
+// Hard-coded set of acceptable public COSE_Keys that can act as roots of EEK chains.
+inline constexpr KeyInfoEcdsa kAuthorizedEcdsa256EekRoots[] = {
+ {CoseKeyCurve::P256, byte_view(kEcdsa256GeekRootX, sizeof(kEcdsa256GeekRootX)),
+ byte_view(kEcdsa256GeekRootY, sizeof(kEcdsa256GeekRootY))},
+};
+
+static ErrMsgOr<CoseKey> parseEcdh256(const bytevec& coseKey) {
+ auto key = CoseKey::parse(coseKey, EC2, ECDH_ES_HKDF_256, P256);
+ if (!key) return key;
+
+ auto& pubkey_x = key->getMap().get(cppcose::CoseKey::PUBKEY_X);
+ auto& pubkey_y = key->getMap().get(cppcose::CoseKey::PUBKEY_Y);
+ if (!pubkey_x || !pubkey_y || !pubkey_x->asBstr() || !pubkey_y->asBstr() ||
+ pubkey_x->asBstr()->value().size() != 32 || pubkey_y->asBstr()->value().size() != 32) {
+ return "Invalid P256 public key";
+ }
+
+ return key;
+}
+
+StatusOr<std::tuple<std::vector<uint8_t> /* EEK pubX */, std::vector<uint8_t> /* EEK pubY */,
+ std::vector<uint8_t> /* EEK ID */>>
+validateAndExtractEcdsa256EekPubAndId(bool testMode,
+ const KeymasterBlob& endpointEncryptionCertChain) {
+ auto [item, newPos, errMsg] =
+ cppbor::parse(endpointEncryptionCertChain.begin(), endpointEncryptionCertChain.end());
+ if (!item || !item->asArray()) {
+ return kStatusFailed;
+ }
+ const cppbor::Array* certArr = item->asArray();
+ std::vector<uint8_t> lastPubKey;
+ for (size_t i = 0; i < certArr->size(); ++i) {
+ auto cosePubKey =
+ verifyAndParseCoseSign1(certArr->get(i)->asArray(), lastPubKey, {} /* AAD */);
+ if (!cosePubKey) {
+ return kStatusInvalidEek;
+ }
+ lastPubKey = *std::move(cosePubKey);
+
+ // In prod mode the first pubkey should match a well-known Google public key.
+ if (!testMode && i == 0) {
+ auto parsedPubKey = CoseKey::parse(lastPubKey);
+ if (!parsedPubKey) {
+ return kStatusFailed;
+ }
+ auto curve = parsedPubKey->getIntValue(CoseKey::CURVE);
+ if (!curve) {
+ return kStatusInvalidEek;
+ }
+ auto rawPubX = parsedPubKey->getBstrValue(CoseKey::PUBKEY_X);
+ if (!rawPubX) {
+ return kStatusInvalidEek;
+ }
+ auto rawPubY = parsedPubKey->getBstrValue(CoseKey::PUBKEY_Y);
+ if (!rawPubY) {
+ return kStatusInvalidEek;
+ }
+ KeyInfoEcdsa matcher = {static_cast<CoseKeyCurve>(*curve),
+ byte_view(rawPubX->data(), rawPubX->size()),
+ byte_view(rawPubY->data(), rawPubY->size())};
+ if (std::find(std::begin(kAuthorizedEcdsa256EekRoots),
+ std::end(kAuthorizedEcdsa256EekRoots),
+ matcher) == std::end(kAuthorizedEcdsa256EekRoots)) {
+ return kStatusInvalidEek;
+ }
+ }
+ }
+ auto eek = parseEcdh256(lastPubKey);
+ if (!eek) {
+ return kStatusInvalidEek;
+ }
+ return std::make_tuple(eek->getBstrValue(CoseKey::PUBKEY_X).value(),
+ eek->getBstrValue(CoseKey::PUBKEY_Y).value(),
+ eek->getBstrValue(CoseKey::KEY_ID).value());
+}
TEST(RemoteProvUtilsTest, GenerateEekChainInvalidLength) {
- ASSERT_FALSE(generateEekChain(1, /*eekId=*/{}));
+ ASSERT_FALSE(generateEekChain(RpcHardwareInfo::CURVE_25519, 1, /*eekId=*/{}));
}
TEST(RemoteProvUtilsTest, GenerateEekChain) {
bytevec kTestEekId = {'t', 'e', 's', 't', 'I', 'd', 0};
for (size_t length : {2, 3, 31}) {
- auto get_eek_result = generateEekChain(length, kTestEekId);
+ auto get_eek_result = generateEekChain(RpcHardwareInfo::CURVE_25519, length, kTestEekId);
ASSERT_TRUE(get_eek_result) << get_eek_result.message();
auto& [chain, pubkey, privkey] = *get_eek_result;
@@ -57,7 +156,7 @@
}
TEST(RemoteProvUtilsTest, GetProdEekChain) {
- auto chain = getProdEekChain();
+ auto chain = getProdEekChain(RpcHardwareInfo::CURVE_25519);
auto validation_result = validateAndExtractEekPubAndId(
/*testMode=*/false, KeymasterBlob(chain.data(), chain.size()));
@@ -97,5 +196,57 @@
ASSERT_EQ(json, expected);
}
+TEST(RemoteProvUtilsTest, GenerateEcdsaEekChainInvalidLength) {
+ ASSERT_FALSE(generateEekChain(RpcHardwareInfo::CURVE_P256, 1, /*eekId=*/{}));
+}
+
+TEST(RemoteProvUtilsTest, GenerateEcdsaEekChain) {
+ bytevec kTestEekId = {'t', 'e', 's', 't', 'I', 'd', 0};
+ for (size_t length : {2, 3, 31}) {
+ auto get_eek_result = generateEekChain(RpcHardwareInfo::CURVE_P256, length, kTestEekId);
+ ASSERT_TRUE(get_eek_result) << get_eek_result.message();
+
+ auto& [chain, pubkey, privkey] = *get_eek_result;
+
+ auto validation_result = validateAndExtractEcdsa256EekPubAndId(
+ /*testMode=*/true, KeymasterBlob(chain.data(), chain.size()));
+ ASSERT_TRUE(validation_result.isOk());
+
+ auto& [eekPubX, eekPubY, eekId] = *validation_result;
+ bytevec eekPub;
+ eekPub.insert(eekPub.begin(), eekPubX.begin(), eekPubX.end());
+ eekPub.insert(eekPub.end(), eekPubY.begin(), eekPubY.end());
+ EXPECT_THAT(eekId, ElementsAreArray(kTestEekId));
+ EXPECT_THAT(eekPub, ElementsAreArray(pubkey));
+ }
+}
+
+TEST(RemoteProvUtilsTest, GetProdEcdsaEekChain) {
+ auto chain = getProdEekChain(RpcHardwareInfo::CURVE_P256);
+
+ auto validation_result = validateAndExtractEcdsa256EekPubAndId(
+ /*testMode=*/false, KeymasterBlob(chain.data(), chain.size()));
+ ASSERT_TRUE(validation_result.isOk()) << "Error: " << validation_result.moveError();
+
+ auto& [eekPubX, eekPubY, eekId] = *validation_result;
+
+ auto [geekCert, ignoredNewPos, error] =
+ cppbor::parse(kCoseEncodedEcdsa256GeekCert, sizeof(kCoseEncodedEcdsa256GeekCert));
+ ASSERT_NE(geekCert, nullptr) << "Error: " << error;
+ ASSERT_NE(geekCert->asArray(), nullptr);
+
+ auto& encodedGeekCoseKey = geekCert->asArray()->get(kCoseSign1Payload);
+ ASSERT_NE(encodedGeekCoseKey, nullptr);
+ ASSERT_NE(encodedGeekCoseKey->asBstr(), nullptr);
+
+ auto geek = CoseKey::parse(encodedGeekCoseKey->asBstr()->value());
+ ASSERT_TRUE(geek) << "Error: " << geek.message();
+
+ const std::vector<uint8_t> empty;
+ EXPECT_THAT(eekId, ElementsAreArray(geek->getBstrValue(CoseKey::KEY_ID).value_or(empty)));
+ EXPECT_THAT(eekPubX, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_X).value_or(empty)));
+ EXPECT_THAT(eekPubY, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_Y).value_or(empty)));
+}
+
} // namespace
} // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/sensors/1.0/vts/functional/Android.bp b/sensors/1.0/vts/functional/Android.bp
index 9a92fb3..274cfa7 100644
--- a/sensors/1.0/vts/functional/Android.bp
+++ b/sensors/1.0/vts/functional/Android.bp
@@ -27,6 +27,9 @@
name: "VtsHalSensorsV1_0TargetTest",
cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "VtsHalSensorsV1_0TargetTest.cpp",
+ ],
srcs: [
"SensorsHidlEnvironmentV1_0.cpp",
"VtsHalSensorsV1_0TargetTest.cpp",
diff --git a/sensors/2.0/vts/functional/Android.bp b/sensors/2.0/vts/functional/Android.bp
index cf7c9fa..c4ec866 100644
--- a/sensors/2.0/vts/functional/Android.bp
+++ b/sensors/2.0/vts/functional/Android.bp
@@ -27,6 +27,9 @@
name: "VtsHalSensorsV2_0TargetTest",
cflags: ["-DLOG_TAG=\"sensors_hidl_hal_test\""],
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "VtsHalSensorsV2_0TargetTest.cpp",
+ ],
srcs: [
"VtsHalSensorsV2_0TargetTest.cpp",
],
diff --git a/sensors/common/default/2.X/Sensor.cpp b/sensors/common/default/2.X/Sensor.cpp
index 23c9803..fd701fd 100644
--- a/sensors/common/default/2.X/Sensor.cpp
+++ b/sensors/common/default/2.X/Sensor.cpp
@@ -59,10 +59,10 @@
}
void Sensor::batch(int64_t samplingPeriodNs) {
- if (samplingPeriodNs < mSensorInfo.minDelay * 1000ll) {
- samplingPeriodNs = mSensorInfo.minDelay * 1000ll;
- } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000ll) {
- samplingPeriodNs = mSensorInfo.maxDelay * 1000ll;
+ if (samplingPeriodNs < mSensorInfo.minDelay * 1000LL) {
+ samplingPeriodNs = mSensorInfo.minDelay * 1000LL;
+ } else if (samplingPeriodNs > mSensorInfo.maxDelay * 1000LL) {
+ samplingPeriodNs = mSensorInfo.maxDelay * 1000LL;
}
if (mSamplingPeriodNs != samplingPeriodNs) {
diff --git a/sensors/common/default/2.X/multihal/tests/Android.bp b/sensors/common/default/2.X/multihal/tests/Android.bp
index d8e7ce6..21d1d77 100644
--- a/sensors/common/default/2.X/multihal/tests/Android.bp
+++ b/sensors/common/default/2.X/multihal/tests/Android.bp
@@ -99,6 +99,9 @@
cc_test {
name: "android.hardware.sensors@2.X-halproxy-unit-tests",
+ tidy_timeout_srcs: [
+ "HalProxy_test.cpp",
+ ],
srcs: [
"HalProxy_test.cpp",
"ScopedWakelock_test.cpp",
diff --git a/thermal/2.0/vts/functional/Android.bp b/thermal/2.0/vts/functional/Android.bp
index f26c1af..29dffcb 100644
--- a/thermal/2.0/vts/functional/Android.bp
+++ b/thermal/2.0/vts/functional/Android.bp
@@ -26,6 +26,7 @@
cc_test {
name: "VtsHalThermalV2_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: ["VtsHalThermalV2_0TargetTest.cpp"],
srcs: ["VtsHalThermalV2_0TargetTest.cpp"],
static_libs: [
"android.hardware.thermal@1.0",
diff --git a/tv/Android.mk b/tv/Android.mk
new file mode 100644
index 0000000..d78614a
--- /dev/null
+++ b/tv/Android.mk
@@ -0,0 +1,2 @@
+$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_0.xml))
+$(eval $(call declare-1p-copy-files,hardware/interfaces/tv,tuner_vts_config_1_1.xml))
diff --git a/update-base-files.sh b/update-base-files.sh
index d01847d..bf7f6e4 100755
--- a/update-base-files.sh
+++ b/update-base-files.sh
@@ -45,8 +45,11 @@
-o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_common-base.h \
android.hardware.audio.common@7.0
hidl-gen $options \
- -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base.h \
+ -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base-v7.0.h \
android.hardware.audio@7.0
hidl-gen $options \
+ -o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio-base-v7.1.h \
+ android.hardware.audio@7.1
+hidl-gen $options \
-o $ANDROID_BUILD_TOP/system/media/audio/include/system/audio_effect-base.h \
android.hardware.audio.effect@7.0
diff --git a/vibrator/aidl/OWNERS b/vibrator/aidl/OWNERS
index ae10db6..3982c7b 100644
--- a/vibrator/aidl/OWNERS
+++ b/vibrator/aidl/OWNERS
@@ -1,4 +1,4 @@
# Bug component: 345036
include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
chasewu@google.com
-leungv@google.com
+taikuo@google.com
diff --git a/vibrator/aidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
index 3f328fa..1261870 100644
--- a/vibrator/aidl/vts/Android.bp
+++ b/vibrator/aidl/vts/Android.bp
@@ -13,6 +13,7 @@
"VtsHalTargetTestDefaults",
"use_libaidlvintf_gtest_helper_static",
],
+ tidy_timeout_srcs: ["VtsHalVibratorTargetTest.cpp"],
srcs: ["VtsHalVibratorTargetTest.cpp"],
shared_libs: [
"libbinder",
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
index 6c0ebf7..ebfa164 100644
--- a/wifi/1.0/vts/functional/Android.bp
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -48,6 +48,9 @@
cc_test {
name: "VtsHalWifiV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "wifi_chip_hidl_test.cpp",
+ ],
srcs: [
"wifi_chip_hidl_test.cpp",
"wifi_p2p_iface_hidl_test.cpp",
diff --git a/wifi/hostapd/1.3/vts/functional/Android.bp b/wifi/hostapd/1.3/vts/functional/Android.bp
index 6eceadf..78cd4af 100644
--- a/wifi/hostapd/1.3/vts/functional/Android.bp
+++ b/wifi/hostapd/1.3/vts/functional/Android.bp
@@ -26,6 +26,9 @@
cc_test {
name: "VtsHalWifiHostapdV1_3TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "hostapd_hidl_test.cpp",
+ ],
srcs: [
"hostapd_hidl_test.cpp",
],
diff --git a/wifi/supplicant/1.0/vts/functional/Android.bp b/wifi/supplicant/1.0/vts/functional/Android.bp
index 121117c..2d86822 100644
--- a/wifi/supplicant/1.0/vts/functional/Android.bp
+++ b/wifi/supplicant/1.0/vts/functional/Android.bp
@@ -44,6 +44,9 @@
cc_test {
name: "VtsHalWifiSupplicantV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "supplicant_sta_network_hidl_test.cpp",
+ ],
srcs: [
"supplicant_hidl_test.cpp",
"supplicant_sta_iface_hidl_test.cpp",
@@ -71,6 +74,9 @@
cc_test {
name: "VtsHalWifiSupplicantP2pV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
+ tidy_timeout_srcs: [
+ "supplicant_p2p_iface_hidl_test.cpp",
+ ],
srcs: [
"VtsHalWifiSupplicantP2pV1_0TargetTest.cpp",
"supplicant_p2p_iface_hidl_test.cpp",
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
index b4371fd..4b26ac3 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -34,11 +34,11 @@
package android.hardware.wifi.supplicant;
@VintfStability
interface ISupplicant {
- android.hardware.wifi.supplicant.ISupplicantP2pIface addP2pInterface(in String ifName);
- android.hardware.wifi.supplicant.ISupplicantStaIface addStaInterface(in String ifName);
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pIface addP2pInterface(in String ifName);
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaIface addStaInterface(in String ifName);
android.hardware.wifi.supplicant.DebugLevel getDebugLevel();
- android.hardware.wifi.supplicant.ISupplicantP2pIface getP2pInterface(in String ifName);
- android.hardware.wifi.supplicant.ISupplicantStaIface getStaInterface(in String ifName);
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pIface getP2pInterface(in String ifName);
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaIface getStaInterface(in String ifName);
boolean isDebugShowKeysEnabled();
boolean isDebugShowTimestampEnabled();
android.hardware.wifi.supplicant.IfaceInfo[] listInterfaces();
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index ca7be73..7876d86 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -37,7 +37,7 @@
void addBonjourService(in byte[] query, in byte[] response);
void addGroup(in boolean persistent, in int persistentNetworkId);
void addGroupWithConfig(in byte[] ssid, in String pskPassphrase, in boolean persistent, in int freq, in byte[] peerAddress, in boolean joinExistingGroup);
- android.hardware.wifi.supplicant.ISupplicantP2pNetwork addNetwork();
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pNetwork addNetwork();
void addUpnpService(in int version, in String serviceName);
void cancelConnect();
void cancelServiceDiscovery(in long identifier);
@@ -54,7 +54,7 @@
boolean getEdmg();
android.hardware.wifi.supplicant.P2pGroupCapabilityMask getGroupCapability(in byte[] peerAddress);
String getName();
- android.hardware.wifi.supplicant.ISupplicantP2pNetwork getNetwork(in int id);
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantP2pNetwork getNetwork(in int id);
byte[] getSsid(in byte[] peerAddress);
android.hardware.wifi.supplicant.IfaceType getType();
void invite(in String groupIfName, in byte[] goDeviceAddress, in byte[] peerAddress);
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index ca40379..20c52ac 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -36,7 +36,7 @@
interface ISupplicantStaIface {
int addDppPeerUri(in String uri);
int addExtRadioWork(in String name, in int freqInMhz, in int timeoutInSec);
- android.hardware.wifi.supplicant.ISupplicantStaNetwork addNetwork();
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaNetwork addNetwork();
void addRxFilter(in android.hardware.wifi.supplicant.RxFilterType type);
void cancelWps();
void disconnect();
@@ -48,7 +48,7 @@
android.hardware.wifi.supplicant.KeyMgmtMask getKeyMgmtCapabilities();
byte[] getMacAddress();
String getName();
- android.hardware.wifi.supplicant.ISupplicantStaNetwork getNetwork(in int id);
+ @PropagateAllowBlocking android.hardware.wifi.supplicant.ISupplicantStaNetwork getNetwork(in int id);
android.hardware.wifi.supplicant.IfaceType getType();
android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask getWpaDriverCapabilities();
void initiateAnqpQuery(in byte[] macAddress, in android.hardware.wifi.supplicant.AnqpInfoId[] infoElements, in android.hardware.wifi.supplicant.Hs20AnqpSubtypes[] subTypes);
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
index 2ac1db7..c17289d 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -46,8 +46,8 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_EXISTS|
*/
- ISupplicantP2pIface addP2pInterface(in String ifName);
- ISupplicantStaIface addStaInterface(in String ifName);
+ @PropagateAllowBlocking ISupplicantP2pIface addP2pInterface(in String ifName);
+ @PropagateAllowBlocking ISupplicantStaIface addStaInterface(in String ifName);
/**
* Get the debug level set.
@@ -68,8 +68,8 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_UNKNOWN|
*/
- ISupplicantP2pIface getP2pInterface(in String ifName);
- ISupplicantStaIface getStaInterface(in String ifName);
+ @PropagateAllowBlocking ISupplicantP2pIface getP2pInterface(in String ifName);
+ @PropagateAllowBlocking ISupplicantStaIface getStaInterface(in String ifName);
/**
* Get whether the keys are shown in the debug logs or not.
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 64839e7..5394f49 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -103,7 +103,7 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
- ISupplicantP2pNetwork addNetwork();
+ @PropagateAllowBlocking ISupplicantP2pNetwork addNetwork();
/**
* This command can be used to add a UPNP service.
@@ -320,7 +320,7 @@
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
* |SupplicantStatusCode.FAILURE_NETWORK_UNKNOWN|
*/
- ISupplicantP2pNetwork getNetwork(in int id);
+ @PropagateAllowBlocking ISupplicantP2pNetwork getNetwork(in int id);
/**
* Gets the operational SSID of the device.
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index b48fa04..5cb236f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -86,7 +86,7 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
*/
- ISupplicantStaNetwork addNetwork();
+ @PropagateAllowBlocking ISupplicantStaNetwork addNetwork();
/**
* Send driver command to add the specified RX filter.
@@ -231,7 +231,7 @@
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
* |SupplicantStatusCode.FAILURE_NETWORK_UNKNOWN|
*/
- ISupplicantStaNetwork getNetwork(in int id);
+ @PropagateAllowBlocking ISupplicantStaNetwork getNetwork(in int id);
/**
* Retrieves the type of the network interface.