Remove ToT system/bt code as it has been migrated.
New code location is platform/packages/modules/Bluetooth, removing
ToT in aosp/master to ensure folks do not continue to upload
patches in this project.
BUG: 196026708
Test: TH
Change-Id: I0fe927c913d61f85ca458af0f5620205152dc4db
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 0b4b45a..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright 2016 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.
-#
-
-#
-# Below are some minor deviations from the default Google style to
-# accommodate for handling of the large legacy code base.
-#
-
-BasedOnStyle: Google
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index d26e74c..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-buildtools
-out
-third_party/
-target/
-Cargo.lock
-tags
-cscope.out
-cscope.files
-*.sw?
diff --git a/.style.yapf b/.style.yapf
deleted file mode 100644
index 2b11922..0000000
--- a/.style.yapf
+++ /dev/null
@@ -1,5 +0,0 @@
-[style]
-# http://google.github.io/styleguide/pyguide.html
-based_on_style: google
-indent_width: 4
-column_limit: 120
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 2b49380..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,68 +0,0 @@
-package {
- default_applicable_licenses: ["system_bt_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-// See: http://go/android-license-faq
-license {
- name: "system_bt_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- "SPDX-license-identifier-BSD",
- "SPDX-license-identifier-MIT",
- "legacy_unencumbered",
- ],
- license_text: [
- "NOTICE",
- ],
-}
-
-subdirs = [
- "apex",
- "binder",
- "build",
- "btif",
- "btcore",
- "common",
- "audio_a2dp_hw",
- "audio_bluetooth_hw",
- "audio_hal_interface",
- "audio_hearing_aid_hw",
- "gd",
- "hci",
- "utils",
- "device",
- "stack",
- "osi",
- "embdrv",
- "service",
- "include",
- "main",
- "bta",
- "vendor_libs",
- "test",
- "types",
- "udrv",
- "tools",
- "proto",
-]
-
-filegroup {
- name: "BluetoothTestConfigTemplate",
- srcs: [
- "AndroidTestTemplate.xml",
- ],
-}
diff --git a/AndroidTestTemplate.xml b/AndroidTestTemplate.xml
deleted file mode 100644
index 601be93..0000000
--- a/AndroidTestTemplate.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Runs {MODULE}.">
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-native" />
- <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
- <option name="cleanup" value="true" />
- <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
- <option name="run-command" value="settings put global ble_scan_always_enabled 0" />
- <option name="run-command" value="svc bluetooth disable" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.FolderSaver">
- <option name="device-path" value="/data/vendor/ssrdump" />
- </target_preparer>
- <test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp" />
- <option name="module-name" value="{MODULE}" />
- <option name="run-test-as" value="0" />
- </test>
-</configuration>
diff --git a/BUILD.gn b/BUILD.gn
deleted file mode 100644
index ecbfa07..0000000
--- a/BUILD.gn
+++ /dev/null
@@ -1,231 +0,0 @@
-#
-# Copyright 2015 Google, Inc.
-#
-# 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 is the root build file for GN. GN will start processing by loading this
-# file, and recursively load all dependencies until all dependencies are either
-# resolved or known not to exist (which will cause the build to fail). So if
-# you add a new build file, there must be some path of dependencies from this
-# file to your new one or GN won't know about it.
-
-group("all") {
- deps = [ ":bluetooth" ]
-
- #if (use.test) {
- #deps += [ ":bluetooth_tests" ]
- #}
-}
-
-# This pulls in main/BUILD.gn and all of its dependencies.
-group("bluetooth") {
- deps = [
- "//bt/main:bluetooth",
- "//bt/main:bluetooth-static",
- #"//bt/service:bluetoothtbd",
- ]
-}
-
-# TODO(b/190750167) - Re-enable once we're fully Bazel build
-#if (use.test) {
- #group("bluetooth_tests") {
- #deps = [
- #"//bt/btcore:net_test_btcore",
- #"//bt/common:bluetooth_test_common",
- #"//bt/profile/avrcp:net_test_avrcp",
- #"//bt/service:bluetoothtbd_test",
- #"//bt/stack:net_test_btm_iso",
- #"//bt/types:net_test_types",
-
- ##"//bt/packet:net_test_btpackets",
- #]
- #}
-#}
-
-if (host_cpu == target_cpu && host_os == target_os) {
- group("tools") {
- deps = [
- "//bt/gd/dumpsys/bundler:bluetooth_flatbuffer_bundler",
- "//bt/gd/packet/parser:bluetooth_packetgen",
- ]
- }
-}
-
-if (defined(use.android) && use.android) {
- group("android_bluetooth_tests") {
- deps = [
- "//bt/device:net_test_device",
- "//bt/hci:net_test_hci",
- "//bt/osi:net_test_osi",
- "//bt/test/suite:net_test_bluetooth",
- ]
- }
-}
-
-config("target_defaults") {
- include_dirs = [
- "//bt",
- "//bt/linux_include",
- "//bt/types",
- "//bt/include",
-
- # For flatbuffer generated headers
- "${root_gen_dir}/bt/gd/",
- "${root_gen_dir}/bt/gd/dumpsys/bundler",
- ]
-
- cflags = [
- "-fPIC",
- "-Wno-non-c-typedef-for-linkage",
- "-Wno-unreachable-code-return",
- "-Wno-defaulted-function-deleted",
- "-Wno-gnu-variable-sized-type-not-at-end",
- "-Wno-format-nonliteral",
- "-Wno-inconsistent-missing-override",
- "-Wno-unreachable-code",
- "-Wno-range-loop-construct",
- "-Wno-reorder-init-list",
- "-Wno-unused-function",
- "-Wno-unused-result",
- "-Wno-unused-variable",
- "-Wno-unused-const-variable",
- "-Wno-format",
- "-Wno-pessimizing-move",
- "-Wno-unknown-warning-option",
- "-Wno-final-dtor-non-final-class",
- ]
-
- cflags_cc = [
- "-std=c++17",
- ]
-
- defines = [
- "HAS_NO_BDROID_BUILDCFG",
- "OS_GENERIC",
- "OS_LINUX_GENERIC",
- "TARGET_FLOSS",
- "EXPORT_SYMBOL=__attribute__((visibility(\"default\")))",
- "FALLTHROUGH_INTENDED=[[clang::fallthrough]]",
- ]
-
- # If not configured as a dynamic library, default to static library
- if (!(defined(use.bt_dynlib) && use.bt_dynlib)) {
- defines += [
- "STATIC_LIBBLUETOOTH",
- ]
- }
-
- if (!(defined(use.bt_nonstandard_codecs) && use.bt_nonstandard_codecs)) {
- defines += [ "EXCLUDE_NONSTANDARD_CODECS" ]
- }
-
- configs = [ ":external_libchrome" ]
-}
-
-group("libbt-platform-protos-lite") {
- deps = [
- "//external/proto_logging/stats/enums/bluetooth:libbt-platform-protos-lite",
- ]
-}
-
-# Configurations to use as dependencies for GN build
-config("external_gtest") {
- configs = [
- ":pkg_gtest",
- ":pkg_gmock",
- ]
-}
-
-config("external_gtest_main") {
- configs = [ ":pkg_gtest_main" ]
-}
-
-config("external_gmock_main") {
- configs = [ ":pkg_gmock_main" ]
-}
-
-config("external_libchrome") {
- configs = [ ":pkg_libchrome" ]
-}
-
-config("external_modp_b64") {
- configs = [ ":pkg_modp_b64" ]
-}
-
-config("external_tinyxml2") {
- configs = [ ":pkg_tinyxml2" ]
-}
-
-config("external_flatbuffers") {
- lib_dirs = [ "${libdir}" ]
-
- libs = [ "flatbuffers" ]
-}
-
-# Package configurations to extract dependencies from env
-pkg_config("pkg_gtest") {
- pkg_deps = [ "gtest" ]
-}
-
-pkg_config("pkg_gtest_main") {
- pkg_deps = [ "gtest_main" ]
-}
-
-pkg_config("pkg_gmock") {
- pkg_deps = [ "gmock" ]
-}
-
-pkg_config("pkg_gmock_main") {
- pkg_deps = [ "gmock_main" ]
-}
-
-pkg_config("pkg_libchrome") {
- pkg_deps = [ "libchrome" ]
-}
-
-pkg_config("pkg_modp_b64") {
- pkg_deps = [ "libmodp_b64" ]
-}
-
-pkg_config("pkg_tinyxml2") {
- pkg_deps = [ "tinyxml2" ]
-}
-
-# To use non-standard codecs (i.e. ldac, aac, aptx), set this use flag when
-# building. These codecs may have licensing issues that need to be resolved
-# first.
-if (defined(use.bt_nonstandard_codecs) && use.bt_nonstandard_codecs) {
- config("external_aac") {
- configs = [ ":pkg_aac" ]
- }
-
- pkg_config("pkg_aac") {
- pkg_deps = [ "fdk-aac" ]
- }
-
- config("external_libldac") {
- configs = [
- ":pkg_libldacBT_enc",
- ":pkg_libldacBT_abr",
- ]
- }
-
- pkg_config("pkg_libldacBT_enc") {
- pkg_deps = [ "ldacBT-enc" ]
- }
-
- pkg_config("pkg_libldacBT_abr") {
- pkg_deps = [ "ldacBT-abr" ]
- }
-}
diff --git a/Cargo.toml b/Cargo.toml
deleted file mode 100644
index 134dd9f..0000000
--- a/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright 2021 Google, Inc.
-#
-# 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.
-
-[workspace]
-
-members = [
- "gd/rust/shim",
- "gd/rust/topshim",
- "gd/rust/linux/mgmt",
- "gd/rust/linux/service",
- "gd/rust/linux/client",
-]
diff --git a/CleanSpec.mk b/CleanSpec.mk
deleted file mode 100644
index 8be8c0a..0000000
--- a/CleanSpec.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2007 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.
-#
-
-# If you don't need to do a full clean build but would like to touch
-# a file or delete some intermediate files, add a clean step to the end
-# of the list. These steps will only be run once, if they haven't been
-# run before.
-#
-# E.g.:
-# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
-# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
-#
-# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
-# files that are missing or have been moved.
-#
-# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
-# Use $(OUT_DIR) to refer to the "out" directory.
-#
-# If you need to re-do something that's already mentioned, just copy
-# the command and add it to the bottom of the list. E.g., if a change
-# that you made last week required touching a file and a change you
-# made today requires touching the same file, just copy the old
-# touch step and add it to the end of the list.
-#
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
-
-# For example:
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
-#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
-#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
-#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
-
-# Start of Clean Step list:
-$(call add-clean-step, find $(OUT_DIR) -type f -iname "*blue*" -print0 | xargs -0 rm -f)
-$(call add-clean-step, find $(OUT_DIR) -type f -iname "*bdroid*" -print0 | xargs -0 rm -f)
-
-# ************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
diff --git a/EventLogTags.logtags b/EventLogTags.logtags
deleted file mode 100644
index dc1d239..0000000
--- a/EventLogTags.logtags
+++ /dev/null
@@ -1,38 +0,0 @@
-# The entries in this file map a sparse set of log tag numbers to tag names.
-# This is installed on the device, in /system/etc, and parsed by logcat.
-#
-# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
-# negative values alone for now.)
-#
-# Tag names are one or more ASCII letters and numbers or underscores, i.e.
-# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
-# impacts log readability, the latter makes regex searches more annoying).
-#
-# Tag numbers and names are separated by whitespace. Blank lines and lines
-# starting with '#' are ignored.
-#
-# Optionally, after the tag names can be put a description for the value(s)
-# of the tag. Description are in the format
-# (<name>|data type[|data unit])
-# Multiple values are separated by commas.
-#
-# The data type is a number from the following values:
-# 1: int
-# 2: long
-# 3: string
-# 4: list
-#
-# The data unit is a number taken from the following list:
-# 1: Number of objects
-# 2: Number of bytes
-# 3: Number of milliseconds
-# 4: Number of allocations
-# 5: Id
-# 6: Percent
-# Default value for data of type int/long is 2 (bytes).
-#
-# TODO: generate ".java" and ".h" files with integer constants from this file.
-
-1010000 bt_hci_timeout (opcode|1)
-1010001 bt_config_source (opcode|1)
-1010002 bt_hci_unknown_type (hci_type|1)
diff --git a/METADATA b/METADATA
deleted file mode 100644
index d97975c..0000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
- license_type: NOTICE
-}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index d645695..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
diff --git a/OWNERS b/OWNERS
deleted file mode 100644
index e83a055..0000000
--- a/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-set noparent
-
-# Temporary block for b/196026708
-baligh@google.com
diff --git a/OWNERS_automotive b/OWNERS_automotive
deleted file mode 100644
index db6814a..0000000
--- a/OWNERS_automotive
+++ /dev/null
@@ -1,2 +0,0 @@
-# Temporary block for b/196026708
-baligh@google.com
diff --git a/OWNERS_chromeos b/OWNERS_chromeos
deleted file mode 100644
index db6814a..0000000
--- a/OWNERS_chromeos
+++ /dev/null
@@ -1,2 +0,0 @@
-# Temporary block for b/196026708
-baligh@google.com
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
deleted file mode 100644
index 04963df..0000000
--- a/PREUPLOAD.cfg
+++ /dev/null
@@ -1,13 +0,0 @@
-[Options]
-ignore_merged_commits = true
-
-[Builtin Hooks]
-clang_format = true
-rustfmt = true
-
-[Builtin Hooks Options]
-rustfmt = --config-path=rustfmt.toml
-
-[Hook Scripts]
-aosp_first = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} ".*$"
-yapf_hook = ./tools/scripts/yapf_checker.py
diff --git a/README.md b/README.md
index 44ceb71..8df253b 100644
--- a/README.md
+++ b/README.md
@@ -1,180 +1 @@
-# Fluoride Bluetooth stack
-
-## Building and running on AOSP
-Just build AOSP - Fluoride is there by default.
-
-## Building and running on Linux
-
-Instructions for a Debian based distribution:
-* Debian Bullseye or newer
-* Ubuntu 20.10 or newer
-* Clang-11 or Clang-12
-* Flex 2.6.x
-* Bison 3.x.x (tested with 3.0.x, 3.2.x and 3.7.x)
-
-You'll want to download some pre-requisite packages as well. If you're currently
-configured for AOSP development, you should have most required packages.
-Otherwise, you can use the following apt-get list or use the `--run-bootstrap`
-option on `build.py` (see below) to get a list of packages missing on your
-system:
-
-```sh
-sudo apt-get install repo git-core gnupg flex bison gperf build-essential \
- zip curl zlib1g-dev gcc-multilib g++-multilib \
- x11proto-core-dev libx11-dev libncurses5 \
- libgl1-mesa-dev libxml2-utils xsltproc unzip liblz4-tool libssl-dev \
- libc++-dev libevent-dev \
- flatbuffers-compiler libflatbuffers1 openssl \
- libflatbuffers-dev libtinyxml2-dev \
- libglib2.0-dev libevent-dev libnss3-dev libdbus-1-dev \
- libprotobuf-dev ninja-build generate-ninja protobuf-compiler \
- libre2-9 debmake \
- llvm libc++abi-dev
-```
-
-You will also need a recent-ish version of Rust and Cargo. Please follow the
-instructions on [Rustup](https://rustup.rs/) to install a recent version.
-
-### Download source
-
-```sh
-mkdir ~/fluoride
-cd ~/fluoride
-git clone https://android.googlesource.com/platform/system/bt
-```
-
-### Using --run-bootstrap on build.py
-
-`build.py` is the helper script used to build Fluoride for Linux (i.e. Floss).
-It accepts a `--run-bootstrap` option that will set up your build staging
-directory and also make sure you have all required system packages to build
-(should work on Debian and Ubuntu). You will still need to build some unpackaged
-dependencies (like libchrome, modp_b64, googletest, etc).
-
-To use it:
-```sh
-./build.py --run-bootstrap
-```
-
-This will install your bootstrapped build environment to `~/.floss`. If you want
-to change this, just pass in `--bootstrap-dir` to the script.
-
-### Build dependencies
-
-The following third-party dependencies are necessary but currently unavailable
-via a package manager. You may have to build these from source and install them
-to your local environment.
-
-* libchrome
-* modp_b64
-
-We provide a script to produce debian packages for those components. Please
-see the instructions in build/dpkg/README.txt for more details.
-
-```sh
-cd build/dpkg
-mkdir -p outdir/{modp_b64,libchrome}
-
-# Build and install modp_b64
-pushd modp_b64
-./gen-src-pkg.sh $(readlink -f ../outdir/modp_b64)
-popd
-sudo dpkg -i outdir/modp_b64/*.deb
-
-# Build and install libchrome
-pushd libchrome
-./gen-src-pkg.sh $(readlink -f ../outdir/libchrome)
-popd
-sudo dpkg -i outdir/libchrome/*.deb
-```
-
-The googletest packages provided by Debian/Ubuntu (libgmock-dev and
-libgtest-dev) do not provide pkg-config files, so you can build your own
-googletest using the steps below:
-
-```sh
-git clone https://github.com/google/googletest.git -b release-1.10.0
-cd googletest # Main directory of the cloned repository.
-mkdir build # Create a directory to hold the build output.
-cd build
-cmake .. # Generate native build scripts for GoogleTest.
-sudo make install -DCMAKE_INSTALL_PREFIX=/usr
-
-# Optional steps if pkgconfig isn't installed to desired location
-# Modify the source (/usr/lib/x86_64-linux-gnu) and target (/usr/lib) based on
-# your local installation.
-for f in $(ls /usr/lib/x86_64-linux-gnu/pkgconfig/{gtest,gmock}*); do \
- ln -sf $f /usr/lib/pkgconfig/$(basename $f);
-done
-```
-
-### Rust dependencies
-
-**Note**: Handled by `--run-bootstrap` option.
-
-Run the following to install Rust dependencies:
-```
-cargo install cxxbridge-cmd
-```
-
-### Stage your build environment
-
-**Note**: Handled by `--run-bootstrap` option.
-
-For host build, we depend on a few other repositories:
-* [Platform2](https://chromium.googlesource.com/chromiumos/platform2/)
-* [Rust crates](https://chromium.googlesource.com/chromiumos/third_party/rust_crates/)
-* [Proto logging](https://android.googlesource.com/platform/frameworks/proto_logging/)
-
-Clone these all somewhere and create your staging environment.
-```sh
-export STAGING_DIR=path/to/your/staging/dir
-mkdir ${STAGING_DIR}
-mkdir -p ${STAGING_DIR}/external
-ln -s $(readlink -f ${PLATFORM2_DIR}/common-mk) ${STAGING_DIR}/common-mk
-ln -s $(readlink -f ${PLATFORM2_DIR}/.gn) ${STAGING_DIR}/.gn
-ln -s $(readlink -f ${RUST_CRATE_DIR}) ${STAGING_DIR}/external/rust
-ln -s $(readlink -f ${PROTO_LOG_DIR}) ${STAGING_DIR}/external/proto_logging
-```
-
-### Build
-
-We provide a build script to automate building assuming you've staged your build
-environment already as above. At this point, make sure you have all the
-pre-requisites installed (i.e. bootstrap option and other dependencies above) or
-you will see failures. In addition, you may need to set a `--libdir=` if your
-libraries are not stored in `/usr/lib` by default.
-
-
-```sh
-./build.py
-```
-
-This will build all targets to the output directory at `--bootstrap-dir` (which
-defaults to `~/.floss`). You can also build each stage separately (if you want
-to iterate on something specific):
-
-* prepare - Generate the GN rules
-* tools - Generate host tools
-* rust - Build the rust portion of the build
-* main - Build all the C/C++ code
-* test - Build all targets and run the tests
-* clean - Clean the output directory
-
-You can choose to run only a specific stage by passing an arg via `--target`.
-
-Currently, Rust builds are a separate stage that uses Cargo to build. See
-[gd/rust/README.md](gd/rust/README.md) for more information. If you are
-iterating on Rust code and want to add new crates, you may also want to use the
-`--no-vendored-rust` option (which will let you use crates.io instead of using
-a pre-populated vendored crates repo).
-
-### Run
-
-By default on Linux, we statically link libbluetooth so you can just run the
-binary directly. By default, it will try to run on hci0 but you can pass it
---hci=N, where N corresponds to /sys/class/bluetooth/hciN.
-
-```sh
-$OUTPUT_DIR/debug/btadapterd --hci=$HCI INIT_gd_hci=true
-```
+This code has been migrated to platform/packages/modules/Bluetooth
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100755
index 69a0709..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "postsubmit" : [
- {
- "name" : "bluetooth_test_common"
- },
- {
- "name" : "bluetoothtbd_test"
- },
- {
- "name" : "net_test_audio_a2dp_hw"
- },
- {
- "name" : "net_test_avrcp"
- },
- {
- "name" : "net_test_btcore"
- },
- {
- "name" : "net_test_btif"
- },
- {
- "name" : "net_test_btif_profile_queue"
- },
- {
- "name" : "net_test_btpackets"
- },
- {
- "name" : "net_test_device"
- },
- {
- "name" : "net_test_eatt"
- },
- {
- "name" : "net_test_hci"
- },
- {
- "name" : "net_test_performance"
- },
- {
- "name" : "net_test_stack"
- },
- {
- "name" : "net_test_stack_ad_parser"
- },
- {
- "name" : "net_test_stack_multi_adv"
- },
- {
- "name" : "net_test_stack_rfcomm"
- },
- {
- "name" : "net_test_stack_smp"
- },
- {
- "name" : "net_test_types"
- }
- ],
- "presubmit" : [
- {
- "name" : "net_test_hf_client_add_record"
- },
- {
- "name" : "net_test_btif_hf_client_service"
- },
- {
- "name" : "net_test_stack_btm"
- }
- ]
-}
diff --git a/apex/Android.bp b/apex/Android.bp
deleted file mode 100644
index c206dca..0000000
--- a/apex/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 "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-apex {
- name: "com.android.bluetooth.updatable",
- enabled: false,
-
- manifest: "apex_manifest.json",
-
- native_shared_libs: [
- "libbluetooth_jni",
- "libbluetooth"
- ],
- apps: ["Bluetooth"],
-
- compile_multilib: "both",
-
- key: "com.android.bluetooth.updatable.key",
- certificate: ":com.android.bluetooth.updatable.certificate",
-}
-
-apex_key {
- name: "com.android.bluetooth.updatable.key",
- public_key: "com.android.bluetooth.updatable.avbpubkey",
- private_key: "com.android.bluetooth.updatable.pem",
-}
-
-android_app_certificate {
- name: "com.android.bluetooth.updatable.certificate",
- certificate: "com.android.bluetooth.updatable",
-}
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
deleted file mode 100644
index 11f4d0b..0000000
--- a/apex/apex_manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "name": "com.android.bluetooth.updatable",
- "version": 2
-}
diff --git a/apex/com.android.bluetooth.updatable.avbpubkey b/apex/com.android.bluetooth.updatable.avbpubkey
deleted file mode 100644
index 969211f..0000000
--- a/apex/com.android.bluetooth.updatable.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/com.android.bluetooth.updatable.pem b/apex/com.android.bluetooth.updatable.pem
deleted file mode 100644
index dcbd2be..0000000
--- a/apex/com.android.bluetooth.updatable.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEA1+wvczWqiosiDtTkbA3nEOUz1fjZhfsWGT5blDOTZFEq4mP6
-heTlEwEc/kYy9UTtG3zrzGtGR+6JueffuI9exjvsVWBdAZBcmb5cgJAkZkpqOMjl
-sS0nHLHtZUWaniASFJnoqFZPFsqR5f5nXCcDUQH2ltVV5+lApxnMgldgvn8nEAYv
-YvOT+N4zwkYv/iYp+/jRv3XRsDehJf62iLhXZYkJdHtqGSq52W5OZFSN61QLd1Zd
-t+8zOQE+nshagnbFdJXXZpITZ/WOAQUzuM9pZzh155yPXhzlE0dB532qUkwCUmcv
-EK09FkS/wEy2Dc9aduAvtRIiS4MobawZSRvq+I/MZp68ioxbdDAW3buB9URBC0k8
-eq7z4TaRgYY2QtQdRecyCP26GeZPP/kz9gYIAslGTY3+B58tRMYp9YwWnQOl37Jj
-2vTg9hmHFRo7gaB0gPj+YORtFhILppx/hu9ASklWV5X6vVqoExM3SFnb05LEGwmc
-Orgp0iKGFfqpRH796Yk2gu+qnupVoLyHRKeq2WKpDlxekRNF+hF27BXlDZMFR5eu
-JYwK7fAq2WndlUz0t2bFSsmTr/S0brr4938F2UUMObQqVr/ynwjE368ADPrihwZX
-gsjW/xXFwW/ftU1BSvdz+Ps+OkoqfM3ac3hTVjT06jtXOk9EJZIqgKUWmTcCAwEA
-AQKCAgEAgF+XxnN9tWkLEq5YMDYDzvO2YdzV1uZ1OQTuBaq0Usw/JuIyLDDuUOI0
-jqjF2zTjk5gtyRdubY3QrIrDZEM5Ibq2w/vK0Ac4Rt/6tyT7vyU3ChPHHBOwUUsn
-zTIYvzJqDX2D6bGGzBIbtBYQ9aTsP9le9kZYEM2I9tBL2qKAjkGiw9AplDclHq1d
-MH/yQLQH+hrw+VffF1m7oY9Sju6qZ1+WE37ckaHpZPBEAzqSNft95bGffp/kYFvx
-Ew4jYbWjp7D+o6jtiL1hdBHXsmT+UbQrxUw7oMSlHVUcRblc7hjquHtIbC3TR84Q
-AxCYnJVPP6YCNzFU2nhcLPhJAEJs68stR2JB6lFD/RLfESmkgGieobxV4UMHYlMc
-rTZgIwhpKTDAMDmBmfZdRVYa7n3euCHZ/dMiLLkMeeXqHpfZ4kDWfUo89DfRdgp2
-XLb0MZ+RriZDZS7QY7IN0aW9M2UBfNtK9XVuXmMhE7haYtEVxp5UZX2IUicYvi6j
-pko/oyCQJjEBQopYYU1to8izGpPsxARLSl3mn6RoRTCaHmXZniu6HztBzuf6cxH4
-Ze78tHKN/PnSOehGAiLGxVAjlah/D6rxrnmDnvwbF0dUSqSiSho78X2JcpeC+jJz
-XbfassFqvKxsZzEz8ZKdciGydcRJHv5kk0Yf6DDZBXeICId+kqECggEBAPRSpBu7
-3hqT75LIXrE7OHd93Zn61+l/ww0K/s8TSuIVYOZjYMSEUXjVJHsm2DHxaMb7/47P
-IR+LU9zcRuNMa6o0e3w9pACXl/VVbECY5F8oNTYa8tkZA1C4nhWjKJiCGsCSzHMA
-D3+tcwGb2sFJe8UYAkyoZozh4rSxphTLS1OgvQ/T24ofJ5afPT4ZX/vTcs4P4skK
-ScwCG9mBsAw03DONVvj7fWTLQLEOrIBwQkWemlTUU3+gWYXzDi+7Ab7oiCNVYCNc
-yMCv05XpZFW1/nOGXgj1z1EAyj09G8BSgnTH47n/7pmHzSVRxTWK3px5dQfDOoEd
-wae5bkGMrrsHSHsCggEBAOI+D0Ebw+RmhuiMGREE/v5VhSCODK0qfyyN5LIpIp8j
-7O1nLwg8uXljHSA6PIuZJptVvSgaKncpjmVLp8LHPEphFV1fH1lglm9hXUjZWmYL
-AONVuma/n6E5x5BbD2dLP4H8EXsZdHmPYaSOB8nD4k1FeMgBNSzCjW62GmT5WUbH
-ii72TTrzb0ytGoX6qEIlFjUL3ivNmywyVA4tHSHJmyuJNpHrLB+DaIUSnCK6VJWG
-a6aJlGDXcCFGJX+YAxL/wAXfySv5/fRd+RUQgNXagOzQ9AZFgERebyc77s2+zKOq
-o7emvQ2sNhGxw6nWEC0KFUSc7UkJ/kKrLwvHDc+gm3UCggEBAICqOLRGRlv2xjal
-gICTMFR1G0tot2XHG5/1x2Sjw062dXY+pYo4KHOaw4B7X2VFvaj0souxdr8W744j
-Ds3Kw/Q5eUJfb8vECYlwd/a4zaNzGDqrDHLZ4k4TO2UnrExMT+xUIoj5YjAZ1rPl
-MNmTajPMRgG6uW690lbYKx9ORBgBUS9RoY7mg0GmEGlwkYSbwRzVbtfyrBRck/AC
-hQSYndIkP8YVIt7+zs2vbZaiB7SEJsA/pM1UU3DgI/ts3yl7aZ456swUo8AdmC6d
-X3Jnyl1qSIEtegUthlOjp8arbPo0/i9IoY2G37kki9d7j2oV6FSzMk8mrYI3e+HX
-RXlHB5sCggEAJtRf6dzKEjlGjkL9Sl6BJUWoQ54drtrMWOlBhxJoTsfrshMzj0Zc
-zuij5xQXsB3o8mAUxv02rJ0FQ31onZV0U4+2CwB4cO6S4yrix84GJd1dmabtBxV8
-YD96cNwwGJphm/2XQnlr9DEXoRZ/X7Gu9XQm9qy+Y6BAhe/bN9lT6UH2BXlgZ+2/
-/Hj5RGVw22liFlijGQGA0GUS6Bv2FAZ2C1LRetnSCNaU6cH36j3wpnkboMmcHcLc
-C9nuNafxXyFl45w0+sc9PuOiDGt4sTt/RSXXu/vRt+o9SY6PveAxXyW6U5rad65G
-2WKZIl0LCa/hVpVYZGDCss6OlIblZ+04wQKCAQAPnQZKHYRAbMwf3hISiD3HVLQO
-ZRegAF1Jxfw19jSAzAuC4KTChilS2ta5N+ppigbdrXmMhQNloX3dNWf5Qfn83Wk6
-/1oVsZSGL0GAOXYfMFSB6d+o3V0NTCf3SDfV/Yk38ffRp0J1GIV5BOveS6vQICPV
-yGr7AjZzXdqkSkQNsn2Wy4Z9kWQyDBmCkqYBbTn6gw+1Qlg028q9YClQFRrANDx4
-VuORCKP2BCoYexICU+awXao/JtgO1fSBnD52vKjGYaaPnqKbYtDwBBo9MaQ1VSFC
-Jj9v2jUoc0j1uEO13IBAvzebnVuSp4S0EW8nM+oal+enrzTLwgWnGw6hTmwT
------END RSA PRIVATE KEY-----
diff --git a/apex/com.android.bluetooth.updatable.pk8 b/apex/com.android.bluetooth.updatable.pk8
deleted file mode 100644
index 59f489f..0000000
--- a/apex/com.android.bluetooth.updatable.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/com.android.bluetooth.updatable.x509.pem b/apex/com.android.bluetooth.updatable.x509.pem
deleted file mode 100644
index 71c169c..0000000
--- a/apex/com.android.bluetooth.updatable.x509.pem
+++ /dev/null
@@ -1,35 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIGKTCCBBGgAwIBAgIUZNVGFCcxcNXIbScs78HfUDxmLbEwDQYJKoZIhvcNAQEL
-BQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
-DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
-b2lkMR4wHAYDVQQDDBVjb20uYW5kcm9pZC5ibHVldG9vdGgxIjAgBgkqhkiG9w0B
-CQEWE2FuZHJvaWRAYW5kcm9pZC5jb20wIBcNMTkxMTEwMDIyMzI5WhgPNDc1NzEw
-MDYwMjIzMjlaMIGiMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
-MBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UE
-CwwHQW5kcm9pZDEeMBwGA1UEAwwVY29tLmFuZHJvaWQuYmx1ZXRvb3RoMSIwIAYJ
-KoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEAs4zDyliENHT++R/FRTzSoCv6103aAHme/pSrX0qWx8A7
-5IBEtevCaYR/DqCH/QlAZOndf3MPzf1eeGYSJ+YcBGXBNQ2nikUrpZd6a0cBaOXp
-4SQV3qzTasPCBzcOESEanijcSYdB31S5nAtFKQ1Qu3VtgmwyOw3C29A0DeSN1uDQ
-oZXL+11crJ+ZiVyvRA5OdNoKLppcX45fMFEf0Vel3Cp+XbdEBu3p1DkEN0PxKmPO
-43hS2/2hpaEmy3MM2J8v1SzRdyTj2Ftcv/H2JU1D9RUPKOO8iJkTWLgCewE8VVdC
-hZR4/h6vYKBT4v/fE4zTHS0sLlJhrCAz08BbnxNIUAB/WzcwHMy+EO0AaqZ4PLwh
-WfB2UBX4/mru/2BsoL47/aeXsfQi5+M8NrfnUR+KDUBu9SCqY9nSpvDVWLDJKMVh
-OQm2QBYCiPHoDRBClkkQxtBkQJ3CeH5Peufoamrd9oBcpJi8ZJCDtMWoi0Ie4dJR
-c9b4A/25GkxOwhSyNeIGmdnq3osSK6f1grDefi6GmxvTckyvBMQ0OS4BjfaMwqpw
-GpHe6NFZnDB3qfQPqwGOWcwChTFaoajkO/ETgv9m6RQelOBNQbB1lK3PmcIb1IC3
-9xq5Bp3bcb0DdTA/cKunE4kjDNE+zFSaTDKoexB6TtKjTWMMB6hQgx6KwZNWcc8C
-AwEAAaNTMFEwHQYDVR0OBBYEFAC1MgICiq6wSQUio2PzkQfMzAwmMB8GA1UdIwQY
-MBaAFAC1MgICiq6wSQUio2PzkQfMzAwmMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
-hvcNAQELBQADggIBAJmeqnXuhvxKmwEpsAGN2Y5moMNuch09KYssnqU7Nb94VxyT
-1qyrUHdiHxOffN0NKrxlgeoNqtbDIRf0LgmgOxRKGm0gf3+XEmw0KtBD29NyzxDy
-RfAvb+m7biTYhq6+V0wkCoT7HZqeuiSC+l+Gv03Qa3CHc613O5fJCpDJwAXIfRux
-/fvA5k/Pci3upra8kAu7xmZad6EMiY+HO4eK4ph8Kr3T8tFjkKMXzmYgj70zA4MD
-bNkZdUsGSsfVxrqfBJC0aCh0VwDskGXwIbs0q1Uc1RCpLLjdY0gMjkWVkgRKNq+u
-W/HiCaqLbjBk2QVOWugwIo6qqVhMOqCekpQjlIc+zJ8WZDunzFmF2OfmVKV4IkWU
-oHoU8Q2jo0211aO/jO8L7LuzsJb0oeGtOkMDaTm7IRE/cQOdN6bCxKV6da6EdZXw
-YTpTcfqg+D7q1/oYK4DzQsRfdfHrAh9PH/S8BU8buScST5ULdT6N+G4lcE5jAc3C
-c2/CTM3l6CWBAgYK+zDqh2Izjns3br25OT5WEtAcdrEU3igLsn3TU30gsK1+pefi
-Pa0ki00pGYj8Et6bIyBfHZ9nuu0SVAgIKNgtPWIu7QnxqpBHTsNH0GgLI/fCRNps
-XxeFStsf+Nj3NSGXAVUBgQZGAWgeMNjiG8siJJKa3A6ouRCkgiRrqcypYCCi
------END CERTIFICATE-----
diff --git a/apex/key.pem b/apex/key.pem
deleted file mode 100644
index 527a032..0000000
--- a/apex/key.pem
+++ /dev/null
@@ -1,52 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCzjMPKWIQ0dP75
-H8VFPNKgK/rXTdoAeZ7+lKtfSpbHwDvkgES168JphH8OoIf9CUBk6d1/cw/N/V54
-ZhIn5hwEZcE1DaeKRSull3prRwFo5enhJBXerNNqw8IHNw4RIRqeKNxJh0HfVLmc
-C0UpDVC7dW2CbDI7DcLb0DQN5I3W4NChlcv7XVysn5mJXK9EDk502goumlxfjl8w
-UR/RV6XcKn5dt0QG7enUOQQ3Q/EqY87jeFLb/aGloSbLcwzYny/VLNF3JOPYW1y/
-8fYlTUP1FQ8o47yImRNYuAJ7ATxVV0KFlHj+Hq9goFPi/98TjNMdLSwuUmGsIDPT
-wFufE0hQAH9bNzAczL4Q7QBqpng8vCFZ8HZQFfj+au7/YGygvjv9p5ex9CLn4zw2
-t+dRH4oNQG71IKpj2dKm8NVYsMkoxWE5CbZAFgKI8egNEEKWSRDG0GRAncJ4fk96
-5+hqat32gFykmLxkkIO0xaiLQh7h0lFz1vgD/bkaTE7CFLI14gaZ2ereixIrp/WC
-sN5+LoabG9NyTK8ExDQ5LgGN9ozCqnAakd7o0VmcMHep9A+rAY5ZzAKFMVqhqOQ7
-8ROC/2bpFB6U4E1BsHWUrc+ZwhvUgLf3GrkGndtxvQN1MD9wq6cTiSMM0T7MVJpM
-Mqh7EHpO0qNNYwwHqFCDHorBk1ZxzwIDAQABAoICAGXfODdWgaxBtWkj3YmrONYo
-HeqLAWXDm7JWJ+WpLGOpblH3dQTC/0tfIbfq3T10QlT/W+00G4OEflVRlHuO09aq
-5TR0ytpo5JrPl2XGo8YgrNJQ5xewd0PcTfpKAnE1lySlilctpvJP3//pZRQlueii
-d7/II7fd1vFg8CfxxYhlhfooQ9Qa5LoM09BcBhVXCKzECYLnkgGlhdykKqlcUX7Z
-nVkO4koMMt92ei3hHrQubPQjEOBAx7Zx+ND2NhOyPjF1fGNdSuk27Sj63+3KKQSl
-LjTFAfN+5rsvrDieOt0w5U1lMED+qALq9K2W/7rX6/Bh8O9XTpOasc0zFsjq59uI
-b+uBsZIPaGDpTjkYBKK3xrhNqIuq2ylN+0D14uAK4/z4sXsvP1XymjWkVNR9ii45
-doiDxANvZzqYoXcR5aEkJcO126RbDIw/SIglWTag6mRvNYCnLVcTzVf7uZXFyLXc
-Yk0NpTGAphVl4uVjXFgr8ZXfQIoM51zFvVVh3+dhosNGms1lgcvGHzJRKsOCzaA8
-EdWm3mGZrM8kvviqFoS4PndIIz6hB71MGhISEWbTUssF/AJSDWKdvJEWpTSLUjyY
-OoWaTABjZEjyCXpaIvssQilyOb+UVP6ayMAyfDjz5lDKB2216PhoQ9sOb9fIDrdK
-24XwqdMUqDZJV6GY8nQBAoIBAQDnS1DTUYeQwO1C831d1m8P8PhEDpwioBPv53y/
-owbmbwADTMxWvRfGnmXM5BYAeiDFfECp2HPnB5SGpkXOJOQ8H8WStgkhRglNHBbK
-yDaoLYTZqkk49enYEO6MNuFgTqiOWwgO+MVXPKmjreenhsoAQAKFFBPqyNU6v9a2
-WEHuIMc6Gv+2GkT7wkVwgmTZA1L58Y2EWX0wdDAYLS+0+6u+xJ5lPQI014Y7YNsa
-qvu7PG5gQ8fdU1fPmMRk9OOxiHilLc0GAQPtnF4fQYcNdcZ66FARMjHjZnFqHCPI
-irddmFReMkKj+HHufO6EVf8KkWgyIr9CzS9wh43PWW/CILwZAoIBAQDGuoM4DEV5
-tr+FmF3Rri1P0G+iC3Bm9oTa1S1AC4r8yPiY9Q8/lV009am2gbz6R5TFma+oFU1y
-R3pm6AaijeKmusmi2NGtdbqa9cUL98HtVAT7ZQmzyz9UepyZQmDy/0B4q2fGOUX1
-QnxKIOU2j8CFVUkbijUooRypZG7mIs/PsnTtmDb0JdOr54E26BLaBXbFcrxLuJxX
-STpQVbU3U/Y2jaLnRcPF4e6bCrQbrsH37wMLM3JTes8PRr0IcPDs4sp30Gj55rcL
-vSYZqfeVKadA312In5p4OPJV7/HSzRl4JE4JSWlCRLZepmAy36kFpQzI6N3LUVMp
-RuZtf+UXIVonAoIBAQCVLEIoyICCn6tmbtwAVXiz81prqnCQ9GVnaQlQH7knjZeY
-iUOQ/cwD0c0eZEy8aggQ1p5t7Khz7LOiVELZPXnmPSeUA8vHpgABt4gLqS13MkRo
-jidDkXcMX38693pMPu7/QT7lSRUduoY+hr7NkWVe2+nEIrrlxjmf9nJokGuVRZa4
-pwkdTbwIE7ftZGveewJdKal4Hq9bPNR4A0ytkVOnafAuozZ1FjwAt+sYPAa3L7aQ
-Z6bT3BjaT1D7O+ZObhJBllSQ9r6t1RfvWLfduoQUaRiavqDmZP/oy9VYVf8FYmWn
-iwrn7iitA+5hc4VWL4ngLADm+KcMEKEphilKLwqhAoIBAAC7FNpy6Rp+eovSOJ4Z
-xt7hRFfTNPGb/HcVi5oNsNAnKQre89RnBzW3pY0fQwOkmb50RzoWAffmnWOdfNDC
-NtAoJa+snnDF2w7Q0o2tto/Z3D7Ua0m2+J+l58eEf/jEyYboEnSfJ0u0l+Jp5o3h
-z3JuEtvAEVv547IXxXShMiRwYo+xHJqfPP0H1+jMx6z3ki09s8WPgzuq8ET1W7o9
-W81tjejNz999ajQ1wN3NMbdosJks8kGuVO6Ycv+B8tDcMKRqJsiseYXYhzhW8Ksi
-wROy/pQPCjFg/Dsmq7v7txlDAOp106ZDvGvyrq3hNqzno3llqdMilGy1bwl+C+ie
-3ccCggEBAISSVWD3owRf5n8unlVTmg64miLv3rM3s67F+Hn62qeyYmW3AhMSPyt2
-RIkEr2YrOKQ5D8Ijk3Gad4ae5UdyeCOPg495qk7bD5thcYG4Mo/MVvCQXxgdkeaK
-TFHpzzUttgKUe2EBfCbkxPjzWqf3ba0mvcnW621vUVA+VDqIUlBU9aosRMgDOFUi
-N+667Kj5P382oZHHxFnUZnCa3PczyGG3WLYBLRFAHl3n8kJ9mOUAAlVC8sRgcYmZ
-z2ZYfc22sUREah+kdxvDvR2ayopl86XoyrdTnK0XKEo+lU8Ghovc5Kbopf15KdWz
-/cAk+1ZkOAzn5RIZNaFGw2FKHds1ODQ=
------END PRIVATE KEY-----
diff --git a/audio_a2dp_hw/Android.bp b/audio_a2dp_hw/Android.bp
deleted file mode 100644
index 3ae1ee9..0000000
--- a/audio_a2dp_hw/Android.bp
+++ /dev/null
@@ -1,62 +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 "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_defaults {
- name: "audio_a2dp_hw_defaults",
- defaults: ["libchrome_support_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/audio_a2dp_hw/include",
- "system/bt/gd",
- "system/bt/include",
- "system/bt/types",
- ],
-}
-
-// Audio A2DP shared library for target
-cc_library {
- name: "audio.a2dp.default",
- defaults: ["audio_a2dp_hw_defaults"],
- relative_install_path: "hw",
- srcs: [
- "src/audio_a2dp_hw.cc",
- "src/audio_a2dp_hw_utils.cc",
- ],
- shared_libs: [
- "liblog",
- "libcutils",
- ],
- static_libs: ["libosi"],
-}
-
-cc_library_static {
- name: "libaudio-a2dp-hw-utils",
- defaults: ["audio_a2dp_hw_defaults"],
- srcs: [
- "src/audio_a2dp_hw_utils.cc",
- ],
- host_supported: true,
-}
-
-// Audio A2DP library unit tests for target and host
-cc_test {
- name: "net_test_audio_a2dp_hw",
- test_suites: ["device-tests"],
- defaults: ["audio_a2dp_hw_defaults"],
- srcs: [
- "test/audio_a2dp_hw_test.cc",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: [
- "audio.a2dp.default",
- "libosi",
- ],
-}
diff --git a/audio_a2dp_hw/include/audio_a2dp_hw.h b/audio_a2dp_hw/include/audio_a2dp_hw.h
deleted file mode 100644
index 3f380a6..0000000
--- a/audio_a2dp_hw/include/audio_a2dp_hw.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2009-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * Filename: audio_a2dp_hw.h
- *
- * Description:
- *
- *****************************************************************************/
-
-#ifndef AUDIO_A2DP_HW_H
-#define AUDIO_A2DP_HW_H
-
-#include <stdint.h>
-
-#include <hardware/bt_av.h>
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define A2DP_AUDIO_HARDWARE_INTERFACE "audio.a2dp"
-#define A2DP_CTRL_PATH "/data/misc/bluedroid/.a2dp_ctrl"
-#define A2DP_DATA_PATH "/data/misc/bluedroid/.a2dp_data"
-
-// AUDIO_STREAM_OUTPUT_BUFFER_SZ controls the size of the audio socket buffer.
-// If one assumes the write buffer is always full during normal BT playback,
-// then increasing this value increases our playback latency.
-//
-// FIXME: The BT HAL should consume data at a constant rate.
-// AudioFlinger assumes that the HAL draws data at a constant rate, which is
-// true for most audio devices; however, the BT engine reads data at a variable
-// rate (over the short term), which confuses both AudioFlinger as well as
-// applications which deliver data at a (generally) fixed rate.
-//
-// 20 * 512 is not sufficient to smooth the variability for some BT devices,
-// resulting in mixer sleep and throttling. We increase this to 28 * 512 to help
-// reduce the effect of variable data consumption.
-#define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 512)
-#define AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ 256
-
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided
-// for AudioFlinger data delivery. The AudioFlinger mixer delivers data in
-// chunks of AUDIO_STREAM_OUTPUT_BUFFER_SZ / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS.
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// In general, AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 * 4 should be a divisor
-// of AUDIO_STREAM_OUTPUT_BUFFER_SZ.
-//
-// These values should be chosen such that
-//
-// AUDIO_STREAM_BUFFER_SIZE * 1000 / (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS
-// * AUDIO_STREAM_DEFAULT_RATE * 4) > 20 (ms)
-//
-// to avoid introducing the FastMixer in AudioFlinger. Using the FastMixer
-// results in unnecessary latency and CPU overhead for Bluetooth.
-#define AUDIO_STREAM_OUTPUT_BUFFER_PERIODS 2
-
-#define AUDIO_SKT_DISCONNECTED (-1)
-
-typedef enum {
- A2DP_CTRL_CMD_NONE,
- A2DP_CTRL_CMD_CHECK_READY,
- A2DP_CTRL_CMD_START,
- A2DP_CTRL_CMD_STOP,
- A2DP_CTRL_CMD_SUSPEND,
- A2DP_CTRL_GET_INPUT_AUDIO_CONFIG,
- A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG,
- A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG,
- A2DP_CTRL_GET_PRESENTATION_POSITION,
-} tA2DP_CTRL_CMD;
-
-typedef enum {
- A2DP_CTRL_ACK_SUCCESS,
- A2DP_CTRL_ACK_FAILURE,
- A2DP_CTRL_ACK_INCALL_FAILURE, /* Failure when in Call*/
- A2DP_CTRL_ACK_UNSUPPORTED,
- A2DP_CTRL_ACK_PENDING,
- A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS,
-} tA2DP_CTRL_ACK;
-
-typedef uint32_t tA2DP_SAMPLE_RATE;
-typedef uint8_t tA2DP_CHANNEL_COUNT;
-typedef uint8_t tA2DP_BITS_PER_SAMPLE;
-
-/*****************************************************************************
- * Type definitions for callback functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Type definitions and return values
- *****************************************************************************/
-
-/*****************************************************************************
- * Extern variables and functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-
-// Computes the Audio A2DP HAL output buffer size.
-// |codec_sample_rate| is the sample rate of the output stream.
-// |codec_bits_per_sample| is the number of bits per sample of the output
-// stream.
-// |codec_channel_mode| is the channel mode of the output stream.
-//
-// The buffer size is computed by using the following formula:
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
-// (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
-// SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
-// divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
-// data in chunks of
-// (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// Furthermore, the AudioFlinger expects the buffer size to be a multiple
-// of 16 frames.
-//
-// NOTE: Currently, the computation uses the conservative 20ms time period.
-//
-// Returns the computed buffer size. If any of the input parameters is
-// invalid, the return value is the default |AUDIO_STREAM_OUTPUT_BUFFER_SZ|.
-size_t audio_a2dp_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode);
-
-// Returns whether the delay reporting property is set.
-bool delay_reporting_enabled();
-
-// Returns a string representation of |event|.
-const char* audio_a2dp_hw_dump_ctrl_event(tA2DP_CTRL_CMD event);
-
-#endif /* A2DP_AUDIO_HW_H */
diff --git a/audio_a2dp_hw/src/audio_a2dp_hw.cc b/audio_a2dp_hw/src/audio_a2dp_hw.cc
deleted file mode 100644
index cfa30fd..0000000
--- a/audio_a2dp_hw/src/audio_a2dp_hw.cc
+++ /dev/null
@@ -1,1960 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2009-2012 Broadcom Corporation
- *
- * 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.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * Filename: audio_a2dp_hw.c
- *
- * Description: Implements hal for bluedroid a2dp audio device
- *
- *****************************************************************************/
-
-#define LOG_TAG "bt_a2dp_hw"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <stdint.h>
-#include <sys/errno.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <mutex>
-
-#include <hardware/audio.h>
-#include <hardware/hardware.h>
-#include <system/audio.h>
-
-#include "osi/include/hash_map_utils.h"
-#include "osi/include/osi.h"
-#include "osi/include/socket_utils/sockets.h"
-
-#include "audio_a2dp_hw.h"
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define CTRL_CHAN_RETRY_COUNT 3
-#define USEC_PER_SEC 1000000L
-#define SOCK_SEND_TIMEOUT_MS 2000 /* Timeout for sending */
-#define SOCK_RECV_TIMEOUT_MS 5000 /* Timeout for receiving */
-#define SEC_TO_MS 1000
-#define SEC_TO_NS 1000000000
-#define MS_TO_NS 1000000
-#define DELAY_TO_NS 100000
-
-#define MIN_DELAY_MS 100
-#define MAX_DELAY_MS 1000
-
-// set WRITE_POLL_MS to 0 for blocking sockets, nonzero for polled non-blocking
-// sockets
-#define WRITE_POLL_MS 20
-
-#define FNLOG() ALOGV("%s:%d %s: ", __FILE__, __LINE__, __func__)
-#define DEBUG(fmt, args...) \
- ALOGD("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define INFO(fmt, args...) \
- ALOGI("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define WARN(fmt, args...) \
- ALOGW("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define ERROR(fmt, args...) \
- ALOGE("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-
-#define ASSERTC(cond, msg, val) \
- if (!(cond)) { \
- ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, \
- val); \
- }
-
-/*****************************************************************************
- * Local type definitions
- *****************************************************************************/
-
-typedef enum {
- AUDIO_A2DP_STATE_STARTING,
- AUDIO_A2DP_STATE_STARTED,
- AUDIO_A2DP_STATE_STOPPING,
- AUDIO_A2DP_STATE_STOPPED,
- /* need explicit set param call to resume (suspend=false) */
- AUDIO_A2DP_STATE_SUSPENDED,
- AUDIO_A2DP_STATE_STANDBY /* allows write to autoresume */
-} a2dp_state_t;
-
-struct a2dp_stream_in;
-struct a2dp_stream_out;
-
-struct a2dp_audio_device {
- // Important: device must be first as an audio_hw_device* may be cast to
- // a2dp_audio_device* when the type is implicitly known.
- struct audio_hw_device device;
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- struct a2dp_stream_in* input;
- struct a2dp_stream_out* output;
-};
-
-struct a2dp_config {
- uint32_t rate;
- audio_channel_mask_t channel_mask;
- bool is_stereo_to_mono; // True if fetching Stereo and mixing into Mono
- int format;
-};
-
-/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
-
-struct a2dp_stream_common {
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- int ctrl_fd;
- int audio_fd;
- size_t buffer_sz;
- struct a2dp_config cfg;
- a2dp_state_t state;
-};
-
-struct a2dp_stream_out {
- struct audio_stream_out stream;
- struct a2dp_stream_common common;
- uint64_t frames_presented; // frames written, never reset
- uint64_t frames_rendered; // frames written, reset on standby
-};
-
-struct a2dp_stream_in {
- struct audio_stream_in stream;
- struct a2dp_stream_common common;
-};
-
-/*
- * Mutex acquisition order:
- *
- * The a2dp_audio_device (adev) mutex must be acquired before
- * the a2dp_stream_common (out or in) mutex.
- *
- * This may differ from other audio HALs.
- */
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-
-static bool enable_delay_reporting = false;
-
-/*****************************************************************************
- * Static functions
- *****************************************************************************/
-
-static size_t out_get_buffer_size(const struct audio_stream* stream);
-static uint32_t out_get_latency(const struct audio_stream_out* stream);
-
-/*****************************************************************************
- * Externs
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-static void a2dp_open_ctrl_path(struct a2dp_stream_common* common);
-
-/*****************************************************************************
- * Miscellaneous helper functions
- *****************************************************************************/
-static void hash_map_utils_dump_string_keys_string_values(
- std::unordered_map<std::string, std::string>& map) {
- for (const auto& ptr : map) {
- INFO("key: '%s' value: '%s'\n", ptr.first.c_str(), ptr.second.c_str());
- }
-}
-
-/* logs timestamp with microsec precision
- pprev is optional in case a dedicated diff is required */
-static void ts_log(UNUSED_ATTR const char* tag, UNUSED_ATTR int val,
- struct timespec* pprev_opt) {
- struct timespec now;
- static struct timespec prev = {0, 0};
- unsigned long long now_us;
- unsigned long long diff_us;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- now_us = now.tv_sec * USEC_PER_SEC + now.tv_nsec / 1000;
-
- if (pprev_opt) {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- *pprev_opt = now;
- DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
- } else {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- prev = now;
- DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
- }
-}
-
-static int calc_audiotime_usec(struct a2dp_config cfg, int bytes) {
- int chan_count = audio_channel_count_from_out_mask(cfg.channel_mask);
- int bytes_per_sample;
-
- switch (cfg.format) {
- case AUDIO_FORMAT_PCM_8_BIT:
- bytes_per_sample = 1;
- break;
- case AUDIO_FORMAT_PCM_16_BIT:
- bytes_per_sample = 2;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- bytes_per_sample = 3;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- bytes_per_sample = 4;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- bytes_per_sample = 4;
- break;
- default:
- ASSERTC(false, "unsupported sample format", cfg.format);
- bytes_per_sample = 2;
- break;
- }
-
- return (
- int)(((int64_t)bytes * (USEC_PER_SEC / (chan_count * bytes_per_sample))) /
- cfg.rate);
-}
-
-/*****************************************************************************
- *
- * bluedroid stack adaptation
- *
- ****************************************************************************/
-
-static int skt_connect(const char* path, size_t buffer_sz) {
- int ret;
- int skt_fd;
- int len;
-
- INFO("connect to %s (sz %zu)", path, buffer_sz);
-
- skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
-
- if (osi_socket_local_client_connect(
- skt_fd, path, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) {
- ERROR("failed to connect (%s)", strerror(errno));
- close(skt_fd);
- return -1;
- }
-
- len = buffer_sz;
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- /* Socket send/receive timeout value */
- struct timeval tv;
- tv.tv_sec = SOCK_SEND_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_SEND_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- tv.tv_sec = SOCK_RECV_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_RECV_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- INFO("connected to stack fd = %d", skt_fd);
-
- return skt_fd;
-}
-
-static int skt_read(int fd, void* p, size_t len) {
- ssize_t read;
-
- FNLOG();
-
- ts_log("skt_read recv", len, NULL);
-
- OSI_NO_INTR(read = recv(fd, p, len, MSG_NOSIGNAL));
- if (read == -1) ERROR("read failed with errno=%d\n", errno);
-
- return (int)read;
-}
-
-static int skt_write(int fd, const void* p, size_t len) {
- ssize_t sent;
- FNLOG();
-
- ts_log("skt_write", len, NULL);
-
- if (WRITE_POLL_MS == 0) {
- // do not poll, use blocking send
- OSI_NO_INTR(sent = send(fd, p, len, MSG_NOSIGNAL));
- if (sent == -1) ERROR("write failed with error(%s)", strerror(errno));
-
- return (int)sent;
- }
-
- // use non-blocking send, poll
- int ms_timeout = SOCK_SEND_TIMEOUT_MS;
- size_t count = 0;
- while (count < len) {
- OSI_NO_INTR(sent = send(fd, p, len - count, MSG_NOSIGNAL | MSG_DONTWAIT));
- if (sent == -1) {
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- ERROR("write failed with error(%s)", strerror(errno));
- return -1;
- }
- if (ms_timeout >= WRITE_POLL_MS) {
- usleep(WRITE_POLL_MS * 1000);
- ms_timeout -= WRITE_POLL_MS;
- continue;
- }
- WARN("write timeout exceeded, sent %zu bytes", count);
- return -1;
- }
- count += sent;
- p = (const uint8_t*)p + sent;
- }
- return (int)count;
-}
-
-static int skt_disconnect(int fd) {
- INFO("fd %d", fd);
-
- if (fd != AUDIO_SKT_DISCONNECTED) {
- shutdown(fd, SHUT_RDWR);
- close(fd);
- }
- return 0;
-}
-
-/*****************************************************************************
- *
- * AUDIO CONTROL PATH
- *
- ****************************************************************************/
-
-static int a2dp_ctrl_receive(struct a2dp_stream_common* common, void* buffer,
- size_t length) {
- ssize_t ret;
- int i;
-
- for (i = 0;; i++) {
- OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
- if (ret > 0) {
- break;
- }
- if (ret == 0) {
- ERROR("receive control data failed: peer closed");
- break;
- }
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("receive control data failed: error(%s)", strerror(errno));
- break;
- }
- if (i == (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("receive control data failed: max retry count");
- break;
- }
- INFO("receive control data failed (%s), retrying", strerror(errno));
- }
- if (ret <= 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- return ret;
-}
-
-// Sends control info for stream |common|. The data to send is stored in
-// |buffer| and has size |length|.
-// On success, returns the number of octets sent, otherwise -1.
-static int a2dp_ctrl_send(struct a2dp_stream_common* common, const void* buffer,
- size_t length) {
- ssize_t sent;
- size_t remaining = length;
- int i;
-
- if (length == 0) return 0; // Nothing to do
-
- for (i = 0;; i++) {
- OSI_NO_INTR(sent = send(common->ctrl_fd, buffer, remaining, MSG_NOSIGNAL));
- if (sent == static_cast<ssize_t>(remaining)) {
- remaining = 0;
- break;
- }
- if (sent > 0) {
- buffer = (static_cast<const char*>(buffer) + sent);
- remaining -= sent;
- continue;
- }
- if (sent < 0) {
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("send control data failed: error(%s)", strerror(errno));
- break;
- }
- INFO("send control data failed (%s), retrying", strerror(errno));
- }
- if (i >= (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("send control data failed: max retry count");
- break;
- }
- }
- if (remaining > 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
- return length;
-}
-
-static int a2dp_command(struct a2dp_stream_common* common, tA2DP_CTRL_CMD cmd) {
- char ack;
-
- DEBUG("A2DP COMMAND %s", audio_a2dp_hw_dump_ctrl_event(cmd));
-
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- INFO("starting up or recovering from previous error: command=%s",
- audio_a2dp_hw_dump_ctrl_event(cmd));
- a2dp_open_ctrl_path(common);
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- ERROR("failure to open ctrl path: command=%s",
- audio_a2dp_hw_dump_ctrl_event(cmd));
- return -1;
- }
- }
-
- /* send command */
- ssize_t sent;
- OSI_NO_INTR(sent = send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL));
- if (sent == -1) {
- ERROR("cmd failed (%s): command=%s", strerror(errno),
- audio_a2dp_hw_dump_ctrl_event(cmd));
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
-
- /* wait for ack byte */
- if (a2dp_ctrl_receive(common, &ack, 1) < 0) {
- ERROR("A2DP COMMAND %s: no ACK", audio_a2dp_hw_dump_ctrl_event(cmd));
- return -1;
- }
-
- DEBUG("A2DP COMMAND %s DONE STATUS %d", audio_a2dp_hw_dump_ctrl_event(cmd),
- ack);
-
- if (ack == A2DP_CTRL_ACK_INCALL_FAILURE) {
- ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
- return ack;
- }
- if (ack != A2DP_CTRL_ACK_SUCCESS) {
- ERROR("A2DP COMMAND %s error %d", audio_a2dp_hw_dump_ctrl_event(cmd), ack);
- return -1;
- }
-
- return 0;
-}
-
-static int check_a2dp_ready(struct a2dp_stream_common* common) {
- if (a2dp_command(common, A2DP_CTRL_CMD_CHECK_READY) < 0) {
- ERROR("check a2dp ready failed");
- return -1;
- }
- return 0;
-}
-
-static int a2dp_read_input_audio_config(struct a2dp_stream_common* common) {
- tA2DP_SAMPLE_RATE sample_rate;
- tA2DP_CHANNEL_COUNT channel_count;
-
- if (a2dp_command(common, A2DP_CTRL_GET_INPUT_AUDIO_CONFIG) < 0) {
- ERROR("get a2dp input audio config failed");
- return -1;
- }
-
- if (a2dp_ctrl_receive(common, &sample_rate, sizeof(tA2DP_SAMPLE_RATE)) < 0)
- return -1;
- if (a2dp_ctrl_receive(common, &channel_count, sizeof(tA2DP_CHANNEL_COUNT)) <
- 0) {
- return -1;
- }
-
- switch (sample_rate) {
- case 44100:
- case 48000:
- common->cfg.rate = sample_rate;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, sample_rate);
- return -1;
- }
-
- switch (channel_count) {
- case 1:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_MONO;
- break;
- case 2:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_STEREO;
- break;
- default:
- ERROR("Invalid channel count: %" PRIu32, channel_count);
- return -1;
- }
-
- // TODO: For now input audio format is always hard-coded as PCM 16-bit
- common->cfg.format = AUDIO_FORMAT_PCM_16_BIT;
-
- INFO("got input audio config %d %d", common->cfg.format, common->cfg.rate);
-
- return 0;
-}
-
-static int a2dp_read_output_audio_config(
- struct a2dp_stream_common* common, btav_a2dp_codec_config_t* codec_config,
- btav_a2dp_codec_config_t* codec_capability, bool update_stream_config) {
- struct a2dp_config stream_config;
-
- if (a2dp_command(common, A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("get a2dp output audio config failed");
- return -1;
- }
-
- // Receive the current codec config
- if (a2dp_ctrl_receive(common, &codec_config->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_config->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_config->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Receive the current codec capability
- if (a2dp_ctrl_receive(common, &codec_capability->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_capability->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_receive(common, &codec_capability->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Check the codec config sample rate
- switch (codec_config->sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- stream_config.rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- stream_config.rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- stream_config.rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- stream_config.rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- stream_config.rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- stream_config.rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_config->sample_rate);
- return -1;
- }
-
- // Check the codec config bits per sample
- switch (codec_config->bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- stream_config.format = AUDIO_FORMAT_PCM_16_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- stream_config.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- stream_config.format = AUDIO_FORMAT_PCM_32_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_config->bits_per_sample);
- return -1;
- }
-
- // Check the codec config channel mode
- switch (codec_config->channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_MONO;
- stream_config.is_stereo_to_mono = true;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- stream_config.is_stereo_to_mono = false;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_config->channel_mode);
- return -1;
- }
- if (stream_config.is_stereo_to_mono) {
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- }
-
- // Update the output stream configuration
- if (update_stream_config) {
- common->cfg.rate = stream_config.rate;
- common->cfg.channel_mask = stream_config.channel_mask;
- common->cfg.is_stereo_to_mono = stream_config.is_stereo_to_mono;
- common->cfg.format = stream_config.format;
- common->buffer_sz = audio_a2dp_hw_stream_compute_buffer_size(
- codec_config->sample_rate, codec_config->bits_per_sample,
- codec_config->channel_mode);
- if (common->cfg.is_stereo_to_mono) {
- // We need to fetch twice as much data from the Audio framework
- common->buffer_sz *= 2;
- }
- }
-
- INFO(
- "got output codec config (update_stream_config=%s): "
- "sample_rate=0x%x bits_per_sample=0x%x channel_mode=0x%x",
- update_stream_config ? "true" : "false", codec_config->sample_rate,
- codec_config->bits_per_sample, codec_config->channel_mode);
-
- INFO(
- "got output codec capability: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_capability->sample_rate, codec_capability->bits_per_sample,
- codec_capability->channel_mode);
-
- return 0;
-}
-
-static int a2dp_write_output_audio_config(struct a2dp_stream_common* common) {
- btav_a2dp_codec_config_t codec_config;
-
- if (a2dp_command(common, A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("set a2dp output audio config failed");
- return -1;
- }
-
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
-
- switch (common->cfg.rate) {
- case 44100:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
- break;
- case 48000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
- break;
- case 88200:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_88200;
- break;
- case 96000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_96000;
- break;
- case 176400:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_176400;
- break;
- case 192000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_192000;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, common->cfg.rate);
- return -1;
- }
-
- switch (common->cfg.format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- // All 24-bit audio is expected in AUDIO_FORMAT_PCM_24_BIT_PACKED format
- FALLTHROUGH_INTENDED; /* FALLTHROUGH */
- default:
- ERROR("Invalid audio format: 0x%x", common->cfg.format);
- return -1;
- }
-
- switch (common->cfg.channel_mask) {
- case AUDIO_CHANNEL_OUT_MONO:
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- break;
- case AUDIO_CHANNEL_OUT_STEREO:
- if (common->cfg.is_stereo_to_mono) {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- } else {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
- }
- break;
- default:
- ERROR("Invalid channel mask: 0x%x", common->cfg.channel_mask);
- return -1;
- }
-
- // Send the current codec config that has been selected by us
- if (a2dp_ctrl_send(common, &codec_config.sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0)
- return -1;
- if (a2dp_ctrl_send(common, &codec_config.bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (a2dp_ctrl_send(common, &codec_config.channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- INFO(
- "sent output codec config: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_config.sample_rate, codec_config.bits_per_sample,
- codec_config.channel_mode);
-
- return 0;
-}
-
-static int a2dp_get_presentation_position_cmd(struct a2dp_stream_common* common,
- uint64_t* bytes, uint16_t* delay,
- struct timespec* timestamp) {
- if ((common->ctrl_fd == AUDIO_SKT_DISCONNECTED) ||
- (common->state != AUDIO_A2DP_STATE_STARTED)) { // Audio is not streaming
- return -1;
- }
-
- if (a2dp_command(common, A2DP_CTRL_GET_PRESENTATION_POSITION) < 0) {
- return -1;
- }
-
- if (a2dp_ctrl_receive(common, bytes, sizeof(*bytes)) < 0) {
- return -1;
- }
-
- if (a2dp_ctrl_receive(common, delay, sizeof(*delay)) < 0) {
- return -1;
- }
-
- uint32_t seconds;
- if (a2dp_ctrl_receive(common, &seconds, sizeof(seconds)) < 0) {
- return -1;
- }
-
- uint32_t nsec;
- if (a2dp_ctrl_receive(common, &nsec, sizeof(nsec)) < 0) {
- return -1;
- }
-
- timestamp->tv_sec = seconds;
- timestamp->tv_nsec = nsec;
- return 0;
-}
-
-static void a2dp_open_ctrl_path(struct a2dp_stream_common* common) {
- int i;
-
- if (common->ctrl_fd != AUDIO_SKT_DISCONNECTED) return; // already connected
-
- /* retry logic to catch any timing variations on control channel */
- for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) {
- /* connect control channel if not already connected */
- if ((common->ctrl_fd = skt_connect(
- A2DP_CTRL_PATH, AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ)) >= 0) {
- /* success, now check if stack is ready */
- if (check_a2dp_ready(common) == 0) break;
-
- ERROR("error : a2dp not ready, wait 250 ms and retry");
- usleep(250000);
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- /* ctrl channel not ready, wait a bit */
- usleep(250000);
- }
-}
-
-/*****************************************************************************
- *
- * AUDIO DATA PATH
- *
- ****************************************************************************/
-
-static void a2dp_stream_common_init(struct a2dp_stream_common* common) {
- FNLOG();
-
- common->mutex = new std::recursive_mutex;
-
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
- common->state = AUDIO_A2DP_STATE_STOPPED;
-
- /* manages max capacity of socket pipe */
- common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
-}
-
-static void a2dp_stream_common_destroy(struct a2dp_stream_common* common) {
- FNLOG();
-
- delete common->mutex;
- common->mutex = NULL;
-}
-
-static int start_audio_datapath(struct a2dp_stream_common* common) {
- INFO("state %d", common->state);
-
- int oldstate = common->state;
- common->state = AUDIO_A2DP_STATE_STARTING;
-
- int a2dp_status = a2dp_command(common, A2DP_CTRL_CMD_START);
- if (a2dp_status < 0) {
- ERROR("Audiopath start failed (status %d)", a2dp_status);
- goto error;
- } else if (a2dp_status == A2DP_CTRL_ACK_INCALL_FAILURE) {
- ERROR("Audiopath start failed - in call, move to suspended");
- goto error;
- }
-
- /* connect socket if not yet connected */
- if (common->audio_fd == AUDIO_SKT_DISCONNECTED) {
- common->audio_fd = skt_connect(A2DP_DATA_PATH, common->buffer_sz);
- if (common->audio_fd < 0) {
- ERROR("Audiopath start failed - error opening data socket");
- goto error;
- }
- }
- common->state = (a2dp_state_t)AUDIO_A2DP_STATE_STARTED;
-
- /* check to see if delay reporting is enabled */
- enable_delay_reporting = delay_reporting_enabled();
-
- return 0;
-
-error:
- common->state = (a2dp_state_t)oldstate;
- return -1;
-}
-
-static int stop_audio_datapath(struct a2dp_stream_common* common) {
- int oldstate = common->state;
-
- INFO("state %d", common->state);
-
- /* prevent any stray output writes from autostarting the stream
- while stopping audiopath */
- common->state = AUDIO_A2DP_STATE_STOPPING;
-
- if (a2dp_command(common, A2DP_CTRL_CMD_STOP) < 0) {
- ERROR("audiopath stop failed");
- common->state = (a2dp_state_t)oldstate;
- return -1;
- }
-
- common->state = (a2dp_state_t)AUDIO_A2DP_STATE_STOPPED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-static int suspend_audio_datapath(struct a2dp_stream_common* common,
- bool standby) {
- INFO("state %d", common->state);
-
- if (common->state == AUDIO_A2DP_STATE_STOPPING) return -1;
-
- if (a2dp_command(common, A2DP_CTRL_CMD_SUSPEND) < 0) return -1;
-
- if (standby)
- common->state = AUDIO_A2DP_STATE_STANDBY;
- else
- common->state = AUDIO_A2DP_STATE_SUSPENDED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
-
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * audio output callbacks
- *
- ****************************************************************************/
-
-static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
- size_t bytes) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- int sent = -1;
- size_t write_bytes = bytes;
-
- DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
-
- std::unique_lock<std::recursive_mutex> lock(*out->common.mutex);
- if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED ||
- out->common.state == AUDIO_A2DP_STATE_STOPPING) {
- DEBUG("stream suspended or closing");
- goto finish;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((out->common.state == AUDIO_A2DP_STATE_STOPPED) ||
- (out->common.state == AUDIO_A2DP_STATE_STANDBY)) {
- if (start_audio_datapath(&out->common) < 0) {
- goto finish;
- }
- } else if (out->common.state != AUDIO_A2DP_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto finish;
- }
-
- // Mix the stereo into mono if necessary
- if (out->common.cfg.is_stereo_to_mono) {
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- int16_t* src = (int16_t*)buffer;
- int16_t* dst = (int16_t*)buffer;
- for (size_t i = 0; i < frames; i++, dst++, src += 2) {
- *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
- }
- write_bytes /= 2;
- DEBUG("stereo-to-mono mixing: write %zu bytes (fd %d)", write_bytes,
- out->common.audio_fd);
- }
-
- lock.unlock();
- sent = skt_write(out->common.audio_fd, buffer, write_bytes);
- lock.lock();
-
- if (sent == -1) {
- skt_disconnect(out->common.audio_fd);
- out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((out->common.state != AUDIO_A2DP_STATE_SUSPENDED) &&
- (out->common.state != AUDIO_A2DP_STATE_STOPPING)) {
- out->common.state = AUDIO_A2DP_STATE_STOPPED;
- } else {
- ERROR("write failed : stream suspended, avoid resetting state");
- }
- goto finish;
- }
-
-finish:;
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- out->frames_rendered += frames;
- out->frames_presented += frames;
- lock.unlock();
-
- // If send didn't work out, sleep to emulate write delay.
- if (sent == -1) {
- const int us_delay = calc_audiotime_usec(out->common.cfg, bytes);
- DEBUG("emulate a2dp write delay (%d us)", us_delay);
- usleep(us_delay);
- }
- return bytes;
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- DEBUG("rate %" PRIu32, out->common.cfg.rate);
-
- return out->common.cfg.rate;
-}
-
-static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- DEBUG("out_set_sample_rate : %" PRIu32, rate);
-
- out->common.cfg.rate = rate;
-
- return 0;
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- // period_size is the AudioFlinger mixer buffer size.
- const size_t period_size =
- out->common.buffer_sz / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS;
-
- DEBUG("socket buffer size: %zu period size: %zu", out->common.buffer_sz,
- period_size);
-
- return period_size;
-}
-
-size_t audio_a2dp_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- size_t buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; // Default value
- const uint64_t time_period_ms = 20; // Conservative 20ms
- uint32_t sample_rate;
- uint32_t bits_per_sample;
- uint32_t number_of_channels;
-
- // Check the codec config sample rate
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- sample_rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- sample_rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- sample_rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- sample_rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- sample_rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- sample_rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_sample_rate);
- return buffer_sz;
- }
-
- // Check the codec config bits per sample
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- bits_per_sample = 16;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- bits_per_sample = 24;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- bits_per_sample = 32;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_bits_per_sample);
- return buffer_sz;
- }
-
- // Check the codec config channel mode
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- number_of_channels = 1;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- number_of_channels = 2;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_channel_mode);
- return buffer_sz;
- }
-
- //
- // The buffer size is computed by using the following formula:
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
- // (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- // SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
- // divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
- // data in chunks of
- // (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
- // If the number of periods is 2, the socket buffer represents "double
- // buffering" of the AudioFlinger mixer buffer.
- //
- // Furthermore, the AudioFlinger expects the buffer size to be a multiple
- // of 16 frames.
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
-
- buffer_sz = (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- sample_rate * number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Adjust the buffer size so it can be divided by the divisor
- const size_t remainder = buffer_sz % divisor;
- if (remainder != 0) {
- buffer_sz += divisor - remainder;
- }
-
- return buffer_sz;
-}
-
-static audio_channel_mask_t out_get_channels(
- const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_mask);
-
- return (audio_channel_mask_t)out->common.cfg.channel_mask;
-}
-
-static audio_format_t out_get_format(const struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- DEBUG("format 0x%x", out->common.cfg.format);
- return (audio_format_t)out->common.cfg.format;
-}
-
-static int out_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- DEBUG("setting format not yet supported (0x%x)", format);
- return -ENOSYS;
-}
-
-static int out_standby(struct audio_stream* stream) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
- int retVal = 0;
-
- FNLOG();
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- // Do nothing in SUSPENDED state.
- if (out->common.state != AUDIO_A2DP_STATE_SUSPENDED)
- retVal = suspend_audio_datapath(&out->common, true);
- out->frames_rendered = 0; // rendered is reset, presented is not
-
- return retVal;
-}
-
-static int out_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream* stream,
- const char* kvpairs) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- INFO("state %d kvpairs %s", out->common.state, kvpairs);
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(kvpairs);
- int status = 0;
-
- if (params.empty()) return status;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- /* dump params */
- hash_map_utils_dump_string_keys_string_values(params);
-
- if (params["closing"].compare("true") == 0) {
- DEBUG("stream closing, disallow any writes");
- out->common.state = AUDIO_A2DP_STATE_STOPPING;
- }
-
- if (params["A2dpSuspended"].compare("true") == 0) {
- if (out->common.state == AUDIO_A2DP_STATE_STARTED)
- status = suspend_audio_datapath(&out->common, false);
- } else {
- /* Do not start the streaming automatically. If the phone was streaming
- * prior to being suspended, the next out_write shall trigger the
- * AVDTP start procedure */
- if (out->common.state == AUDIO_A2DP_STATE_SUSPENDED)
- out->common.state = AUDIO_A2DP_STATE_STANDBY;
- /* Irrespective of the state, return 0 */
- }
-
- return status;
-}
-
-static char* out_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- FNLOG();
-
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
-
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- std::unordered_map<std::string, std::string> return_params;
-
- if (params.empty()) return strdup("");
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- if (a2dp_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- false /* update_stream_config */) < 0) {
- ERROR("a2dp_read_output_audio_config failed");
- goto done;
- }
-
- // Add the format
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- std::string param;
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_16_BIT";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_24_BIT_PACKED";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_32_BIT";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability bits_per_sample=0x%x",
- codec_capability.bits_per_sample);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param;
- }
- }
-
- // Add the sample rate
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) {
- std::string param;
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_44100) {
- if (!param.empty()) param += "|";
- param += "44100";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_48000) {
- if (!param.empty()) param += "|";
- param += "48000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_88200) {
- if (!param.empty()) param += "|";
- param += "88200";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_96000) {
- if (!param.empty()) param += "|";
- param += "96000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_176400) {
- if (!param.empty()) param += "|";
- param += "176400";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_192000) {
- if (!param.empty()) param += "|";
- param += "192000";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability sample_rate=0x%x",
- codec_capability.sample_rate);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param;
- }
- }
-
- // Add the channel mask
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) {
- std::string param;
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_MONO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_MONO";
- }
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_STEREO";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability channel_mode=0x%x",
- codec_capability.channel_mode);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param;
- }
- }
-
-done:
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- INFO("get parameters result = %s", result.c_str());
-
- return strdup(result.c_str());
-}
-
-static uint32_t out_get_latency(const struct audio_stream_out* stream) {
- int latency_us;
-
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- FNLOG();
-
- latency_us =
- ((out->common.buffer_sz * 1000) /
- audio_stream_out_frame_size(&out->stream) / out->common.cfg.rate) *
- 1000;
-
- return (latency_us / 1000) + 200;
-}
-
-static int out_set_volume(UNUSED_ATTR struct audio_stream_out* stream,
- UNUSED_ATTR float left, UNUSED_ATTR float right) {
- FNLOG();
-
- /* volume controlled in audioflinger mixer (digital) */
-
- return -ENOSYS;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out* stream,
- uint64_t* frames,
- struct timespec* timestamp) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || frames == NULL || timestamp == NULL) return -EINVAL;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- // bytes is the total number of bytes sent by the Bluetooth stack to a
- // remote headset
- uint64_t bytes = 0;
-
- // delay_report is the audio delay from the remote headset receiving data to
- // the headset playing sound in units of 1/10ms
- uint16_t delay_report = 0;
-
- // If for some reason getting a delay fails or delay reports are disabled,
- // default to old delay
- if (enable_delay_reporting &&
- a2dp_get_presentation_position_cmd(&out->common, &bytes, &delay_report,
- timestamp) == 0) {
- uint64_t delay_ns = delay_report * DELAY_TO_NS;
- if (delay_ns > MIN_DELAY_MS * MS_TO_NS &&
- delay_ns < MAX_DELAY_MS * MS_TO_NS) {
- *frames = bytes / audio_stream_out_frame_size(stream);
-
- timestamp->tv_nsec += delay_ns;
- if (timestamp->tv_nsec > 1 * SEC_TO_NS) {
- timestamp->tv_sec++;
- timestamp->tv_nsec -= SEC_TO_NS;
- }
- return 0;
- }
- }
-
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_presented >= latency_frames) {
- clock_gettime(CLOCK_MONOTONIC, timestamp);
- *frames = out->frames_presented - latency_frames;
- return 0;
- }
-
- return -EWOULDBLOCK;
-}
-
-static int out_get_render_position(const struct audio_stream_out* stream,
- uint32_t* dsp_frames) {
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || dsp_frames == NULL) return -EINVAL;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_rendered >= latency_frames) {
- *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
- } else {
- *dsp_frames = 0;
- }
- return 0;
-}
-
-static int out_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int out_remove_audio_effect(
- UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-/*
- * AUDIO INPUT STREAM
- */
-
-static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- FNLOG();
- return in->common.cfg.rate;
-}
-
-static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- FNLOG();
-
- if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
- return 0;
- else
- return -1;
-}
-
-static size_t in_get_buffer_size(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return 320;
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- FNLOG();
- return (audio_channel_mask_t)in->common.cfg.channel_mask;
-}
-
-static audio_format_t in_get_format(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return AUDIO_FORMAT_PCM_16_BIT;
-}
-
-static int in_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- FNLOG();
- if (format == AUDIO_FORMAT_PCM_16_BIT)
- return 0;
- else
- return -1;
-}
-
-static int in_standby(UNUSED_ATTR struct audio_stream* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int in_set_parameters(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR const char* kvpairs) {
- FNLOG();
- return 0;
-}
-
-static char* in_get_parameters(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR const char* keys) {
- FNLOG();
- return strdup("");
-}
-
-static int in_set_gain(UNUSED_ATTR struct audio_stream_in* stream,
- UNUSED_ATTR float gain) {
- FNLOG();
- return 0;
-}
-
-static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
- size_t bytes) {
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
- int read;
- int us_delay;
-
- DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
-
- std::unique_lock<std::recursive_mutex> lock(*in->common.mutex);
- if (in->common.state == AUDIO_A2DP_STATE_SUSPENDED ||
- in->common.state == AUDIO_A2DP_STATE_STOPPING) {
- DEBUG("stream suspended");
- goto error;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((in->common.state == AUDIO_A2DP_STATE_STOPPED) ||
- (in->common.state == AUDIO_A2DP_STATE_STANDBY)) {
- if (start_audio_datapath(&in->common) < 0) {
- goto error;
- }
- } else if (in->common.state != AUDIO_A2DP_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto error;
- }
-
- lock.unlock();
- read = skt_read(in->common.audio_fd, buffer, bytes);
- lock.lock();
- if (read == -1) {
- skt_disconnect(in->common.audio_fd);
- in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((in->common.state != AUDIO_A2DP_STATE_SUSPENDED) &&
- (in->common.state != AUDIO_A2DP_STATE_STOPPING)) {
- in->common.state = AUDIO_A2DP_STATE_STOPPED;
- } else {
- ERROR("read failed : stream suspended, avoid resetting state");
- }
- goto error;
- } else if (read == 0) {
- DEBUG("read time out - return zeros");
- memset(buffer, 0, bytes);
- read = bytes;
- }
- lock.unlock();
-
- DEBUG("read %d bytes out of %zu bytes", read, bytes);
- return read;
-
-error:
- memset(buffer, 0, bytes);
- us_delay = calc_audiotime_usec(in->common.cfg, bytes);
- DEBUG("emulate a2dp read delay (%d us)", us_delay);
-
- usleep(us_delay);
- return bytes;
-}
-
-static uint32_t in_get_input_frames_lost(
- UNUSED_ATTR struct audio_stream_in* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int in_remove_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_open_output_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- UNUSED_ATTR const char* address)
-
-{
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_out* out;
- int ret = 0;
-
- INFO("opening output");
- // protect against adev->output and stream_out from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- out = (struct a2dp_stream_out*)calloc(1, sizeof(struct a2dp_stream_out));
-
- if (!out) return -ENOMEM;
-
- out->stream.common.get_sample_rate = out_get_sample_rate;
- out->stream.common.set_sample_rate = out_set_sample_rate;
- out->stream.common.get_buffer_size = out_get_buffer_size;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
- out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
- out->stream.common.dump = out_dump;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.common.get_parameters = out_get_parameters;
- out->stream.common.add_audio_effect = out_add_audio_effect;
- out->stream.common.remove_audio_effect = out_remove_audio_effect;
- out->stream.get_latency = out_get_latency;
- out->stream.set_volume = out_set_volume;
- out->stream.write = out_write;
- out->stream.get_render_position = out_get_render_position;
- out->stream.get_presentation_position = out_get_presentation_position;
-
- /* initialize a2dp specifics */
- a2dp_stream_common_init(&out->common);
-
- // Make sure we always have the feeding parameters configured
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
- if (a2dp_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("a2dp_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // a2dp_read_output_audio_config() opens the socket control path (or fails)
-
- /* set output config values */
- if (config != nullptr) {
- // Try to use the config parameters and send it to the remote side
- // TODO: Shall we use out_set_format() and similar?
- if (config->format != 0) out->common.cfg.format = config->format;
- if (config->sample_rate != 0) out->common.cfg.rate = config->sample_rate;
- if (config->channel_mask != 0)
- out->common.cfg.channel_mask = config->channel_mask;
- if ((out->common.cfg.format != 0) || (out->common.cfg.rate != 0) ||
- (out->common.cfg.channel_mask != 0)) {
- if (a2dp_write_output_audio_config(&out->common) < 0) {
- ERROR("a2dp_write_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // Read again and make sure we use the same parameters as the remote side
- if (a2dp_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("a2dp_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- }
- config->format = out_get_format((const struct audio_stream*)&out->stream);
- config->sample_rate =
- out_get_sample_rate((const struct audio_stream*)&out->stream);
- config->channel_mask =
- out_get_channels((const struct audio_stream*)&out->stream);
-
- INFO(
- "Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x "
- "buffer_sz=%zu",
- config->format, config->sample_rate, config->channel_mask,
- out->common.buffer_sz);
- }
- *stream_out = &out->stream;
- a2dp_dev->output = out;
-
- DEBUG("success");
- /* Delay to ensure Headset is in proper state when START is initiated from
- * DUT immediately after the connection due to ongoing music playback. */
- usleep(250000);
- return 0;
-
-err_open:
- a2dp_stream_common_destroy(&out->common);
- free(out);
- *stream_out = NULL;
- a2dp_dev->output = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_out* out = (struct a2dp_stream_out*)stream;
-
- INFO("%s: state %d", __func__, out->common.state);
-
- // prevent interference with adev_set_parameters.
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- const a2dp_state_t state = out->common.state;
- INFO("closing output (state %d)", (int)state);
- if ((state == AUDIO_A2DP_STATE_STARTED) ||
- (state == AUDIO_A2DP_STATE_STOPPING)) {
- stop_audio_datapath(&out->common);
- }
-
- skt_disconnect(out->common.ctrl_fd);
- out->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- a2dp_stream_common_destroy(&out->common);
- free(stream);
- a2dp_dev->output = NULL;
-
- DEBUG("done");
-}
-
-static int adev_set_parameters(struct audio_hw_device* dev,
- const char* kvpairs) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- int retval = 0;
-
- // prevent interference with adev_close_output_stream
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- struct a2dp_stream_out* out = a2dp_dev->output;
-
- if (out == NULL) return retval;
-
- INFO("state %d", out->common.state);
-
- retval =
- out->stream.common.set_parameters((struct audio_stream*)out, kvpairs);
-
- return retval;
-}
-
-static char* adev_get_parameters(UNUSED_ATTR const struct audio_hw_device* dev,
- const char* keys) {
- FNLOG();
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- hash_map_utils_dump_string_keys_string_values(params);
-
- return strdup("");
-}
-
-static int adev_init_check(UNUSED_ATTR const struct audio_hw_device* dev) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_voice_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_master_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_mode(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR audio_mode_t mode) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_mic_mute(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR bool state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_get_mic_mute(UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR bool* state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static size_t adev_get_input_buffer_size(
- UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR const struct audio_config* config) {
- FNLOG();
-
- return 320;
-}
-
-static int adev_open_input_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR struct audio_config* config,
- struct audio_stream_in** stream_in,
- UNUSED_ATTR audio_input_flags_t flags,
- UNUSED_ATTR const char* address,
- UNUSED_ATTR audio_source_t source) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_in* in;
- int ret;
-
- FNLOG();
-
- // protect against adev->input and stream_in from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- in = (struct a2dp_stream_in*)calloc(1, sizeof(struct a2dp_stream_in));
-
- if (!in) return -ENOMEM;
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- /* initialize a2dp specifics */
- a2dp_stream_common_init(&in->common);
-
- *stream_in = &in->stream;
- a2dp_dev->input = in;
-
- if (a2dp_read_input_audio_config(&in->common) < 0) {
- ERROR("a2dp_read_input_audio_config failed (%s)", strerror(errno));
- ret = -1;
- goto err_open;
- }
- // a2dp_read_input_audio_config() opens socket control path (or fails)
-
- DEBUG("success");
- return 0;
-
-err_open:
- a2dp_stream_common_destroy(&in->common);
- free(in);
- *stream_in = NULL;
- a2dp_dev->input = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* stream) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)dev;
- struct a2dp_stream_in* in = (struct a2dp_stream_in*)stream;
-
- std::lock_guard<std::recursive_mutex> lock(*a2dp_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*in->common.mutex);
- const a2dp_state_t state = in->common.state;
- INFO("closing input (state %d)", (int)state);
-
- if ((state == AUDIO_A2DP_STATE_STARTED) ||
- (state == AUDIO_A2DP_STATE_STOPPING))
- stop_audio_datapath(&in->common);
-
- skt_disconnect(in->common.ctrl_fd);
- in->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- a2dp_stream_common_destroy(&in->common);
- free(stream);
- a2dp_dev->input = NULL;
-
- DEBUG("done");
-}
-
-static int adev_dump(UNUSED_ATTR const audio_hw_device_t* device,
- UNUSED_ATTR int fd) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_close(hw_device_t* device) {
- struct a2dp_audio_device* a2dp_dev = (struct a2dp_audio_device*)device;
- FNLOG();
-
- delete a2dp_dev->mutex;
- a2dp_dev->mutex = nullptr;
- free(device);
- return 0;
-}
-
-static int adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- struct a2dp_audio_device* adev;
-
- INFO(" adev_open in A2dp_hw module");
- FNLOG();
-
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
- ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
- return -EINVAL;
- }
-
- adev = (struct a2dp_audio_device*)calloc(1, sizeof(struct a2dp_audio_device));
-
- if (!adev) return -ENOMEM;
-
- adev->mutex = new std::recursive_mutex;
-
- adev->device.common.tag = HARDWARE_DEVICE_TAG;
- adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->device.common.module = (struct hw_module_t*)module;
- adev->device.common.close = adev_close;
-
- adev->device.init_check = adev_init_check;
- adev->device.set_voice_volume = adev_set_voice_volume;
- adev->device.set_master_volume = adev_set_master_volume;
- adev->device.set_mode = adev_set_mode;
- adev->device.set_mic_mute = adev_set_mic_mute;
- adev->device.get_mic_mute = adev_get_mic_mute;
- adev->device.set_parameters = adev_set_parameters;
- adev->device.get_parameters = adev_get_parameters;
- adev->device.get_input_buffer_size = adev_get_input_buffer_size;
- adev->device.open_output_stream = adev_open_output_stream;
- adev->device.close_output_stream = adev_close_output_stream;
- adev->device.open_input_stream = adev_open_input_stream;
- adev->device.close_input_stream = adev_close_input_stream;
- adev->device.dump = adev_dump;
-
- adev->output = NULL;
-
- *device = &adev->device.common;
-
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-__attribute__((
- visibility("default"))) struct audio_module HAL_MODULE_INFO_SYM = {
- .common =
- {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 1,
- .version_minor = 0,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "A2DP Audio HW HAL",
- .author = "The Android Open Source Project",
- .methods = &hal_module_methods,
- },
-};
diff --git a/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc b/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc
deleted file mode 100644
index b4115c6..0000000
--- a/audio_a2dp_hw/src/audio_a2dp_hw_utils.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2009-2012 Broadcom Corporation
- *
- * 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 "audio_a2dp_hw.h"
-#include "osi/include/properties.h"
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-const char* audio_a2dp_hw_dump_ctrl_event(tA2DP_CTRL_CMD event) {
- switch (event) {
- CASE_RETURN_STR(A2DP_CTRL_CMD_NONE)
- CASE_RETURN_STR(A2DP_CTRL_CMD_CHECK_READY)
- CASE_RETURN_STR(A2DP_CTRL_CMD_START)
- CASE_RETURN_STR(A2DP_CTRL_CMD_STOP)
- CASE_RETURN_STR(A2DP_CTRL_CMD_SUSPEND)
- CASE_RETURN_STR(A2DP_CTRL_GET_INPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(A2DP_CTRL_GET_PRESENTATION_POSITION)
- }
-
- return "UNKNOWN A2DP_CTRL_CMD";
-}
-
-bool delay_reporting_enabled() {
- return !osi_property_get_bool("persist.bluetooth.disabledelayreports", false);
-}
diff --git a/audio_a2dp_hw/test/audio_a2dp_hw_test.cc b/audio_a2dp_hw/test/audio_a2dp_hw_test.cc
deleted file mode 100644
index 8fcbae5..0000000
--- a/audio_a2dp_hw/test/audio_a2dp_hw_test.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2017 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 <gtest/gtest.h>
-
-#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
-
-namespace {
-static uint32_t codec_sample_rate2value(
- btav_a2dp_codec_sample_rate_t codec_sample_rate) {
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- return 44100;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- return 48000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- return 88200;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- return 96000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- return 176400;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- return 192000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- return 16000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- return 24000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_bits_per_sample2value(
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample) {
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- return 16;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- return 24;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- return 32;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_channel_mode2value(
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- return 1;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- return 2;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- break;
- }
- return 0;
-}
-
-} // namespace
-
-class AudioA2dpHwTest : public ::testing::Test {
- protected:
- AudioA2dpHwTest() {}
-
- private:
-};
-
-TEST_F(AudioA2dpHwTest, test_compute_buffer_size) {
- const btav_a2dp_codec_sample_rate_t codec_sample_rate_array[] = {
- BTAV_A2DP_CODEC_SAMPLE_RATE_NONE, BTAV_A2DP_CODEC_SAMPLE_RATE_44100,
- BTAV_A2DP_CODEC_SAMPLE_RATE_48000, BTAV_A2DP_CODEC_SAMPLE_RATE_88200,
- BTAV_A2DP_CODEC_SAMPLE_RATE_96000, BTAV_A2DP_CODEC_SAMPLE_RATE_176400,
- BTAV_A2DP_CODEC_SAMPLE_RATE_192000};
-
- const btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample_array[] = {
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16,
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32};
-
- const btav_a2dp_codec_channel_mode_t codec_channel_mode_array[] = {
- BTAV_A2DP_CODEC_CHANNEL_MODE_NONE, BTAV_A2DP_CODEC_CHANNEL_MODE_MONO,
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO};
-
- for (const auto codec_sample_rate : codec_sample_rate_array) {
- for (const auto codec_bits_per_sample : codec_bits_per_sample_array) {
- for (const auto codec_channel_mode : codec_channel_mode_array) {
- size_t buffer_size = audio_a2dp_hw_stream_compute_buffer_size(
- codec_sample_rate, codec_bits_per_sample, codec_channel_mode);
-
- // Check for invalid input
- if ((codec_sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) ||
- (codec_bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) ||
- (codec_channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE)) {
- EXPECT_EQ(buffer_size,
- static_cast<size_t>(AUDIO_STREAM_OUTPUT_BUFFER_SZ));
- continue;
- }
-
- uint32_t sample_rate = codec_sample_rate2value(codec_sample_rate);
- EXPECT_TRUE(sample_rate != 0);
-
- uint32_t bits_per_sample =
- codec_bits_per_sample2value(codec_bits_per_sample);
- EXPECT_TRUE(bits_per_sample != 0);
-
- uint32_t number_of_channels =
- codec_channel_mode2value(codec_channel_mode);
- EXPECT_TRUE(number_of_channels != 0);
-
- const uint64_t time_period_ms = 20; // TODO: Must be a parameter
- size_t expected_buffer_size =
- (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * sample_rate *
- number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Compute the divisor and adjust the buffer size
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
- const size_t remainder = expected_buffer_size % divisor;
- if (remainder != 0) {
- expected_buffer_size += divisor - remainder;
- }
-
- EXPECT_EQ(buffer_size, expected_buffer_size);
- }
- }
- }
-}
diff --git a/audio_bluetooth_hw/Android.bp b/audio_bluetooth_hw/Android.bp
deleted file mode 100644
index e52f1db..0000000
--- a/audio_bluetooth_hw/Android.bp
+++ /dev/null
@@ -1,59 +0,0 @@
-// The format of the name is audio.<type>.<hardware/etc>.so
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_library_shared {
- name: "audio.bluetooth.default",
- relative_install_path: "hw",
- proprietary: true,
- srcs: [
- "audio_bluetooth_hw.cc",
- "stream_apis.cc",
- "device_port_proxy.cc",
- "utils.cc",
- ],
- header_libs: ["libhardware_headers"],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libaudioutils",
- "libbase",
- "libbluetooth_audio_session",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- ],
-}
-
-cc_test {
- name: "audio_bluetooth_hw_test",
- srcs: [
- "utils.cc",
- "utils_unittest.cc",
- ],
- shared_libs: [
- "libbase",
- "libcutils",
- "liblog",
- "libutils",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- ],
-}
diff --git a/audio_bluetooth_hw/audio_bluetooth_hw.cc b/audio_bluetooth_hw/audio_bluetooth_hw.cc
deleted file mode 100644
index 887c4e3..0000000
--- a/audio_bluetooth_hw/audio_bluetooth_hw.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2019 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 "BTAudioHw"
-
-#include <android-base/logging.h>
-#include <errno.h>
-#include <hardware/hardware.h>
-#include <log/log.h>
-#include <malloc.h>
-#include <string.h>
-#include <system/audio.h>
-
-#include "stream_apis.h"
-#include "utils.h"
-
-using ::android::bluetooth::audio::utils::GetAudioParamString;
-using ::android::bluetooth::audio::utils::ParseAudioParams;
-
-static int adev_set_parameters(struct audio_hw_device* dev,
- const char* kvpairs) {
- LOG(VERBOSE) << __func__ << ": kevpairs=[" << kvpairs << "]";
- std::unordered_map<std::string, std::string> params =
- ParseAudioParams(kvpairs);
- if (params.empty()) return 0;
-
- LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
- << "]";
- if (params.find("A2dpSuspended") == params.end()) {
- return -ENOSYS;
- }
-
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
- std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
- for (auto sout : bluetooth_device->opened_stream_outs_) {
- if (sout->stream_out_.common.set_parameters != nullptr) {
- sout->stream_out_.common.set_parameters(&sout->stream_out_.common,
- kvpairs);
- }
- }
- return 0;
-}
-
-static char* adev_get_parameters(const struct audio_hw_device* dev,
- const char* keys) {
- LOG(VERBOSE) << __func__ << ": keys=[" << keys << "]";
- return strdup("");
-}
-
-static int adev_init_check(const struct audio_hw_device* dev) { return 0; }
-
-static int adev_set_voice_volume(struct audio_hw_device* dev, float volume) {
- LOG(VERBOSE) << __func__ << ": volume=" << volume;
- return -ENOSYS;
-}
-
-static int adev_set_master_volume(struct audio_hw_device* dev, float volume) {
- LOG(VERBOSE) << __func__ << ": volume=" << volume;
- return -ENOSYS;
-}
-
-static int adev_get_master_volume(struct audio_hw_device* dev, float* volume) {
- return -ENOSYS;
-}
-
-static int adev_set_master_mute(struct audio_hw_device* dev, bool muted) {
- LOG(VERBOSE) << __func__ << ": mute=" << muted;
- return -ENOSYS;
-}
-
-static int adev_get_master_mute(struct audio_hw_device* dev, bool* muted) {
- return -ENOSYS;
-}
-
-static int adev_set_mode(struct audio_hw_device* dev, audio_mode_t mode) {
- LOG(VERBOSE) << __func__ << ": mode=" << mode;
- return 0;
-}
-
-static int adev_set_mic_mute(struct audio_hw_device* dev, bool state) {
- LOG(VERBOSE) << __func__ << ": state=" << state;
- return -ENOSYS;
-}
-
-static int adev_get_mic_mute(const struct audio_hw_device* dev, bool* state) {
- return -ENOSYS;
-}
-
-static int adev_dump(const audio_hw_device_t* device, int fd) { return 0; }
-
-static int adev_close(hw_device_t* device) {
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(device);
- delete bluetooth_device;
- return 0;
-}
-
-static int adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- LOG(VERBOSE) << __func__ << ": name=[" << name << "]";
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL;
-
- auto bluetooth_audio_device = new BluetoothAudioDevice{};
- struct audio_hw_device* adev = &bluetooth_audio_device->audio_device_;
- if (!adev) return -ENOMEM;
-
- adev->common.tag = HARDWARE_DEVICE_TAG;
- adev->common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->common.module = (struct hw_module_t*)module;
- adev->common.close = adev_close;
-
- adev->init_check = adev_init_check;
- adev->set_voice_volume = adev_set_voice_volume;
- adev->set_master_volume = adev_set_master_volume;
- adev->get_master_volume = adev_get_master_volume;
- adev->set_mode = adev_set_mode;
- adev->set_mic_mute = adev_set_mic_mute;
- adev->get_mic_mute = adev_get_mic_mute;
- adev->set_parameters = adev_set_parameters;
- adev->get_parameters = adev_get_parameters;
- adev->get_input_buffer_size = adev_get_input_buffer_size;
- adev->open_output_stream = adev_open_output_stream;
- adev->close_output_stream = adev_close_output_stream;
- adev->open_input_stream = adev_open_input_stream;
- adev->close_input_stream = adev_close_input_stream;
- adev->dump = adev_dump;
- adev->set_master_mute = adev_set_master_mute;
- adev->get_master_mute = adev_get_master_mute;
-
- *device = &adev->common;
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-struct audio_module HAL_MODULE_INFO_SYM = {
- .common =
- {
- .tag = HARDWARE_MODULE_TAG,
- .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
- .hal_api_version = HARDWARE_HAL_API_VERSION,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "Bluetooth Audio HW HAL",
- .author = "The Android Open Source Project",
- .methods = &hal_module_methods,
- },
-};
diff --git a/audio_bluetooth_hw/device_port_proxy.cc b/audio_bluetooth_hw/device_port_proxy.cc
deleted file mode 100644
index afa8742..0000000
--- a/audio_bluetooth_hw/device_port_proxy.cc
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Copyright 2019 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 "BTAudioHalDeviceProxy"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <audio_utils/primitives.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <stdlib.h>
-
-#include "BluetoothAudioSessionControl_2_1.h"
-#include "device_port_proxy.h"
-#include "stream_apis.h"
-#include "utils.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using ::android::base::StringPrintf;
-using ::android::bluetooth::audio::BluetoothAudioSessionControl_2_1;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
-using SampleRate = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-using BluetoothAudioStatus =
- ::android::hardware::bluetooth::audio::V2_0::Status;
-using ControlResultCallback = std::function<void(
- uint16_t cookie, bool start_resp, const BluetoothAudioStatus& status)>;
-using SessionChangedCallback = std::function<void(uint16_t cookie)>;
-
-namespace {
-
-unsigned int SampleRateToAudioFormat(SampleRate_2_1 sample_rate) {
- switch (sample_rate) {
- case SampleRate_2_1::RATE_8000:
- return 8000;
- case SampleRate_2_1::RATE_16000:
- return 16000;
- case SampleRate_2_1::RATE_24000:
- return 24000;
- case SampleRate_2_1::RATE_32000:
- return 32000;
- case SampleRate_2_1::RATE_44100:
- return 44100;
- case SampleRate_2_1::RATE_48000:
- return 48000;
- case SampleRate_2_1::RATE_88200:
- return 88200;
- case SampleRate_2_1::RATE_96000:
- return 96000;
- case SampleRate_2_1::RATE_176400:
- return 176400;
- case SampleRate_2_1::RATE_192000:
- return 192000;
- default:
- return kBluetoothDefaultSampleRate;
- }
-}
-audio_channel_mask_t OutputChannelModeToAudioFormat(ChannelMode channel_mode) {
- switch (channel_mode) {
- case ChannelMode::MONO:
- return AUDIO_CHANNEL_OUT_MONO;
- case ChannelMode::STEREO:
- return AUDIO_CHANNEL_OUT_STEREO;
- default:
- return kBluetoothDefaultOutputChannelModeMask;
- }
-}
-
-audio_channel_mask_t InputChannelModeToAudioFormat(ChannelMode channel_mode) {
- switch (channel_mode) {
- case ChannelMode::MONO:
- return AUDIO_CHANNEL_IN_MONO;
- case ChannelMode::STEREO:
- return AUDIO_CHANNEL_IN_STEREO;
- default:
- return kBluetoothDefaultInputChannelModeMask;
- }
-}
-
-audio_format_t BitsPerSampleToAudioFormat(BitsPerSample bits_per_sample) {
- switch (bits_per_sample) {
- case BitsPerSample::BITS_16:
- return AUDIO_FORMAT_PCM_16_BIT;
- case BitsPerSample::BITS_24:
- return AUDIO_FORMAT_PCM_24_BIT_PACKED;
- case BitsPerSample::BITS_32:
- return AUDIO_FORMAT_PCM_32_BIT;
- default:
- return kBluetoothDefaultAudioFormatBitsPerSample;
- }
-}
-
-// The maximum time to wait in std::condition_variable::wait_for()
-constexpr unsigned int kMaxWaitingTimeMs = 4500;
-
-} // namespace
-
-BluetoothAudioPort::BluetoothAudioPort()
- : cookie_(android::bluetooth::audio::kObserversCookieUndefined),
- state_(BluetoothStreamState::DISABLED),
- session_type_(SessionType_2_1::UNKNOWN) {}
-
-bool BluetoothAudioPort::SetUp(audio_devices_t devices) {
- if (!init_session_type(devices)) return false;
-
- state_ = BluetoothStreamState::STANDBY;
-
- auto control_result_cb = [port = this](uint16_t cookie, bool start_resp,
- const BluetoothAudioStatus& status) {
- if (!port->in_use()) {
- LOG(ERROR) << "control_result_cb: BluetoothAudioPort is not in use";
- return;
- }
- if (port->cookie_ != cookie) {
- LOG(ERROR) << "control_result_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
- << ") is corrupted";
- return;
- }
- port->ControlResultHandler(status);
- };
- auto session_changed_cb = [port = this](uint16_t cookie) {
- if (!port->in_use()) {
- LOG(ERROR) << "session_changed_cb: BluetoothAudioPort is not in use";
- return;
- }
- if (port->cookie_ != cookie) {
- LOG(ERROR) << "session_changed_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
- << ") is corrupted";
- return;
- }
- port->SessionChangedHandler();
- };
- ::android::bluetooth::audio::PortStatusCallbacks cbacks = {
- .control_result_cb_ = control_result_cb,
- .session_changed_cb_ = session_changed_cb};
- cookie_ = BluetoothAudioSessionControl_2_1::RegisterControlResultCback(
- session_type_, cbacks);
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
-
- return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
-}
-
-bool BluetoothAudioPort::init_session_type(audio_devices_t device) {
- switch (device) {
- case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
- case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
- case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
- LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_BLUETOOTH_A2DP (HEADPHONES/SPEAKER) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_OUT_HEARING_AID:
- LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_HEARING_AID (MEDIA/VOICE) (" << StringPrintf("%#x", device)
- << ")";
- session_type_ = SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_OUT_BLE_HEADSET:
- LOG(VERBOSE) << __func__
- << ": device=AUDIO_DEVICE_OUT_BLE_HEADSET (MEDIA/VOICE) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_OUT_BLE_SPEAKER:
- LOG(VERBOSE) << __func__
- << ": device=AUDIO_DEVICE_OUT_BLE_SPEAKER (MEDIA) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH;
- break;
- case AUDIO_DEVICE_IN_BLE_HEADSET:
- LOG(VERBOSE) << __func__
- << ": device=AUDIO_DEVICE_IN_BLE_HEADSET (VOICE) ("
- << StringPrintf("%#x", device) << ")";
- session_type_ = SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH;
- break;
- default:
- LOG(ERROR) << __func__ << ": unknown device=" << StringPrintf("%#x", device);
- return false;
- }
-
- if (!BluetoothAudioSessionControl_2_1::IsSessionReady(session_type_)) {
- LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device) << ", session_type=" << toString(session_type_)
- << " is not ready";
- return false;
- }
- return true;
-}
-
-void BluetoothAudioPort::TearDown() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " unknown monitor";
- return;
- }
-
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
- BluetoothAudioSessionControl_2_1::UnregisterControlResultCback(session_type_,
- cookie_);
- cookie_ = android::bluetooth::audio::kObserversCookieUndefined;
-}
-
-void BluetoothAudioPort::ControlResultHandler(
- const BluetoothAudioStatus& status) {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortis not in use";
- return;
- }
- std::unique_lock<std::mutex> port_lock(cv_mutex_);
- BluetoothStreamState previous_state = state_;
- LOG(INFO) << "control_result_cb: session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state
- << ", status=" << toString(status);
-
- switch (previous_state) {
- case BluetoothStreamState::STARTING:
- if (status == BluetoothAudioStatus::SUCCESS) {
- state_ = BluetoothStreamState::STARTED;
- } else {
- // Set to standby since the stack may be busy switching between outputs
- LOG(WARNING) << "control_result_cb: status=" << toString(status)
- << " failure for session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
- state_ = BluetoothStreamState::STANDBY;
- }
- break;
- case BluetoothStreamState::SUSPENDING:
- if (status == BluetoothAudioStatus::SUCCESS) {
- state_ = BluetoothStreamState::STANDBY;
- } else {
- // It will be failed if the headset is disconnecting, and set to disable
- // to wait for re-init again
- LOG(WARNING) << "control_result_cb: status=" << toString(status)
- << " failure for session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
- state_ = BluetoothStreamState::DISABLED;
- }
- break;
- default:
- LOG(ERROR) << "control_result_cb: unexpected status=" << toString(status)
- << " for session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", previous_state=" << previous_state;
- return;
- }
- port_lock.unlock();
- internal_cv_.notify_all();
-}
-
-void BluetoothAudioPort::SessionChangedHandler() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return;
- }
- std::unique_lock<std::mutex> port_lock(cv_mutex_);
- BluetoothStreamState previous_state = state_;
- LOG(INFO) << "session_changed_cb: session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
- if (previous_state != BluetoothStreamState::DISABLED) {
- state_ = BluetoothStreamState::DISABLED;
- } else {
- state_ = BluetoothStreamState::STANDBY;
- }
- port_lock.unlock();
- internal_cv_.notify_all();
-}
-
-bool BluetoothAudioPort::in_use() const {
- return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
-}
-
-bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
-
- const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
- hal_audio_cfg =
- BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_);
- if (hal_audio_cfg.getDiscriminator() !=
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
- hidl_discriminator::pcmConfig) {
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
- const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg =
- hal_audio_cfg.pcmConfig();
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << ", PcmConfig=["
- << toString(pcm_cfg) << "]";
- if (pcm_cfg.sampleRate == SampleRate_2_1::RATE_UNKNOWN ||
- pcm_cfg.channelMode == ChannelMode::UNKNOWN ||
- pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- return false;
- }
- audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate);
- audio_cfg->channel_mask =
- (is_stereo_to_mono_
- ? AUDIO_CHANNEL_OUT_STEREO
- : OutputChannelModeToAudioFormat(pcm_cfg.channelMode));
- audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample);
- return true;
-}
-
-bool BluetoothAudioPortIn::LoadAudioConfig(audio_config_t* audio_cfg) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPortIn is not in use";
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
-
- const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
- hal_audio_cfg =
- BluetoothAudioSessionControl_2_1::GetAudioConfig(session_type_);
- if (hal_audio_cfg.getDiscriminator() !=
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
- hidl_discriminator::pcmConfig) {
- audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
- audio_cfg->channel_mask = kBluetoothDefaultInputChannelModeMask;
- audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
- return false;
- }
- const ::android::hardware::bluetooth::audio::V2_1::PcmParameters& pcm_cfg =
- hal_audio_cfg.pcmConfig();
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << ", PcmConfig=[" << toString(pcm_cfg)
- << "]";
- if (pcm_cfg.sampleRate == SampleRate_2_1::RATE_UNKNOWN ||
- pcm_cfg.channelMode == ChannelMode::UNKNOWN ||
- pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- return false;
- }
-
- audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate);
- audio_cfg->channel_mask = InputChannelModeToAudioFormat(pcm_cfg.channelMode);
- audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample);
- return true;
-}
-
-bool BluetoothAudioPort::CondwaitState(BluetoothStreamState state) {
- bool retval;
- std::unique_lock<std::mutex> port_lock(cv_mutex_);
- switch (state) {
- case BluetoothStreamState::STARTING:
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for STARTED";
- retval = internal_cv_.wait_for(
- port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
- [this] { return this->state_ != BluetoothStreamState::STARTING; });
- retval = retval && state_ == BluetoothStreamState::STARTED;
- break;
- case BluetoothStreamState::SUSPENDING:
- LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for SUSPENDED";
- retval = internal_cv_.wait_for(
- port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
- [this] { return this->state_ != BluetoothStreamState::SUSPENDING; });
- retval = retval && state_ == BluetoothStreamState::STANDBY;
- break;
- default:
- LOG(WARNING) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for KNOWN";
- return false;
- }
-
- return retval; // false if any failure like timeout
-}
-
-bool BluetoothAudioPort::Start() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return false;
- }
-
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " request";
- bool retval = false;
- if (state_ == BluetoothStreamState::STANDBY) {
- state_ = BluetoothStreamState::STARTING;
- if (BluetoothAudioSessionControl_2_1::StartStream(session_type_)) {
- retval = CondwaitState(BluetoothStreamState::STARTING);
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
- }
- }
-
- if (retval) {
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_
- << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " done";
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " failure";
- }
-
- return retval; // false if any failure like timeout
-}
-
-bool BluetoothAudioPort::Suspend() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return false;
- }
-
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << " request";
- bool retval = false;
- if (state_ == BluetoothStreamState::STARTED) {
- state_ = BluetoothStreamState::SUSPENDING;
- if (BluetoothAudioSessionControl_2_1::SuspendStream(session_type_)) {
- retval = CondwaitState(BluetoothStreamState::SUSPENDING);
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
- }
- }
-
- if (retval) {
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " done";
- } else {
- LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " failure";
- }
-
- return retval; // false if any failure like timeout
-}
-
-void BluetoothAudioPort::Stop() {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return;
- }
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << " request";
- state_ = BluetoothStreamState::DISABLED;
- BluetoothAudioSessionControl_2_1::StopStream(session_type_);
- LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << " done";
-}
-
-size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const {
- if (!in_use()) return 0;
- if (!is_stereo_to_mono_) {
- return BluetoothAudioSessionControl_2_1::OutWritePcmData(session_type_,
- buffer, bytes);
- }
-
- // WAR to mix the stereo into Mono (16 bits per sample)
- const size_t write_frames = bytes >> 2;
- if (write_frames == 0) return 0;
- auto src = static_cast<const int16_t*>(buffer);
- std::unique_ptr<int16_t[]> dst{new int16_t[write_frames]};
- downmix_to_mono_i16_from_stereo_i16(dst.get(), src, write_frames);
- // a frame is 16 bits, and the size of a mono frame is equal to half a stereo.
- return BluetoothAudioSessionControl_2_1::OutWritePcmData(
- session_type_, dst.get(), write_frames * 2) *
- 2;
-}
-
-size_t BluetoothAudioPortIn::ReadData(void* buffer, size_t bytes) const {
- if (!in_use()) return 0;
- return BluetoothAudioSessionControl_2_1::InReadPcmData(session_type_, buffer,
- bytes);
-}
-
-bool BluetoothAudioPort::GetPresentationPosition(uint64_t* delay_ns,
- uint64_t* bytes,
- timespec* timestamp) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return false;
- }
- bool retval = BluetoothAudioSessionControl_2_1::GetPresentationPosition(
- session_type_, delay_ns, bytes, timestamp);
- LOG(VERBOSE) << __func__ << ": session_type=" << StringPrintf("%#hhx", session_type_)
- << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << ", delay=" << *delay_ns
- << "ns, data=" << *bytes << " bytes, timestamp=" << timestamp->tv_sec << "."
- << StringPrintf("%09ld", timestamp->tv_nsec) << "s";
-
- return retval;
-}
-
-void BluetoothAudioPort::UpdateMetadata(
- const source_metadata* source_metadata) const {
- if (!in_use()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioPort is not in use";
- return;
- }
- LOG(DEBUG) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
- << ", state=" << state_ << ", " << source_metadata->track_count << " track(s)";
- if (source_metadata->track_count == 0) return;
- BluetoothAudioSessionControl_2_1::UpdateTracksMetadata(session_type_,
- source_metadata);
-}
-
-BluetoothStreamState BluetoothAudioPort::GetState() const { return state_; }
-
-void BluetoothAudioPort::SetState(BluetoothStreamState state) {
- state_ = state;
-}
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/device_port_proxy.h b/audio_bluetooth_hw/device_port_proxy.h
deleted file mode 100644
index 9e11392..0000000
--- a/audio_bluetooth_hw/device_port_proxy.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2019 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.1/types.h>
-#include <hardware/audio.h>
-#include <condition_variable>
-#include <mutex>
-#include <unordered_map>
-
-enum class BluetoothStreamState : uint8_t;
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
-
-// Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio
-// Session Control. All methods are not thread safe, so users must acquire a
-// lock. Note: currently, in stream_apis.cc, if GetState() is only used for
-// verbose logging, it is not locked, so the state may not be synchronized.
-class BluetoothAudioPort {
- public:
- BluetoothAudioPort();
- virtual ~BluetoothAudioPort() = default;
-
- // Fetch output control / data path of BluetoothAudioPort and setup
- // callbacks into BluetoothAudioProvider. If SetUp() returns false, the audio
- // HAL must delete this BluetoothAudioPort and return EINVAL to caller
- bool SetUp(audio_devices_t devices);
-
- // Unregister this BluetoothAudioPort from BluetoothAudioSessionControl.
- // Audio HAL must delete this BluetoothAudioPort after calling this.
- void TearDown();
-
- // When the Audio framework / HAL tries to query audio config about format,
- // channel mask and sample rate, it uses this function to fetch from the
- // Bluetooth stack
- virtual bool LoadAudioConfig(audio_config_t* audio_cfg) const = 0;
-
- // WAR to support Mono mode / 16 bits per sample
- void ForcePcmStereoToMono(bool force) {
- is_stereo_to_mono_ = force;
- }
-
- // When the Audio framework / HAL wants to change the stream state, it invokes
- // these 3 functions to control the Bluetooth stack (Audio Control Path).
- // Note: Both Start() and Suspend() will return ture when there are no errors.
- // Called by Audio framework / HAL to start the stream
- bool Start();
- // Called by Audio framework / HAL to suspend the stream
- bool Suspend();
- // Called by Audio framework / HAL to stop the stream
- void Stop();
-
- // Called by the Audio framework / HAL to fetch informaiton about audio frames
- // presented to an external sink, or frames presented fror an internal sink
- bool GetPresentationPosition(uint64_t* delay_ns, uint64_t* bytes,
- timespec* timestamp) const;
-
- // Called by the Audio framework / HAL when the metadata of the stream's
- // source has been changed.
- void UpdateMetadata(const source_metadata* source_metadata) const;
-
- // Return the current BluetoothStreamState
- BluetoothStreamState GetState() const;
-
- // Set the current BluetoothStreamState
- void SetState(BluetoothStreamState state);
-
- bool IsA2dp() const {
- return session_type_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH;
- }
-
- protected:
- uint16_t cookie_;
- BluetoothStreamState state_;
- SessionType_2_1 session_type_;
- // WR to support Mono: True if fetching Stereo and mixing into Mono
- bool is_stereo_to_mono_ = false;
- bool in_use() const;
-
- private:
- mutable std::mutex cv_mutex_;
- std::condition_variable internal_cv_;
-
- // Check and initialize session type for |devices| If failed, this
- // BluetoothAudioPort is not initialized and must be deleted.
- bool init_session_type(audio_devices_t device);
-
- bool CondwaitState(BluetoothStreamState state);
-
- void ControlResultHandler(
- const ::android::hardware::bluetooth::audio::V2_0::Status& status);
- void SessionChangedHandler();
-};
-
-class BluetoothAudioPortOut : public BluetoothAudioPort {
- public:
- ~BluetoothAudioPortOut() = default;
-
- // The audio data path to the Bluetooth stack (Software encoding)
- size_t WriteData(const void* buffer, size_t bytes) const;
- bool LoadAudioConfig(audio_config_t* audio_cfg) const;
-};
-
-class BluetoothAudioPortIn : public BluetoothAudioPort {
- public:
- ~BluetoothAudioPortIn() = default;
-
- // The audio data path from the Bluetooth stack (Software decoded)
- size_t ReadData(void* buffer, size_t bytes) const;
- bool LoadAudioConfig(audio_config_t* audio_cfg) const;
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/stream_apis.cc b/audio_bluetooth_hw/stream_apis.cc
deleted file mode 100644
index f202d7bc..0000000
--- a/audio_bluetooth_hw/stream_apis.cc
+++ /dev/null
@@ -1,1216 +0,0 @@
-/*
- * Copyright 2019 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 "BTAudioHalStream"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include <cutils/properties.h>
-#include <errno.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "stream_apis.h"
-#include "utils.h"
-
-using ::android::base::StringPrintf;
-using ::android::bluetooth::audio::BluetoothAudioPortOut;
-using ::android::bluetooth::audio::utils::GetAudioParamString;
-using ::android::bluetooth::audio::utils::ParseAudioParams;
-
-namespace {
-
-constexpr unsigned int kMinimumDelayMs = 50;
-constexpr unsigned int kMaximumDelayMs = 1000;
-constexpr int kExtraAudioSyncMs = 200;
-
-std::ostream& operator<<(std::ostream& os, const audio_config& config) {
- return os << "audio_config[sample_rate=" << config.sample_rate
- << ", channels=" << StringPrintf("%#x", config.channel_mask)
- << ", format=" << config.format << "]";
-}
-
-void out_calculate_feeding_delay_ms(const BluetoothStreamOut* out,
- uint32_t* latency_ms,
- uint64_t* frames = nullptr,
- struct timespec* timestamp = nullptr) {
- if (latency_ms == nullptr && frames == nullptr && timestamp == nullptr) {
- return;
- }
-
- // delay_report is the audio delay from the remote headset receiving data to
- // the headset playing sound in units of nanoseconds
- uint64_t delay_report_ns = 0;
- uint64_t delay_report_ms = 0;
- // absorbed_bytes is the total number of bytes sent by the Bluetooth stack to
- // a remote headset
- uint64_t absorbed_bytes = 0;
- // absorbed_timestamp is the ...
- struct timespec absorbed_timestamp = {};
- bool timestamp_fetched = false;
-
- std::unique_lock<std::mutex> lock(out->mutex_);
- if (out->bluetooth_output_.GetPresentationPosition(
- &delay_report_ns, &absorbed_bytes, &absorbed_timestamp)) {
- delay_report_ms = delay_report_ns / 1000000;
- // assume kMinimumDelayMs (50ms) < delay_report_ns < kMaximumDelayMs
- // (1000ms), or it is invalid / ignored and use old delay calculated
- // by ourselves.
- if (delay_report_ms > kMinimumDelayMs &&
- delay_report_ms < kMaximumDelayMs) {
- timestamp_fetched = true;
- } else if (delay_report_ms >= kMaximumDelayMs) {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", delay_report=" << delay_report_ns << "ns abnormal";
- }
- }
- if (!timestamp_fetched) {
- // default to old delay if any failure is found when fetching from ports
- // audio_a2dp_hw:
- // frames_count = buffer_size / frame_size
- // latency (sec.) = frames_count / samples_per_second (sample_rate)
- // Sync from audio_a2dp_hw to add extra delay kExtraAudioSyncMs(+200ms)
- delay_report_ms =
- out->frames_count_ * 1000 / out->sample_rate_ + kExtraAudioSyncMs;
- if (timestamp != nullptr) {
- clock_gettime(CLOCK_MONOTONIC, &absorbed_timestamp);
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " uses the legacy delay " << delay_report_ms << " ms";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", delay=" << delay_report_ms << "ms, data=" << absorbed_bytes
- << " bytes, timestamp=" << absorbed_timestamp.tv_sec << "."
- << StringPrintf("%09ld", absorbed_timestamp.tv_nsec) << "s";
-
- if (latency_ms != nullptr) {
- *latency_ms = delay_report_ms;
- }
- if (frames != nullptr) {
- const uint64_t latency_frames = delay_report_ms * out->sample_rate_ / 1000;
- *frames = absorbed_bytes / audio_stream_out_frame_size(&out->stream_out_);
- if (out->frames_presented_ < *frames) {
- // Are we (the audio HAL) reset?! The stack counter is obsoleted.
- *frames = out->frames_presented_;
- } else if ((out->frames_presented_ - *frames) > latency_frames) {
- // Is the Bluetooth output reset / restarted by AVDTP reconfig?! Its
- // counter was reset but could not be used.
- *frames = out->frames_presented_;
- }
- // suppose frames would be queued in the headset buffer for delay_report
- // period, so those frames in buffers should not be included in the number
- // of presented frames at the timestamp.
- if (*frames > latency_frames) {
- *frames -= latency_frames;
- } else {
- *frames = 0;
- }
- }
- if (timestamp != nullptr) {
- *timestamp = absorbed_timestamp;
- }
-}
-
-void in_calculate_starving_delay_ms(const BluetoothStreamIn* in,
- int64_t* frames, int64_t* time) {
- // delay_report is the audio delay from the remote headset receiving data to
- // the headset playing sound in units of nanoseconds
- uint64_t delay_report_ns = 0;
- uint64_t delay_report_ms = 0;
- // dispersed_bytes is the total number of bytes received by the Bluetooth
- // stack from a remote headset
- uint64_t dispersed_bytes = 0;
- struct timespec dispersed_timestamp = {};
-
- std::unique_lock<std::mutex> lock(in->mutex_);
- in->bluetooth_input_.GetPresentationPosition(
- &delay_report_ns, &dispersed_bytes, &dispersed_timestamp);
- delay_report_ms = delay_report_ns / 1000000;
-
- const uint64_t latency_frames = delay_report_ms * in->sample_rate_ / 1000;
- *frames = dispersed_bytes / audio_stream_in_frame_size(&in->stream_in_);
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", delay=" << delay_report_ms
- << "ms, data=" << dispersed_bytes
- << " bytes, timestamp=" << dispersed_timestamp.tv_sec << "."
- << StringPrintf("%09ld", dispersed_timestamp.tv_nsec) << "s";
-
- if (in->frames_presented_ < *frames) {
- // Was audio HAL reset?! The stack counter is obsoleted.
- *frames = in->frames_presented_;
- } else if ((in->frames_presented_ - *frames) > latency_frames) {
- // Is the Bluetooth input reset ?! Its counter was reset but could not be
- // used.
- *frames = in->frames_presented_;
- }
- // suppose frames would be queued in the headset buffer for delay_report
- // period, so those frames in buffers should not be included in the number
- // of presented frames at the timestamp.
- if (*frames > latency_frames) {
- *frames -= latency_frames;
- } else {
- *frames = 0;
- }
-
- *time = (dispersed_timestamp.tv_sec * 1000000000LL +
- dispersed_timestamp.tv_nsec) /
- 1000;
-}
-
-} // namespace
-
-std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state) {
- switch (state) {
- case BluetoothStreamState::DISABLED:
- return os << "DISABLED";
- case BluetoothStreamState::STANDBY:
- return os << "STANDBY";
- case BluetoothStreamState::STARTING:
- return os << "STARTING";
- case BluetoothStreamState::STARTED:
- return os << "STARTED";
- case BluetoothStreamState::SUSPENDING:
- return os << "SUSPENDING";
- case BluetoothStreamState::UNKNOWN:
- return os << "UNKNOWN";
- default:
- return os << StringPrintf("%#hhx", state);
- }
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.sample_rate;
- } else {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", sample_rate=" << out->sample_rate_ << " failed";
- return out->sample_rate_;
- }
-}
-
-static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", sample_rate=" << out->sample_rate_;
- return (rate == out->sample_rate_ ? 0 : -1);
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- size_t buffer_size =
- out->frames_count_ * audio_stream_out_frame_size(&out->stream_out_);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", buffer_size=" << buffer_size;
- return buffer_size;
-}
-
-static audio_channel_mask_t out_get_channels(
- const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.channel_mask;
- } else {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", channels=" << StringPrintf("%#x", out->channel_mask_) << " failure";
- return out->channel_mask_;
- }
-}
-
-static audio_format_t out_get_format(const struct audio_stream* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.format;
- } else {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", format=" << out->format_ << " failure";
- return out->format_;
- }
-}
-
-static int out_set_format(struct audio_stream* stream, audio_format_t format) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", format=" << out->format_;
- return (format == out->format_ ? 0 : -1);
-}
-
-static int out_standby(struct audio_stream* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
-
- // out->last_write_time_us_ = 0; unnecessary as a stale write time has same
- // effect
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " being standby (suspend)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
- out->frames_rendered_ = 0;
- retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT ready to be standby";
- retval = -EBUSY;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " standby already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " standby (suspend) retval=" << retval;
-
- return retval;
-}
-
-static int out_dump(const struct audio_stream* stream, int fd) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState();
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream* stream,
- const char* kvpairs) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", kvpairs=[" << kvpairs << "]";
-
- std::unordered_map<std::string, std::string> params =
- ParseAudioParams(kvpairs);
- if (params.empty()) return retval;
-
- LOG(VERBOSE) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
- << "]";
-
- audio_config_t audio_cfg;
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end() ||
- params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end() ||
- params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- out->sample_rate_ = audio_cfg.sample_rate;
- out->channel_mask_ = audio_cfg.channel_mask;
- out->format_ = audio_cfg.format;
- LOG(VERBOSE) << "state=" << out->bluetooth_output_.GetState() << ", sample_rate=" << out->sample_rate_
- << ", channels=" << StringPrintf("%#x", out->channel_mask_) << ", format=" << out->format_;
- } else {
- LOG(WARNING) << __func__
- << ": state=" << out->bluetooth_output_.GetState()
- << " failed to get audio config";
- }
- }
-
- if (params.find("routing") != params.end()) {
- auto routing_param = params.find("routing");
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", stream param '" << routing_param->first.c_str() << "="
- << routing_param->second.c_str() << "'";
- }
-
- if (params.find("A2dpSuspended") != params.end() &&
- out->bluetooth_output_.IsA2dp()) {
- if (params["A2dpSuspended"] == "true") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param stopped";
- out->frames_rendered_ = 0;
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
- out->bluetooth_output_.Suspend();
- out->bluetooth_output_.SetState(BluetoothStreamState::DISABLED);
- } else if (out->bluetooth_output_.GetState() !=
- BluetoothStreamState::DISABLED) {
- out->bluetooth_output_.Stop();
- }
- } else {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param standby";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::DISABLED) {
- out->bluetooth_output_.SetState(BluetoothStreamState::STANDBY);
- }
- }
- }
-
- if (params.find("closing") != params.end()) {
- if (params["closing"] == "true") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param closing, disallow any writes?";
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
- }
- }
- }
-
- if (params.find("exiting") != params.end()) {
- if (params["exiting"] == "1") {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " stream param exiting";
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
- }
- }
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", kvpairs=[" << kvpairs << "], retval=" << retval;
- return retval;
-}
-
-static char* out_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", keys=[" << keys << "]";
-
- std::unordered_map<std::string, std::string> params = ParseAudioParams(keys);
- if (params.empty()) return strdup("");
-
- audio_config_t audio_cfg;
- if (out->bluetooth_output_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " audio_cfg=" << audio_cfg;
- } else {
- LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " failed to get audio config";
- }
-
- std::unordered_map<std::string, std::string> return_params;
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) {
- std::string param;
- if (audio_cfg.sample_rate == 16000) {
- param = "16000";
- }
- if (audio_cfg.sample_rate == 24000) {
- param = "24000";
- }
- if (audio_cfg.sample_rate == 44100) {
- param = "44100";
- }
- if (audio_cfg.sample_rate == 48000) {
- param = "48000";
- }
- if (audio_cfg.sample_rate == 88200) {
- param = "88200";
- }
- if (audio_cfg.sample_rate == 96000) {
- param = "96000";
- }
- if (audio_cfg.sample_rate == 176400) {
- param = "176400";
- }
- if (audio_cfg.sample_rate == 192000) {
- param = "192000";
- }
- return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param;
- }
-
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) {
- std::string param;
- if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_MONO) {
- param = "AUDIO_CHANNEL_OUT_MONO";
- }
- if (audio_cfg.channel_mask == AUDIO_CHANNEL_OUT_STEREO) {
- param = "AUDIO_CHANNEL_OUT_STEREO";
- }
- return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param;
- }
-
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- std::string param;
- if (audio_cfg.format == AUDIO_FORMAT_PCM_16_BIT) {
- param = "AUDIO_FORMAT_PCM_16_BIT";
- }
- if (audio_cfg.format == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
- param = "AUDIO_FORMAT_PCM_24_BIT_PACKED";
- }
- if (audio_cfg.format == AUDIO_FORMAT_PCM_32_BIT) {
- param = "AUDIO_FORMAT_PCM_32_BIT";
- }
- return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param;
- }
-
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", result=[" << result << "]";
- return strdup(result.c_str());
-}
-
-static uint32_t out_get_latency_ms(const struct audio_stream_out* stream) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- uint32_t latency_ms = 0;
- out_calculate_feeding_delay_ms(out, &latency_ms);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", latency=" << latency_ms << "ms";
- return latency_ms;
-}
-
-static int out_set_volume(struct audio_stream_out* stream, float left,
- float right) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", Left=" << left << ", Right=" << right;
- return -1;
-}
-
-static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
- size_t bytes) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- size_t totalWritten = 0;
-
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::STARTED) {
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " first time bytes=" << bytes;
- lock.unlock();
- if (stream->resume(stream)) {
- LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " failed to resume";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::DISABLED) {
- // drop data for cases of A2dpSuspended=true / closing=true
- totalWritten = bytes;
- }
- usleep(kBluetoothDefaultOutputBufferMs * 1000);
- return totalWritten;
- }
- lock.lock();
- }
- lock.unlock();
- totalWritten = out->bluetooth_output_.WriteData(buffer, bytes);
- lock.lock();
-
- struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
- clock_gettime(CLOCK_MONOTONIC, &ts);
- if (totalWritten) {
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- out->frames_rendered_ += frames;
- out->frames_presented_ += frames;
- out->last_write_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
- } else {
- const int64_t now = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
- const int64_t elapsed_time_since_last_write =
- now - out->last_write_time_us_;
- // frames_count = written_data / frame_size
- // play_time (ms) = frames_count / (sample_rate (Sec.) / 1000000)
- // sleep_time (ms) = play_time - elapsed_time
- int64_t sleep_time = bytes * 1000000LL /
- audio_stream_out_frame_size(stream) /
- out_get_sample_rate(&stream->common) -
- elapsed_time_since_last_write;
- if (sleep_time > 0) {
- LOG(VERBOSE) << __func__ << ": sleep " << (sleep_time / 1000)
- << " ms when writting FMQ datapath";
- lock.unlock();
- usleep(sleep_time);
- lock.lock();
- } else {
- // we don't sleep when we exit standby (this is typical for a real alsa
- // buffer).
- sleep_time = 0;
- }
- out->last_write_time_us_ = now + sleep_time;
- }
- return totalWritten;
-}
-
-static int out_get_render_position(const struct audio_stream_out* stream,
- uint32_t* dsp_frames) {
- if (dsp_frames == nullptr) return -EINVAL;
-
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- // frames = (latency (ms) / 1000) * samples_per_second (sample_rate)
- const uint64_t latency_frames =
- (uint64_t)out_get_latency_ms(stream) * out->sample_rate_ / 1000;
- if (out->frames_rendered_ >= latency_frames) {
- *dsp_frames = (uint32_t)(out->frames_rendered_ - latency_frames);
- } else {
- *dsp_frames = 0;
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", dsp_frames=" << *dsp_frames;
- return 0;
-}
-
-static int out_add_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int out_remove_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int out_get_next_write_timestamp(const struct audio_stream_out* stream,
- int64_t* timestamp) {
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- *timestamp = 0;
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", timestamp=" << *timestamp;
- return -EINVAL;
-}
-
-static int out_pause(struct audio_stream_out* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", pausing (suspend)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STARTED) {
- out->frames_rendered_ = 0;
- retval = (out->bluetooth_output_.Suspend() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT ready to pause?!";
- retval = -EBUSY;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " paused already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", pausing (suspend) retval=" << retval;
-
- return retval;
-}
-
-static int out_resume(struct audio_stream_out* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- int retval = 0;
-
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", resuming (start)";
- if (out->bluetooth_output_.GetState() == BluetoothStreamState::STANDBY) {
- retval = (out->bluetooth_output_.Start() ? 0 : -EIO);
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::STARTING ||
- out->bluetooth_output_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT ready to resume?!";
- retval = -EBUSY;
- } else if (out->bluetooth_output_.GetState() ==
- BluetoothStreamState::DISABLED) {
- LOG(WARNING) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " NOT allow to resume?!";
- retval = -EINVAL;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " resumed already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", resuming (start) retval=" << retval;
-
- return retval;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out* stream,
- uint64_t* frames,
- struct timespec* timestamp) {
- if (frames == nullptr || timestamp == nullptr) {
- return -EINVAL;
- }
-
- const auto* out = reinterpret_cast<const BluetoothStreamOut*>(stream);
- out_calculate_feeding_delay_ms(out, nullptr, frames, timestamp);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", frames=" << *frames << ", timestamp=" << timestamp->tv_sec
- << "." << StringPrintf("%09ld", timestamp->tv_nsec) << "s";
- return 0;
-}
-
-static void out_update_source_metadata(
- struct audio_stream_out* stream,
- const struct source_metadata* source_metadata) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- std::unique_lock<std::mutex> lock(out->mutex_);
- if (source_metadata == nullptr || source_metadata->track_count == 0) {
- return;
- }
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", " << source_metadata->track_count << " track(s)";
- out->bluetooth_output_.UpdateMetadata(source_metadata);
-}
-
-static size_t samples_per_ticks(size_t milliseconds, uint32_t sample_rate,
- size_t channel_count) {
- return milliseconds * sample_rate * channel_count / 1000;
-}
-
-int adev_open_output_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- const char* address __unused) {
- *stream_out = nullptr;
- auto* out = new BluetoothStreamOut{};
- if (!out->bluetooth_output_.SetUp(devices)) {
- delete out;
- return -EINVAL;
- }
- LOG(VERBOSE) << __func__ << ": device=" << StringPrintf("%#x", devices);
-
- out->stream_out_.common.get_sample_rate = out_get_sample_rate;
- out->stream_out_.common.set_sample_rate = out_set_sample_rate;
- out->stream_out_.common.get_buffer_size = out_get_buffer_size;
- out->stream_out_.common.get_channels = out_get_channels;
- out->stream_out_.common.get_format = out_get_format;
- out->stream_out_.common.set_format = out_set_format;
- out->stream_out_.common.standby = out_standby;
- out->stream_out_.common.dump = out_dump;
- out->stream_out_.common.set_parameters = out_set_parameters;
- out->stream_out_.common.get_parameters = out_get_parameters;
- out->stream_out_.common.add_audio_effect = out_add_audio_effect;
- out->stream_out_.common.remove_audio_effect = out_remove_audio_effect;
- out->stream_out_.get_latency = out_get_latency_ms;
- out->stream_out_.set_volume = out_set_volume;
- out->stream_out_.write = out_write;
- out->stream_out_.get_render_position = out_get_render_position;
- out->stream_out_.get_next_write_timestamp = out_get_next_write_timestamp;
- out->stream_out_.pause = out_pause;
- out->stream_out_.resume = out_resume;
- out->stream_out_.get_presentation_position = out_get_presentation_position;
- out->stream_out_.update_source_metadata = out_update_source_metadata;
-
- if (!out->bluetooth_output_.LoadAudioConfig(config)) {
- LOG(ERROR) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << " failed to get audio config";
- }
- // WAR to support Mono / 16 bits per sample as the Bluetooth stack required
- if (config->channel_mask == AUDIO_CHANNEL_OUT_MONO && config->format == AUDIO_FORMAT_PCM_16_BIT) {
- LOG(INFO) << __func__ << ": force channels=" << StringPrintf("%#x", out->channel_mask_)
- << " to be AUDIO_CHANNEL_OUT_STEREO";
- out->bluetooth_output_.ForcePcmStereoToMono(true);
- config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- }
- out->sample_rate_ = config->sample_rate;
- out->channel_mask_ = config->channel_mask;
- out->format_ = config->format;
- // frame is number of samples per channel
- out->frames_count_ =
- samples_per_ticks(kBluetoothDefaultOutputBufferMs, out->sample_rate_, 1);
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
-
- {
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
- std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
- bluetooth_device->opened_stream_outs_.push_back(out);
- }
- *stream_out = &out->stream_out_;
- LOG(INFO) << __func__ << ": state=" << out->bluetooth_output_.GetState() << ", sample_rate=" << out->sample_rate_
- << ", channels=" << StringPrintf("%#x", out->channel_mask_) << ", format=" << out->format_
- << ", frames=" << out->frames_count_;
- return 0;
-}
-
-void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream) {
- auto* out = reinterpret_cast<BluetoothStreamOut*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", stopping";
- {
- auto* bluetooth_device = reinterpret_cast<BluetoothAudioDevice*>(dev);
- std::lock_guard<std::mutex> guard(bluetooth_device->mutex_);
- bluetooth_device->opened_stream_outs_.remove(out);
- }
- if (out->bluetooth_output_.GetState() != BluetoothStreamState::DISABLED) {
- out->frames_rendered_ = 0;
- out->frames_presented_ = 0;
- out->bluetooth_output_.Stop();
- }
- out->bluetooth_output_.TearDown();
- LOG(VERBOSE) << __func__ << ": state=" << out->bluetooth_output_.GetState()
- << ", stopped";
- delete out;
-}
-
-size_t adev_get_input_buffer_size(const struct audio_hw_device* dev,
- const struct audio_config* config) {
- /* TODO: Adjust this value */
- LOG(VERBOSE) << __func__;
- return 320;
-}
-
-static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
-
- return in->sample_rate_;
-}
-
-static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", sample_rate=" << in->sample_rate_;
- return (rate == in->sample_rate_ ? 0 : -ENOSYS);
-}
-
-static size_t in_get_buffer_size(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- size_t buffer_size =
- in->frames_count_ * audio_stream_in_frame_size(&in->stream_in_);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", buffer_size=" << buffer_size;
- return buffer_size;
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- audio_config_t audio_cfg;
- if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.channel_mask;
- } else {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", channels=" << StringPrintf("%#x", in->channel_mask_)
- << " failure";
- return in->channel_mask_;
- }
-}
-
-static audio_format_t in_get_format(const struct audio_stream* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- audio_config_t audio_cfg;
- if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " audio_cfg=" << audio_cfg;
- return audio_cfg.format;
- } else {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", format=" << in->format_ << " failure";
- return in->format_;
- }
-}
-
-static int in_set_format(struct audio_stream* stream, audio_format_t format) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", format=" << in->format_;
- return (format == in->format_ ? 0 : -ENOSYS);
-}
-
-static bool in_state_transition_timeout(BluetoothStreamIn* in,
- std::unique_lock<std::mutex>& lock,
- const BluetoothStreamState& state,
- uint16_t timeout_ms) {
- /* Don't loose suspend request, AF will not retry */
- while (in->bluetooth_input_.GetState() == state) {
- lock.unlock();
- usleep(1000);
- lock.lock();
-
- /* Don't block AF forever */
- if (--timeout_ms <= 0) {
- LOG(WARNING) << __func__ << ", can't suspend - stucked in: "
- << static_cast<int>(state) << " state";
- return false;
- }
- }
-
- return true;
-}
-
-static int in_standby(struct audio_stream* stream) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
- int retval = 0;
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " being standby (suspend)";
-
- /* Give some time to start up */
- if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING,
- kBluetoothDefaultInputStateTimeoutMs)) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT ready to by standby";
- return retval;
- }
-
- if (in->bluetooth_input_.GetState() == BluetoothStreamState::STARTED) {
- retval = (in->bluetooth_input_.Suspend() ? 0 : -EIO);
- } else if (in->bluetooth_input_.GetState() !=
- BluetoothStreamState::SUSPENDING) {
- LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " standby already";
- return retval;
- }
-
- /* Give some time to suspend */
- if (!in_state_transition_timeout(in, lock, BluetoothStreamState::SUSPENDING,
- kBluetoothDefaultInputStateTimeoutMs)) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT ready to by standby";
- return 0;
- }
-
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " standby (suspend) retval=" << retval;
-
- return retval;
-}
-
-static int in_dump(const struct audio_stream* stream, int fd) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_set_parameters(struct audio_stream* stream, const char* kvpairs) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
- int retval = 0;
-
- LOG(INFO) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
- << ", kvpairs=[" << kvpairs << "]";
-
- std::unordered_map<std::string, std::string> params =
- ParseAudioParams(kvpairs);
-
- if (params.empty()) return retval;
-
- LOG(INFO) << __func__ << ": ParamsMap=[" << GetAudioParamString(params)
- << "]";
-
- return retval;
-}
-
-static char* in_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
-
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState()
- << ", keys=[" << keys << "]";
-
- std::unordered_map<std::string, std::string> params = ParseAudioParams(keys);
- if (params.empty()) return strdup("");
-
- audio_config_t audio_cfg;
- if (in->bluetooth_input_.LoadAudioConfig(&audio_cfg)) {
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " audio_cfg=" << audio_cfg;
- } else {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " failed to get audio config";
- }
-
- std::unordered_map<std::string, std::string> return_params;
-
- /* TODO: Implement parameter getter */
-
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- return strdup(result.c_str());
-}
-
-static int in_add_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int in_remove_audio_effect(const struct audio_stream* stream,
- effect_handle_t effect) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", effect=" << effect;
- return 0;
-}
-
-static int in_set_gain(struct audio_stream_in* stream, float gain) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
- size_t bytes) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
- std::unique_lock<std::mutex> lock(in->mutex_);
- size_t totalRead = 0;
-
- /* Give some time to start up */
- if (!in_state_transition_timeout(in, lock, BluetoothStreamState::STARTING,
- kBluetoothDefaultInputStateTimeoutMs))
- return -EBUSY;
-
- if (in->bluetooth_input_.GetState() != BluetoothStreamState::STARTED) {
- LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " first time bytes=" << bytes;
-
- int retval = 0;
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", starting";
- if (in->bluetooth_input_.GetState() == BluetoothStreamState::STANDBY) {
- retval = (in->bluetooth_input_.Start() ? 0 : -EIO);
- } else if (in->bluetooth_input_.GetState() ==
- BluetoothStreamState::SUSPENDING) {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT ready to start?!";
- retval = -EBUSY;
- } else if (in->bluetooth_input_.GetState() ==
- BluetoothStreamState::DISABLED) {
- LOG(WARNING) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " NOT allow to start?!";
- retval = -EINVAL;
- } else {
- LOG(DEBUG) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " started already";
- }
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", starting (start) retval=" << retval;
-
- if (retval) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " failed to start";
- return retval;
- }
- }
-
- lock.unlock();
- totalRead = in->bluetooth_input_.ReadData(buffer, bytes);
- lock.lock();
-
- struct timespec ts = {.tv_sec = 0, .tv_nsec = 0};
- clock_gettime(CLOCK_MONOTONIC, &ts);
- in->last_read_time_us_ = (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000;
-
- const size_t frames = totalRead / audio_stream_in_frame_size(stream);
- in->frames_presented_ += frames;
-
- return totalRead;
-}
-
-static uint32_t in_get_input_frames_lost(struct audio_stream_in* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_get_capture_position(const struct audio_stream_in* stream,
- int64_t* frames, int64_t* time) {
- if (stream == NULL || frames == NULL || time == NULL) {
- return -EINVAL;
- }
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
-
- if (in->bluetooth_input_.GetState() == BluetoothStreamState::STANDBY) {
- LOG(WARNING) << __func__ << ": state= " << in->bluetooth_input_.GetState();
- return -ENOSYS;
- }
-
- in_calculate_starving_delay_ms(in, frames, time);
-
- return 0;
-}
-
-static int in_start(const struct audio_stream_in* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_stop(const struct audio_stream_in* stream) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return 0;
-}
-
-static int in_create_mmap_buffer(const struct audio_stream_in* stream,
- int32_t min_size_frames,
- struct audio_mmap_buffer_info* info) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_get_mmap_position(const struct audio_stream_in* stream,
- struct audio_mmap_position* position) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_get_active_microphones(
- const struct audio_stream_in* stream,
- struct audio_microphone_characteristic_t* mic_array, size_t* mic_count) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_set_microphone_direction(const struct audio_stream_in* stream,
- audio_microphone_direction_t direction) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static int in_set_microphone_field_dimension(
- const struct audio_stream_in* stream, float zoom) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-
- return -ENOSYS;
-}
-
-static void in_update_sink_metadata(struct audio_stream_in* stream,
- const struct sink_metadata* sink_metadata) {
- const auto* in = reinterpret_cast<const BluetoothStreamIn*>(stream);
- LOG(VERBOSE) << __func__
- << ": NOT HANDLED! state=" << in->bluetooth_input_.GetState();
-}
-
-int adev_open_input_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- struct audio_config* config,
- struct audio_stream_in** stream_in,
- audio_input_flags_t flags __unused,
- const char* address __unused,
- audio_source_t source __unused) {
- *stream_in = nullptr;
- auto* in = new BluetoothStreamIn{};
- if (!in->bluetooth_input_.SetUp(devices)) {
- delete in;
- return -EINVAL;
- }
-
- LOG(INFO) << __func__ << ": device=" << StringPrintf("%#x", devices);
-
- in->stream_in_.common.get_sample_rate = in_get_sample_rate;
- in->stream_in_.common.set_sample_rate = in_set_sample_rate;
- in->stream_in_.common.get_buffer_size = in_get_buffer_size;
- in->stream_in_.common.get_channels = in_get_channels;
- in->stream_in_.common.get_format = in_get_format;
- in->stream_in_.common.set_format = in_set_format;
- in->stream_in_.common.standby = in_standby;
- in->stream_in_.common.dump = in_dump;
- in->stream_in_.common.set_parameters = in_set_parameters;
- in->stream_in_.common.get_parameters = in_get_parameters;
- in->stream_in_.common.add_audio_effect = in_add_audio_effect;
- in->stream_in_.common.remove_audio_effect = in_remove_audio_effect;
- in->stream_in_.set_gain = in_set_gain;
- in->stream_in_.read = in_read;
- in->stream_in_.get_input_frames_lost = in_get_input_frames_lost;
- in->stream_in_.get_capture_position = in_get_capture_position;
- in->stream_in_.start = in_start;
- in->stream_in_.stop = in_stop;
- in->stream_in_.create_mmap_buffer = in_create_mmap_buffer;
- in->stream_in_.get_mmap_position = in_get_mmap_position;
- in->stream_in_.get_active_microphones = in_get_active_microphones;
- in->stream_in_.set_microphone_direction = in_set_microphone_direction;
- in->stream_in_.set_microphone_field_dimension =
- in_set_microphone_field_dimension;
- in->stream_in_.update_sink_metadata = in_update_sink_metadata;
-
- if (!in->bluetooth_input_.LoadAudioConfig(config)) {
- LOG(ERROR) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << " failed to get audio config";
- return -EINVAL;
- }
-
- in->sample_rate_ = config->sample_rate;
- in->channel_mask_ = config->channel_mask;
- in->format_ = config->format;
- // frame is number of samples per channel
- in->frames_count_ =
- samples_per_ticks(kBluetoothDefaultInputBufferMs, in->sample_rate_, 1);
- in->frames_presented_ = 0;
-
- *stream_in = &in->stream_in_;
- LOG(INFO) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", sample_rate=" << in->sample_rate_
- << ", channels=" << StringPrintf("%#x", in->channel_mask_)
- << ", format=" << in->format_ << ", frames=" << in->frames_count_;
-
- return 0;
-}
-
-void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* stream) {
- auto* in = reinterpret_cast<BluetoothStreamIn*>(stream);
-
- if (in->bluetooth_input_.GetState() != BluetoothStreamState::DISABLED) {
- in->bluetooth_input_.Stop();
- }
-
- in->bluetooth_input_.TearDown();
- LOG(VERBOSE) << __func__ << ": state=" << in->bluetooth_input_.GetState()
- << ", stopped";
-
- delete in;
-}
diff --git a/audio_bluetooth_hw/stream_apis.h b/audio_bluetooth_hw/stream_apis.h
deleted file mode 100644
index ae1a842..0000000
--- a/audio_bluetooth_hw/stream_apis.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2019 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 <hardware/audio.h>
-#include <system/audio.h>
-#include <list>
-
-#include "device_port_proxy.h"
-
-constexpr unsigned int kBluetoothDefaultSampleRate = 44100;
-constexpr audio_format_t kBluetoothDefaultAudioFormatBitsPerSample =
- AUDIO_FORMAT_PCM_16_BIT;
-
-constexpr unsigned int kBluetoothDefaultInputBufferMs = 20;
-constexpr unsigned int kBluetoothDefaultInputStateTimeoutMs = 20;
-
-constexpr unsigned int kBluetoothDefaultOutputBufferMs = 2;
-constexpr audio_channel_mask_t kBluetoothDefaultOutputChannelModeMask =
- AUDIO_CHANNEL_OUT_STEREO;
-constexpr audio_channel_mask_t kBluetoothDefaultInputChannelModeMask =
- AUDIO_CHANNEL_IN_MONO;
-
-enum class BluetoothStreamState : uint8_t {
- DISABLED = 0, // This stream is closing or set param "suspend=true"
- STANDBY,
- STARTING,
- STARTED,
- SUSPENDING,
- UNKNOWN,
-};
-
-std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state);
-
-struct BluetoothStreamOut {
- // Must be the first member so it can be cast from audio_stream
- // or audio_stream_out pointer
- audio_stream_out stream_out_{};
- ::android::bluetooth::audio::BluetoothAudioPortOut bluetooth_output_;
- int64_t last_write_time_us_;
- // Audio PCM Configs
- uint32_t sample_rate_;
- audio_channel_mask_t channel_mask_;
- audio_format_t format_;
- // frame is the number of samples per channel
- // frames count per tick
- size_t frames_count_;
- // total frames written, reset on standby
- uint64_t frames_rendered_;
- // total frames written after opened, never reset
- uint64_t frames_presented_;
- mutable std::mutex mutex_;
-};
-
-struct BluetoothAudioDevice {
- // Important: device must be first as an audio_hw_device* may be cast to
- // BluetoothAudioDevice* when the type is implicitly known.
- audio_hw_device audio_device_{};
- // protect against device->output and stream_out from being inconsistent
- std::mutex mutex_;
- std::list<BluetoothStreamOut*> opened_stream_outs_ =
- std::list<BluetoothStreamOut*>(0);
-};
-
-struct BluetoothStreamIn {
- // Must be the first member so it can be cast from audio_stream
- // or audio_stream_in pointer
- audio_stream_in stream_in_;
- ::android::bluetooth::audio::BluetoothAudioPortIn bluetooth_input_;
- int64_t last_read_time_us_;
- // Audio PCM Configs
- uint32_t sample_rate_;
- audio_channel_mask_t channel_mask_;
- audio_format_t format_;
- // frame is the number of samples per channel
- // frames count per tick
- size_t frames_count_;
- // total frames read after opened, never reset
- uint64_t frames_presented_;
- mutable std::mutex mutex_;
-};
-
-int adev_open_output_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- const char* address __unused);
-
-void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream);
-
-size_t adev_get_input_buffer_size(const struct audio_hw_device* dev,
- const struct audio_config* config);
-
-int adev_open_input_stream(struct audio_hw_device* dev,
- audio_io_handle_t handle, audio_devices_t devices,
- struct audio_config* config,
- struct audio_stream_in** stream_in,
- audio_input_flags_t flags __unused,
- const char* address __unused,
- audio_source_t source __unused);
-
-void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* in);
diff --git a/audio_bluetooth_hw/utils.cc b/audio_bluetooth_hw/utils.cc
deleted file mode 100644
index b3ac7a5..0000000
--- a/audio_bluetooth_hw/utils.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2019 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 "BTAudioHalUtils"
-
-#include "utils.h"
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <log/log.h>
-#include <stdlib.h>
-#include <sstream>
-#include <vector>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-namespace utils {
-
-std::unordered_map<std::string, std::string> ParseAudioParams(
- const std::string& params) {
- std::vector<std::string> segments = android::base::Split(params, ";");
- std::unordered_map<std::string, std::string> params_map;
- for (const auto& segment : segments) {
- if (segment.length() == 0) {
- continue;
- }
- std::vector<std::string> kv = android::base::Split(segment, "=");
- if (kv[0].empty()) {
- LOG(WARNING) << __func__ << ": Invalid audio parameter " << segment;
- continue;
- }
- params_map[kv[0]] = (kv.size() > 1 ? kv[1] : "");
- }
- return params_map;
-}
-
-std::string GetAudioParamString(
- std::unordered_map<std::string, std::string>& params_map) {
- std::ostringstream sout;
- for (const auto& ptr : params_map) {
- sout << "key: '" << ptr.first << "' value: '" << ptr.second << "'\n";
- }
- return sout.str();
-}
-
-} // namespace utils
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/utils.h b/audio_bluetooth_hw/utils.h
deleted file mode 100644
index 817a432..0000000
--- a/audio_bluetooth_hw/utils.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-#include <unordered_map>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-namespace utils {
-
-// Creates a hash map based on the |params| string containing key and value
-// pairs. Pairs are expected in the form "key=value" separated by the ';'
-// character. Both ';' and '=' characters are invalid in keys or values.
-// Examples:
-// "key0" -> map: [key0]=""
-// "key0=value0;key1=value1;" -> map: [key0]="value0" [key1]="value1"
-// "key0=;key1=value1;" -> map: [key0]="" [key1]="value1"
-// "=value0;key1=value1;" -> map: [key1]="value1"
-std::unordered_map<std::string, std::string> ParseAudioParams(
- const std::string& params);
-
-// Dumps the contents of the hash_map to the log for debugging purposes.
-// If |map| is not NULL, all entries of |map| will be dumped, otherwise
-// nothing will be dumped. Note that this function does not take the ownership
-// of the |map|.
-std::string GetAudioParamString(
- std::unordered_map<std::string, std::string>& params_map);
-
-} // namespace utils
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/audio_bluetooth_hw/utils_unittest.cc b/audio_bluetooth_hw/utils_unittest.cc
deleted file mode 100644
index 665dea6..0000000
--- a/audio_bluetooth_hw/utils_unittest.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2019 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 <gtest/gtest.h>
-#include <unordered_map>
-
-#include "utils.h"
-
-namespace {
-
-using ::android::bluetooth::audio::utils::ParseAudioParams;
-
-class UtilsTest : public testing::Test {
- protected:
- void SetUp() override {}
- void TearDown() override { map_.clear(); }
-
- std::unordered_map<std::string, std::string> map_;
-};
-
-TEST_F(UtilsTest, HashMapEmptyParams) {
- std::string params = "";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapDelimitOnly) {
- std::string params = ";";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapNotKeyValuePair) {
- std::string params = "key0";
- map_ = ParseAudioParams(params);
- // map = {[key0]=""}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_NE(map_.find("key0"), map_.end());
- EXPECT_EQ(map_["key0"].length(), 0);
-}
-
-TEST_F(UtilsTest, HashMapEmptyValue) {
- std::string params = "key0=";
- map_ = ParseAudioParams(params);
- // map = {[key0]=""}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_NE(map_.find("key0"), map_.end());
- EXPECT_EQ(map_["key0"].length(), 0);
-}
-
-TEST_F(UtilsTest, HashMapEmptyValueWithDelimit) {
- std::string params = "key0=;";
- map_ = ParseAudioParams(params);
- // map = {[key0]=""}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_NE(map_.find("key0"), map_.end());
- EXPECT_EQ(map_["key0"].length(), 0);
-}
-
-TEST_F(UtilsTest, HashMapOneKeyValuePair) {
- std::string params = "key0=value0";
- map_ = ParseAudioParams(params);
- // map = {[key0]="value0"}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_EQ(map_["key0"], "value0");
-}
-
-TEST_F(UtilsTest, HashMapOneKeyValuePairWithDelimit) {
- std::string params = "key0=value0;";
- map_ = ParseAudioParams(params);
- // map = {[key0]="value0"}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_EQ(map_["key0"], "value0");
-}
-
-TEST_F(UtilsTest, HashMapTwoKeyValuePairs) {
- std::string params = "key0=value0;key1=value1";
- map_ = ParseAudioParams(params);
- // map = {[key0]="value0", [key1]="value1"}
- EXPECT_EQ(map_.size(), 2);
- EXPECT_EQ(map_["key0"], "value0");
- EXPECT_EQ(map_["key1"], "value1");
-}
-
-TEST_F(UtilsTest, HashMapEmptyKey) {
- std::string params = "=value";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapEmptyKeyWithDelimit) {
- std::string params = "=value;";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapEquivalentOnly) {
- std::string params = "=";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapNoKeyValuePair) {
- std::string params = "=;";
- map_ = ParseAudioParams(params);
- // map = {}
- EXPECT_TRUE(map_.empty());
-}
-
-TEST_F(UtilsTest, HashMapTwoPairsWithFirstKeyEmpty) {
- std::string params = "=value0;key1=value1";
- map_ = ParseAudioParams(params);
- // map = {[key1]="value1"}
- EXPECT_EQ(map_.size(), 1);
- EXPECT_EQ(map_["key1"], "value1");
-}
-
-} // namespace
diff --git a/audio_hal_interface/Android.bp b/audio_hal_interface/Android.bp
deleted file mode 100644
index c41ad16..0000000
--- a/audio_hal_interface/Android.bp
+++ /dev/null
@@ -1,87 +0,0 @@
-// Bluetooth Audio library for target
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_library_static {
- name: "libbt-audio-hal-interface",
- defaults: ["fluoride_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/bta/include",
- "system/bt/bta/sys",
- "system/bt/btif/include",
- "system/bt/stack/include",
- "system/bt/gd/rust/shim",
- ],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libhidlbase",
- ],
- static_libs: [
- "libosi",
- "libbt-common",
- ],
- target: {
- android: {
- shared_libs: [
- "libfmq",
- ],
- srcs: [
- "a2dp_encoding.cc",
- "client_interface.cc",
- "codec_status.cc",
- "hearing_aid_software_encoding.cc",
- "le_audio_software.cc",
- ],
- },
- host: {
- srcs: [
- "a2dp_encoding_host.cc",
- "hearing_aid_software_encoding_host.cc",
- "le_audio_software_host.cc",
- ],
- },
- },
- host_supported: true,
- cflags: [
- "-DBUILDCFG",
- ],
-}
-
-// Bluetooth Audio client interface library unit tests for target and host
-cc_test {
- name: "bluetooth-test-audio-hal-interface",
- defaults: ["fluoride_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/stack/include",
- ],
- srcs: [
- "client_interface_unittest.cc",
- ],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
- static_libs: [
- "libbt-audio-hal-interface",
- "libbt-common",
- ],
- cflags: [
- "-DBUILDCFG",
- ],
-}
diff --git a/audio_hal_interface/BUILD.gn b/audio_hal_interface/BUILD.gn
deleted file mode 100644
index 31e3856..0000000
--- a/audio_hal_interface/BUILD.gn
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright 2021 Google, Inc.
-#
-# 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.
-#
-
-static_library("audio_hal_interface") {
- sources = [
- "a2dp_encoding_host.cc",
- "hearing_aid_software_encoding_host.cc",
- ]
-
- include_dirs = [
- "//bt/bta/include",
- "//bt/btif/include",
- "//bt/internal_include",
- "//bt/stack/include",
- "//bt/gd/rust/shim",
- ]
-
- configs += [ "//bt:target_defaults" ]
-
- deps = [
- "//bt/common",
- "//bt/osi:osi",
- ]
-}
diff --git a/audio_hal_interface/a2dp_encoding.cc b/audio_hal_interface/a2dp_encoding.cc
deleted file mode 100644
index abfa943..0000000
--- a/audio_hal_interface/a2dp_encoding.cc
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright 2019 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 "a2dp_encoding"
-
-#include "a2dp_encoding.h"
-
-#include "a2dp_sbc_constants.h"
-#include "btif_a2dp_source.h"
-#include "btif_av.h"
-#include "btif_av_co.h"
-#include "btif_hf.h"
-#include "client_interface.h"
-#include "codec_status.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-#include "types/raw_address.h"
-
-namespace {
-
-using ::bluetooth::audio::AudioCapabilities;
-using ::bluetooth::audio::AudioConfiguration;
-using ::bluetooth::audio::BitsPerSample;
-using ::bluetooth::audio::BluetoothAudioCtrlAck;
-using ::bluetooth::audio::ChannelMode;
-using ::bluetooth::audio::PcmParameters;
-using ::bluetooth::audio::SampleRate;
-using ::bluetooth::audio::SessionType;
-
-using ::bluetooth::audio::BluetoothAudioSinkClientInterface;
-using ::bluetooth::audio::codec::A2dpAacToHalConfig;
-using ::bluetooth::audio::codec::A2dpAptxToHalConfig;
-using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample;
-using ::bluetooth::audio::codec::A2dpCodecToHalChannelMode;
-using ::bluetooth::audio::codec::A2dpCodecToHalSampleRate;
-using ::bluetooth::audio::codec::A2dpLdacToHalConfig;
-using ::bluetooth::audio::codec::A2dpSbcToHalConfig;
-using ::bluetooth::audio::codec::CodecConfiguration;
-
-BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack);
-
-// Provide call-in APIs for the Bluetooth Audio HAL
-class A2dpTransport
- : public ::bluetooth::audio::IBluetoothSinkTransportInstance {
- public:
- A2dpTransport(SessionType sessionType)
- : IBluetoothSinkTransportInstance(sessionType, {}),
- total_bytes_read_(0),
- data_position_({}) {
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- remote_delay_report_ = 0;
- }
-
- BluetoothAudioCtrlAck StartRequest() override {
- // Check if a previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_START in progress";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
-
- // Don't send START request to stack while we are in a call
- if (!bluetooth::headset::IsCallIdle()) {
- LOG(ERROR) << __func__ << ": call state is busy";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE);
- }
-
- if (btif_av_stream_started_ready()) {
- // Already started, ACK back immediately.
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
- if (btif_av_stream_ready()) {
- /*
- * Post start event and wait for audio path to open.
- * If we are the source, the ACK will be sent after the start
- * procedure is completed, othewise send it now.
- */
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
- btif_av_stream_start();
- if (btif_av_get_peer_sep() != AVDT_TSEP_SRC) {
- LOG(INFO) << __func__ << ": accepted";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- }
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
- LOG(ERROR) << __func__ << ": AV stream is not ready to start";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- // Previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_SUSPEND) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_SUSPEND in progress";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_PENDING);
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
- }
- // Local suspend
- if (btif_av_stream_started_ready()) {
- LOG(INFO) << __func__ << ": accepted";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_SUSPEND;
- btif_av_stream_suspend();
- return BluetoothAudioCtrlAck::PENDING;
- }
- /* If we are not in started state, just ack back ok and let
- * audioflinger close the channel. This can happen if we are
- * remotely suspended, clear REMOTE SUSPEND flag.
- */
- btif_av_clear_remote_suspend_flag();
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
-
- void StopRequest() override {
- if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
- !btif_av_stream_started_ready()) {
- btif_av_clear_remote_suspend_flag();
- return;
- }
- LOG(INFO) << __func__ << ": handling";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
- btif_av_stream_stop(RawAddress::kEmpty);
- }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_read,
- timespec* data_position) override {
- *remote_delay_report_ns = remote_delay_report_ * 100000u;
- *total_bytes_read = total_bytes_read_;
- *data_position = data_position_;
- VLOG(2) << __func__ << ": delay=" << remote_delay_report_
- << "/10ms, data=" << total_bytes_read_
- << " byte(s), timestamp=" << data_position_.tv_sec << "."
- << data_position_.tv_nsec << "s";
- return true;
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- auto track_count = source_metadata.track_count;
- auto tracks = source_metadata.tracks;
- VLOG(1) << __func__ << ": " << track_count << " track(s) received";
- while (track_count) {
- VLOG(2) << __func__ << ": usage=" << tracks->usage
- << ", content_type=" << tracks->content_type
- << ", gain=" << tracks->gain;
- --track_count;
- ++tracks;
- }
- }
-
- tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
-
- void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
-
- void ResetPresentationPosition() override {
- remote_delay_report_ = 0;
- total_bytes_read_ = 0;
- data_position_ = {};
- }
-
- void LogBytesRead(size_t bytes_read) override {
- if (bytes_read != 0) {
- total_bytes_read_ += bytes_read;
- clock_gettime(CLOCK_MONOTONIC, &data_position_);
- }
- }
-
- // delay reports from AVDTP is based on 1/10 ms (100us)
- void SetRemoteDelay(uint16_t delay_report) {
- remote_delay_report_ = delay_report;
- }
-
- private:
- static tA2DP_CTRL_CMD a2dp_pending_cmd_;
- static uint16_t remote_delay_report_;
- uint64_t total_bytes_read_;
- timespec data_position_;
-};
-
-tA2DP_CTRL_CMD A2dpTransport::a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
-uint16_t A2dpTransport::remote_delay_report_ = 0;
-
-// Common interface to call-out into Bluetooth Audio HAL
-BluetoothAudioSinkClientInterface* software_hal_interface = nullptr;
-BluetoothAudioSinkClientInterface* offloading_hal_interface = nullptr;
-BluetoothAudioSinkClientInterface* active_hal_interface = nullptr;
-
-// Save the value if the remote reports its delay before this interface is
-// initialized
-uint16_t remote_delay = 0;
-
-bool btaudio_a2dp_disabled = false;
-bool is_configured = false;
-
-BluetoothAudioCtrlAck a2dp_ack_to_bt_audio_ctrl_ack(tA2DP_CTRL_ACK ack) {
- switch (ack) {
- case A2DP_CTRL_ACK_SUCCESS:
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- case A2DP_CTRL_ACK_PENDING:
- return BluetoothAudioCtrlAck::PENDING;
- case A2DP_CTRL_ACK_INCALL_FAILURE:
- return BluetoothAudioCtrlAck::FAILURE_BUSY;
- case A2DP_CTRL_ACK_DISCONNECT_IN_PROGRESS:
- return BluetoothAudioCtrlAck::FAILURE_DISCONNECTING;
- case A2DP_CTRL_ACK_UNSUPPORTED: /* Offloading but resource failure */
- return BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED;
- case A2DP_CTRL_ACK_FAILURE:
- return BluetoothAudioCtrlAck::FAILURE;
- default:
- return BluetoothAudioCtrlAck::FAILURE;
- }
-}
-
-bool a2dp_get_selected_hal_codec_config(CodecConfiguration* codec_config) {
- A2dpCodecConfig* a2dp_config = bta_av_get_a2dp_current_codec();
- if (a2dp_config == nullptr) {
- LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
- *codec_config = ::bluetooth::audio::codec::kInvalidCodecConfiguration;
- return false;
- }
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- switch (current_codec.codec_type) {
- case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_SBC: {
- if (!A2dpSbcToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_AAC: {
- if (!A2dpAacToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: {
- if (!A2dpAptxToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: {
- if (!A2dpLdacToHalConfig(codec_config, a2dp_config)) {
- return false;
- }
- break;
- }
- case BTAV_A2DP_CODEC_INDEX_MAX:
- [[fallthrough]];
- default:
- LOG(ERROR) << __func__
- << ": Unknown codec_type=" << current_codec.codec_type;
- *codec_config = ::bluetooth::audio::codec::kInvalidCodecConfiguration;
- return false;
- }
- codec_config->encodedAudioBitrate = a2dp_config->getTrackBitRate();
- // Obtain the MTU
- RawAddress peer_addr = btif_av_source_active_peer();
- tA2DP_ENCODER_INIT_PEER_PARAMS peer_param;
- bta_av_co_get_peer_params(peer_addr, &peer_param);
- int effectiveMtu = bta_av_co_get_encoder_effective_frame_size();
- if (effectiveMtu > 0 && effectiveMtu < peer_param.peer_mtu) {
- codec_config->peerMtu = effectiveMtu;
- } else {
- codec_config->peerMtu = peer_param.peer_mtu;
- }
- if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
- codec_config->config.sbcConfig().maxBitpool <=
- A2DP_SBC_BITPOOL_MIDDLE_QUALITY) {
- codec_config->peerMtu = MAX_2MBPS_AVDTP_MTU;
- } else if (codec_config->peerMtu > MAX_3MBPS_AVDTP_MTU) {
- codec_config->peerMtu = MAX_3MBPS_AVDTP_MTU;
- }
- LOG(INFO) << __func__ << ": CodecConfiguration=" << toString(*codec_config);
- return true;
-}
-
-bool a2dp_get_selected_hal_pcm_config(PcmParameters* pcm_config) {
- if (pcm_config == nullptr) return false;
- A2dpCodecConfig* a2dp_codec_configs = bta_av_get_a2dp_current_codec();
- if (a2dp_codec_configs == nullptr) {
- LOG(WARNING) << __func__ << ": failure to get A2DP codec config";
- *pcm_config = BluetoothAudioSinkClientInterface::kInvalidPcmConfiguration;
- return false;
- }
-
- btav_a2dp_codec_config_t current_codec = a2dp_codec_configs->getCodecConfig();
- pcm_config->sampleRate = A2dpCodecToHalSampleRate(current_codec);
- pcm_config->bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- pcm_config->channelMode = A2dpCodecToHalChannelMode(current_codec);
- return (pcm_config->sampleRate != SampleRate::RATE_UNKNOWN &&
- pcm_config->bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config->channelMode != ChannelMode::UNKNOWN);
-}
-
-// Checking if new bluetooth_audio is supported
-bool is_hal_2_0_force_disabled() {
- if (!is_configured) {
- btaudio_a2dp_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
- is_configured = true;
- }
- return btaudio_a2dp_disabled;
-}
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-bool update_codec_offloading_capabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
- return ::bluetooth::audio::codec::UpdateOffloadingCapabilities(
- framework_preference);
-}
-
-// Checking if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled() { return active_hal_interface != nullptr; }
-
-// Check if new bluetooth_audio is running with offloading encoders
-bool is_hal_2_0_offloading() {
- if (!is_hal_2_0_enabled()) {
- return false;
- }
- return active_hal_interface->GetTransportInstance()->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
-}
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(bluetooth::common::MessageLoopThread* message_loop) {
- LOG(INFO) << __func__;
-
- if (is_hal_2_0_force_disabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
- return false;
- }
-
- auto a2dp_sink =
- new A2dpTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
- software_hal_interface =
- new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
- if (!software_hal_interface->IsValid()) {
- LOG(WARNING) << __func__ << ": BluetoothAudio HAL for A2DP is invalid?!";
- delete software_hal_interface;
- software_hal_interface = nullptr;
- delete a2dp_sink;
- return false;
- }
-
- if (btif_av_is_a2dp_offload_enabled()) {
- a2dp_sink = new A2dpTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- offloading_hal_interface =
- new BluetoothAudioSinkClientInterface(a2dp_sink, message_loop);
- if (!offloading_hal_interface->IsValid()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudio HAL for A2DP offloading is invalid?!";
- delete offloading_hal_interface;
- offloading_hal_interface = nullptr;
- delete a2dp_sink;
- a2dp_sink = static_cast<A2dpTransport*>(
- software_hal_interface->GetTransportInstance());
- delete software_hal_interface;
- software_hal_interface = nullptr;
- delete a2dp_sink;
- return false;
- }
- }
-
- active_hal_interface =
- (offloading_hal_interface != nullptr ? offloading_hal_interface
- : software_hal_interface);
-
- if (remote_delay != 0) {
- LOG(INFO) << __func__ << ": restore DELAY "
- << static_cast<float>(remote_delay / 10.0) << " ms";
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->SetRemoteDelay(remote_delay);
- remote_delay = 0;
- }
- return true;
-}
-
-// Clean up BluetoothAudio HAL
-void cleanup() {
- if (!is_hal_2_0_enabled()) return;
- end_session();
-
- auto a2dp_sink = active_hal_interface->GetTransportInstance();
- static_cast<A2dpTransport*>(a2dp_sink)->ResetPendingCmd();
- static_cast<A2dpTransport*>(a2dp_sink)->ResetPresentationPosition();
- active_hal_interface = nullptr;
-
- a2dp_sink = software_hal_interface->GetTransportInstance();
- delete software_hal_interface;
- software_hal_interface = nullptr;
- delete a2dp_sink;
- if (offloading_hal_interface != nullptr) {
- a2dp_sink = offloading_hal_interface->GetTransportInstance();
- delete offloading_hal_interface;
- offloading_hal_interface = nullptr;
- delete a2dp_sink;
- }
-
- remote_delay = 0;
-}
-
-// Set up the codec into BluetoothAudio HAL
-bool setup_codec() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return false;
- }
- CodecConfiguration codec_config{};
- if (!a2dp_get_selected_hal_codec_config(&codec_config)) {
- LOG(ERROR) << __func__ << ": Failed to get CodecConfiguration";
- return false;
- }
- bool should_codec_offloading =
- bluetooth::audio::codec::IsCodecOffloadingEnabled(codec_config);
- if (should_codec_offloading && !is_hal_2_0_offloading()) {
- LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Hardware";
- end_session();
- active_hal_interface = offloading_hal_interface;
- } else if (!should_codec_offloading && is_hal_2_0_offloading()) {
- LOG(WARNING) << __func__ << ": Switching BluetoothAudio HAL to Software";
- end_session();
- active_hal_interface = software_hal_interface;
- }
-
- AudioConfiguration audio_config{};
- if (active_hal_interface->GetTransportInstance()->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- audio_config.codecConfig(codec_config);
- } else {
- PcmParameters pcm_config{};
- if (!a2dp_get_selected_hal_pcm_config(&pcm_config)) {
- LOG(ERROR) << __func__ << ": Failed to get PcmConfiguration";
- return false;
- }
- audio_config.pcmConfig(pcm_config);
- }
- return active_hal_interface->UpdateAudioConfig(audio_config);
-}
-
-void start_session() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return;
- }
- active_hal_interface->StartSession();
-}
-
-void end_session() {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return;
- }
- active_hal_interface->EndSession();
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->ResetPendingCmd();
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->ResetPresentationPosition();
-}
-
-void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
- auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
- LOG(INFO) << __func__ << ": result=" << ctrl_ack;
- auto a2dp_sink =
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
- auto pending_cmd = a2dp_sink->GetPendingCmd();
- if (pending_cmd == A2DP_CTRL_CMD_START) {
- active_hal_interface->StreamStarted(ctrl_ack);
- } else {
- LOG(WARNING) << __func__ << ": pending=" << pending_cmd
- << " ignore result=" << ctrl_ack;
- return;
- }
- if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
- a2dp_sink->ResetPendingCmd();
- }
-}
-
-void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
- auto ctrl_ack = a2dp_ack_to_bt_audio_ctrl_ack(ack);
- LOG(INFO) << __func__ << ": result=" << ctrl_ack;
- auto a2dp_sink =
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance());
- auto pending_cmd = a2dp_sink->GetPendingCmd();
- if (pending_cmd == A2DP_CTRL_CMD_SUSPEND) {
- active_hal_interface->StreamSuspended(ctrl_ack);
- } else if (pending_cmd == A2DP_CTRL_CMD_STOP) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_STOP result=" << ctrl_ack;
- } else {
- LOG(WARNING) << __func__ << ": pending=" << pending_cmd
- << " ignore result=" << ctrl_ack;
- return;
- }
- if (ctrl_ack != bluetooth::audio::BluetoothAudioCtrlAck::PENDING) {
- a2dp_sink->ResetPendingCmd();
- }
-}
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len) {
- if (!is_hal_2_0_enabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is not enabled";
- return 0;
- } else if (is_hal_2_0_offloading()) {
- LOG(ERROR) << __func__ << ": session_type="
- << toString(active_hal_interface->GetTransportInstance()
- ->GetSessionType())
- << " is not A2DP_SOFTWARE_ENCODING_DATAPATH";
- return 0;
- }
- return active_hal_interface->ReadAudioData(p_buf, len);
-}
-
-// Update A2DP delay report to BluetoothAudio HAL
-void set_remote_delay(uint16_t delay_report) {
- if (!is_hal_2_0_enabled()) {
- LOG(INFO) << __func__ << ": not ready for DelayReport "
- << static_cast<float>(delay_report / 10.0) << " ms";
- remote_delay = delay_report;
- return;
- }
- VLOG(1) << __func__ << ": DELAY " << static_cast<float>(delay_report / 10.0)
- << " ms";
- static_cast<A2dpTransport*>(active_hal_interface->GetTransportInstance())
- ->SetRemoteDelay(delay_report);
-}
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/a2dp_encoding.h b/audio_hal_interface/a2dp_encoding.h
deleted file mode 100644
index fbecde7..0000000
--- a/audio_hal_interface/a2dp_encoding.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <vector>
-
-#include "audio_a2dp_hw/include/audio_a2dp_hw.h"
-#include "common/message_loop_thread.h"
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-bool update_codec_offloading_capabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference);
-
-// Check if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled();
-
-// Check if new bluetooth_audio is running with offloading encoders
-bool is_hal_2_0_offloading();
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(bluetooth::common::MessageLoopThread* message_loop);
-
-// Clean up BluetoothAudio HAL
-void cleanup();
-
-// Set up the codec into BluetoothAudio HAL
-bool setup_codec();
-
-// Send command to the BluetoothAudio HAL: StartSession, EndSession,
-// StreamStarted, StreamSuspended
-void start_session();
-void end_session();
-void ack_stream_started(const tA2DP_CTRL_ACK& status);
-void ack_stream_suspended(const tA2DP_CTRL_ACK& status);
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len);
-
-// Update A2DP delay report to BluetoothAudio HAL
-void set_remote_delay(uint16_t delay_report);
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/a2dp_encoding_host.cc b/audio_hal_interface/a2dp_encoding_host.cc
deleted file mode 100644
index 6ce7fd4..0000000
--- a/audio_hal_interface/a2dp_encoding_host.cc
+++ /dev/null
@@ -1,260 +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.
- */
-
-#include "a2dp_encoding_host.h"
-
-#include <errno.h>
-#include <grp.h>
-#include <sys/stat.h>
-
-#include <memory>
-
-#include "a2dp_encoding.h"
-#include "a2dp_sbc_constants.h"
-#include "btif_a2dp_source.h"
-#include "btif_av.h"
-#include "btif_av_co.h"
-#include "btif_hf.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-#include "types/raw_address.h"
-#include "udrv/include/uipc.h"
-
-#include <base/logging.h>
-
-#define A2DP_DATA_READ_POLL_MS 10
-#define A2DP_HOST_DATA_PATH "/var/run/bluetooth/audio/.a2dp_data"
-// TODO(b/198260375): Make A2DP data owner group configurable.
-#define A2DP_HOST_DATA_GROUP "bluetooth-audio"
-
-namespace {
-
-std::unique_ptr<tUIPC_STATE> a2dp_uipc = nullptr;
-
-static void btif_a2dp_data_cb([[maybe_unused]] tUIPC_CH_ID ch_id,
- tUIPC_EVENT event) {
- APPL_TRACE_WARNING("%s: BTIF MEDIA (A2DP-DATA) EVENT %s", __func__,
- dump_uipc_event(event));
-
- switch (event) {
- case UIPC_OPEN_EVT:
- /*
- * Read directly from media task from here on (keep callback for
- * connection events.
- */
- UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO,
- UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
- UIPC_Ioctl(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
- reinterpret_cast<void*>(A2DP_DATA_READ_POLL_MS));
-
- // Will start audio on btif_a2dp_on_started
-
- /* ACK back when media task is fully started */
- break;
-
- case UIPC_CLOSE_EVT:
- /*
- * Send stop request only if we are actively streaming and haven't
- * received a stop request. Potentially, the audioflinger detached
- * abnormally.
- */
- if (btif_a2dp_source_is_streaming()) {
- /* Post stop event and wait for audio path to stop */
- btif_av_stream_stop(RawAddress::kEmpty);
- }
- break;
-
- default:
- APPL_TRACE_ERROR("%s: ### A2DP-DATA EVENT %d NOT HANDLED ###", __func__,
- event);
- break;
- }
-}
-
-// If A2DP_HOST_DATA_GROUP exists we expect audio server and BT both are
-// in this group therefore have access to A2DP socket. Otherwise audio
-// server should be in the same group that BT stack runs with to access
-// A2DP socket.
-static void a2dp_data_path_open() {
- UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb,
- A2DP_HOST_DATA_PATH);
- struct group* grp = getgrnam(A2DP_HOST_DATA_GROUP);
- chmod(A2DP_HOST_DATA_PATH, 0770);
- if (grp) {
- int res = chown(A2DP_HOST_DATA_PATH, -1, grp->gr_gid);
- if (res == -1) {
- LOG(ERROR) << __func__ << " failed: " << strerror(errno);
- }
- }
-}
-
-tA2DP_CTRL_CMD a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
-uint64_t total_bytes_read_;
-timespec data_position_;
-uint16_t remote_delay_report_;
-
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-// Invoked by audio server to set audio config (PCM for now)
-bool SetAudioConfig(AudioConfig config) {
- btav_a2dp_codec_config_t codec_config;
- codec_config.sample_rate = config.sample_rate;
- codec_config.bits_per_sample = config.bits_per_sample;
- codec_config.channel_mode = config.channel_mode;
- btif_a2dp_source_feeding_update_req(codec_config);
- return true;
-}
-
-// Invoked by audio server when it has audio data to stream.
-bool StartRequest() {
- // Check if a previous request is not finished
- if (a2dp_pending_cmd_ == A2DP_CTRL_CMD_START) {
- LOG(INFO) << __func__ << ": A2DP_CTRL_CMD_START in progress";
- return false;
- } else if (a2dp_pending_cmd_ != A2DP_CTRL_CMD_NONE) {
- LOG(WARNING) << __func__ << ": busy in pending_cmd=" << a2dp_pending_cmd_;
- return false;
- }
-
- // Don't send START request to stack while we are in a call
- if (!bluetooth::headset::IsCallIdle()) {
- LOG(ERROR) << __func__ << ": call state is busy";
- return false;
- }
-
- if (btif_av_stream_started_ready()) {
- // Already started, ACK back immediately.
- a2dp_data_path_open();
- return true;
- }
- if (btif_av_stream_ready()) {
- a2dp_data_path_open();
- /*
- * Post start event and wait for audio path to open.
- * If we are the source, the ACK will be sent after the start
- * procedure is completed, othewise send it now.
- */
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_START;
- btif_av_stream_start();
- if (btif_av_get_peer_sep() != AVDT_TSEP_SRC) {
- LOG(INFO) << __func__ << ": accepted";
- return false; // TODO: should be pending
- }
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- return true;
- }
- LOG(ERROR) << __func__ << ": AV stream is not ready to start";
- return false;
-}
-
-// Invoked by audio server when audio streaming is done.
-bool StopRequest() {
- if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
- !btif_av_stream_started_ready()) {
- btif_av_clear_remote_suspend_flag();
- return true;
- }
- LOG(INFO) << __func__ << ": handling";
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_STOP;
- btif_av_stream_stop(RawAddress::kEmpty);
- return true;
-}
-
-// Invoked by audio server to check audio presentation position periodically.
-PresentationPosition GetPresentationPosition() {
- PresentationPosition presentation_position{
- .remote_delay_report_ns = remote_delay_report_ * 100000u,
- .total_bytes_read = total_bytes_read_,
- .data_position = data_position_,
- };
- return presentation_position;
-}
-
-// delay reports from AVDTP is based on 1/10 ms (100us)
-void set_remote_delay(uint16_t delay_report) {
- remote_delay_report_ = delay_report;
-}
-
-// Inform audio server about offloading codec; not used for now
-bool update_codec_offloading_capabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
- return false;
-}
-
-// Checking if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled() { return true; }
-
-// Check if new bluetooth_audio is running with offloading encoders
-bool is_hal_2_0_offloading() { return false; }
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(bluetooth::common::MessageLoopThread* message_loop) {
- a2dp_uipc = UIPC_Init();
- total_bytes_read_ = 0;
- data_position_ = {};
- remote_delay_report_ = 0;
-
- return true;
-}
-
-// Clean up BluetoothAudio HAL
-void cleanup() {
- end_session();
-
- if (a2dp_uipc != nullptr) {
- UIPC_Close(*a2dp_uipc, UIPC_CH_ID_ALL);
- }
-}
-
-// Set up the codec into BluetoothAudio HAL
-bool setup_codec() {
- // TODO: setup codec
- return true;
-}
-
-void start_session() {
- // TODO: Notify server; or do we handle it during connected?
-}
-
-void end_session() {
- // TODO: Notify server; or do we handle it during disconnected?
-}
-
-void ack_stream_started(const tA2DP_CTRL_ACK& ack) {
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- // TODO: Notify server
-}
-
-void ack_stream_suspended(const tA2DP_CTRL_ACK& ack) {
- a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
- // TODO: Notify server
-}
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len) {
- if (a2dp_uipc == nullptr) {
- return 0;
- }
- return UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, p_buf, len);
-}
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/a2dp_encoding_host.h b/audio_hal_interface/a2dp_encoding_host.h
deleted file mode 100644
index 3a03ebb..0000000
--- a/audio_hal_interface/a2dp_encoding_host.h
+++ /dev/null
@@ -1,57 +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 <stdint.h>
-#include <time.h>
-
-#include "include/hardware/bt_av.h"
-
-namespace bluetooth {
-namespace audio {
-namespace a2dp {
-
-// Audio config from audio server; PCM format for now
-struct AudioConfig {
- btav_a2dp_codec_sample_rate_t sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
- btav_a2dp_codec_bits_per_sample_t bits_per_sample =
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
- btav_a2dp_codec_channel_mode_t channel_mode =
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
-};
-
-// Invoked by audio server to set audio config (PCM for now)
-bool SetAudioConfig(AudioConfig);
-
-// Invoked by audio server when it has audio data to stream.
-bool StartRequest();
-
-// Invoked by audio server when audio streaming is done.
-bool StopRequest();
-
-struct PresentationPosition {
- uint64_t remote_delay_report_ns;
- uint64_t total_bytes_read;
- timespec data_position;
-};
-
-// Invoked by audio server to check audio presentation position periodically.
-PresentationPosition GetPresentationPosition();
-
-} // namespace a2dp
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/client_interface.cc b/audio_hal_interface/client_interface.cc
deleted file mode 100644
index febf43f..0000000
--- a/audio_hal_interface/client_interface.cc
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
- * Copyright 2019 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 "BTAudioClientIf"
-
-#include "client_interface.h"
-#include "hal_version_manager.h"
-
-#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
-#include <base/logging.h>
-#include <hidl/MQDescriptor.h>
-#include <future>
-
-#include "common/stop_watch_legacy.h"
-#include "osi/include/log.h"
-
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::audio::common::V5_0::SourceMetadata;
-using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
-using ::bluetooth::common::StopWatchLegacy;
-
-using DataMQ = ::android::hardware::MessageQueue<
- uint8_t, ::android::hardware::kSynchronizedReadWrite>;
-
-static constexpr int kDefaultDataReadTimeoutMs = 10; // 10 ms
-static constexpr int kDefaultDataWriteTimeoutMs = 10; // 10 ms
-static constexpr int kDefaultDataReadPollIntervalMs = 1; // non-blocking poll
-static constexpr int kDefaultDataWritePollIntervalMs = 1; // non-blocking poll
-
-std::unique_ptr<HalVersionManager> HalVersionManager::instance_ptr =
- std::unique_ptr<HalVersionManager>(new HalVersionManager());
-
-std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack) {
- switch (ack) {
- case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
- return os << "SUCCESS_FINISHED";
- case BluetoothAudioCtrlAck::PENDING:
- return os << "PENDING";
- case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
- return os << "FAILURE_UNSUPPORTED";
- case BluetoothAudioCtrlAck::FAILURE_BUSY:
- return os << "FAILURE_BUSY";
- case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
- return os << "FAILURE_DISCONNECTING";
- case BluetoothAudioCtrlAck::FAILURE:
- return os << "FAILURE";
- default:
- return os << "UNDEFINED " << static_cast<int8_t>(ack);
- }
-}
-
-class BluetoothAudioPortImpl : public IBluetoothAudioPort {
- public:
- BluetoothAudioPortImpl(IBluetoothTransportInstance* transport_instance,
- const android::sp<IBluetoothAudioProvider>& provider)
- : transport_instance_(transport_instance), provider_(provider) {}
-
- Return<void> startStream() override {
- StopWatchLegacy(__func__);
- BluetoothAudioCtrlAck ack = transport_instance_->StartRequest();
- if (ack != BluetoothAudioCtrlAck::PENDING) {
- auto hidl_retval =
- provider_->streamStarted(BluetoothAudioCtrlAckToHalStatus(ack));
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
- << hidl_retval.description();
- }
- }
- return Void();
- }
-
- Return<void> suspendStream() override {
- StopWatchLegacy(__func__);
- BluetoothAudioCtrlAck ack = transport_instance_->SuspendRequest();
- if (ack != BluetoothAudioCtrlAck::PENDING) {
- auto hidl_retval =
- provider_->streamSuspended(BluetoothAudioCtrlAckToHalStatus(ack));
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal failure: "
- << hidl_retval.description();
- }
- }
- return Void();
- }
-
- Return<void> stopStream() override {
- StopWatchLegacy(__func__);
- transport_instance_->StopRequest();
- return Void();
- }
-
- Return<void> getPresentationPosition(
- getPresentationPosition_cb _hidl_cb) override {
- StopWatchLegacy(__func__);
- uint64_t remote_delay_report_ns;
- uint64_t total_bytes_read;
- timespec data_position;
- bool retval = transport_instance_->GetPresentationPosition(
- &remote_delay_report_ns, &total_bytes_read, &data_position);
-
- TimeSpec transmittedOctetsTimeStamp;
- if (retval) {
- transmittedOctetsTimeStamp = timespec_convert_to_hal(data_position);
- } else {
- remote_delay_report_ns = 0;
- total_bytes_read = 0;
- transmittedOctetsTimeStamp = {};
- }
- VLOG(2) << __func__ << ": result=" << retval
- << ", delay=" << remote_delay_report_ns
- << ", data=" << total_bytes_read
- << " byte(s), timestamp=" << toString(transmittedOctetsTimeStamp);
- _hidl_cb((retval ? BluetoothAudioStatus::SUCCESS
- : BluetoothAudioStatus::FAILURE),
- remote_delay_report_ns, total_bytes_read,
- transmittedOctetsTimeStamp);
- return Void();
- }
-
- Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
- StopWatchLegacy(__func__);
- LOG(INFO) << __func__ << ": " << sourceMetadata.tracks.size()
- << " track(s)";
- // refer to StreamOut.impl.h within Audio HAL (AUDIO_HAL_VERSION_5_0)
- std::vector<playback_track_metadata> metadata_vec;
- metadata_vec.reserve(sourceMetadata.tracks.size());
- for (const auto& metadata : sourceMetadata.tracks) {
- metadata_vec.push_back({
- .usage = static_cast<audio_usage_t>(metadata.usage),
- .content_type =
- static_cast<audio_content_type_t>(metadata.contentType),
- .gain = metadata.gain,
- });
- }
- const source_metadata_t source_metadata = {
- .track_count = metadata_vec.size(), .tracks = metadata_vec.data()};
- transport_instance_->MetadataChanged(source_metadata);
- return Void();
- }
-
- private:
- IBluetoothTransportInstance* transport_instance_;
- const android::sp<IBluetoothAudioProvider> provider_;
- TimeSpec timespec_convert_to_hal(const timespec& ts) {
- return {.tvSec = static_cast<uint64_t>(ts.tv_sec),
- .tvNSec = static_cast<uint64_t>(ts.tv_nsec)};
- }
-};
-
-class BluetoothAudioDeathRecipient
- : public ::android::hardware::hidl_death_recipient {
- public:
- BluetoothAudioDeathRecipient(
- BluetoothAudioClientInterface* clientif,
- bluetooth::common::MessageLoopThread* message_loop)
- : bluetooth_audio_clientif_(clientif), message_loop_(message_loop) {}
- void serviceDied(
- uint64_t /*cookie*/,
- const ::android::wp<::android::hidl::base::V1_0::IBase>& /*who*/)
- override {
- LOG(WARNING) << __func__ << ": restarting connection with new Audio Hal";
- if (bluetooth_audio_clientif_ != nullptr && message_loop_ != nullptr) {
- // restart the session on the correct thread
- message_loop_->DoInThread(
- FROM_HERE,
- base::BindOnce(
- &BluetoothAudioClientInterface::RenewAudioProviderAndSession,
- base::Unretained(bluetooth_audio_clientif_)));
- } else {
- LOG(ERROR) << __func__ << ": BluetoothAudioClientInterface corrupted";
- }
- }
-
- private:
- BluetoothAudioClientInterface* bluetooth_audio_clientif_;
- bluetooth::common::MessageLoopThread* message_loop_;
-};
-
-// Constructs an BluetoothAudioClientInterface to communicate to
-// BluetoothAudio HAL. |message_loop| is the thread where callbacks are
-// invoked.
-BluetoothAudioClientInterface::BluetoothAudioClientInterface(
- android::sp<BluetoothAudioDeathRecipient> death_recipient,
- IBluetoothTransportInstance* instance)
- : provider_(nullptr),
- provider_2_1_(nullptr),
- session_started_(false),
- mDataMQ(nullptr),
- transport_(instance) {
- death_recipient_ = death_recipient;
-}
-
-std::vector<AudioCapabilities>
-BluetoothAudioClientInterface::GetAudioCapabilities() const {
- return capabilities_;
-}
-
-std::vector<AudioCapabilities_2_1>
-BluetoothAudioClientInterface::GetAudioCapabilities_2_1() const {
- return capabilities_2_1_;
-}
-
-std::vector<AudioCapabilities>
-BluetoothAudioClientInterface::GetAudioCapabilities(SessionType session_type) {
- std::vector<AudioCapabilities> capabilities(0);
-
- if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
- LOG(ERROR) << __func__ << ", can't get capability from unknown factory";
- return capabilities;
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
- HalVersionManager::GetProvidersFactory_2_0();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities](const hidl_vec<AudioCapabilities>& audioCapabilities) {
- for (auto capability : audioCapabilities) {
- capabilities.push_back(capability);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities(
- session_type, getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- }
- return capabilities;
-}
-
-std::vector<AudioCapabilities_2_1>
-BluetoothAudioClientInterface::GetAudioCapabilities_2_1(
- SessionType_2_1 session_type_2_1) {
- std::vector<AudioCapabilities_2_1> capabilities_2_1(0);
-
- if (HalVersionManager::GetHalVersion() !=
- BluetoothAudioHalVersion::VERSION_2_1) {
- LOG(ERROR) << __func__ << ", can't get capability for HAL 2.1";
- return capabilities_2_1;
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_1> providersFactory =
- HalVersionManager::GetProvidersFactory_2_1();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities_2_1](
- const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
- for (auto capability_2_1 : audioCapabilities_2_1) {
- capabilities_2_1.push_back(capability_2_1);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
- session_type_2_1, getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- }
- return capabilities_2_1;
-}
-
-void BluetoothAudioClientInterface::FetchAudioProvider() {
- if (provider_ != nullptr) {
- LOG(WARNING) << __func__ << ": reflash";
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_0> providersFactory =
- HalVersionManager::GetProvidersFactory_2_0();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities = this->capabilities_](
- const hidl_vec<AudioCapabilities>& audioCapabilities) {
- capabilities.clear();
- for (auto capability : audioCapabilities) {
- capabilities.push_back(capability);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities(
- transport_->GetSessionType(), getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- return;
- }
- if (capabilities_.empty()) {
- LOG(WARNING) << __func__
- << ": SessionType=" << toString(transport_->GetSessionType())
- << " Not supported by BluetoothAudioHal";
- return;
- }
- LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
- << toString(transport_->GetSessionType()) << " has "
- << capabilities_.size() << " AudioCapabilities";
-
- std::promise<void> openProvider_promise;
- auto openProvider_future = openProvider_promise.get_future();
- auto openProvider_cb =
- [&provider_ = this->provider_, &openProvider_promise](
- BluetoothAudioStatus status,
- const android::sp<IBluetoothAudioProvider>& provider) {
- LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
- if (status == BluetoothAudioStatus::SUCCESS) {
- provider_ = provider;
- }
- ALOGE_IF(!provider_, "Failed to open BluetoothAudio provider");
- openProvider_promise.set_value();
- };
- hidl_retval = providersFactory->openProvider(transport_->GetSessionType(),
- openProvider_cb);
- openProvider_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
- << hidl_retval.description();
- }
- CHECK(provider_ != nullptr);
-
- if (!provider_->linkToDeath(death_recipient_, 0).isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
-
- LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
- << provider_.get()
- << (provider_->isRemote() ? " (remote)" : " (local)");
-}
-
-void BluetoothAudioClientInterface::FetchAudioProvider_2_1() {
- if (provider_2_1_ != nullptr) {
- LOG(WARNING) << __func__ << ": reflash";
- }
-
- android::sp<IBluetoothAudioProvidersFactory_2_1> providersFactory =
- HalVersionManager::GetProvidersFactory_2_1();
- CHECK(providersFactory != nullptr)
- << "IBluetoothAudioProvidersFactory_2_1::getService() failed";
-
- auto getProviderCapabilities_cb =
- [&capabilities_2_1 = this->capabilities_2_1_](
- const hidl_vec<AudioCapabilities_2_1>& audioCapabilities_2_1) {
- capabilities_2_1.clear();
- for (auto capability_2_1 : audioCapabilities_2_1) {
- capabilities_2_1.push_back(capability_2_1);
- }
- };
- auto hidl_retval = providersFactory->getProviderCapabilities_2_1(
- transport_->GetSessionType_2_1(), getProviderCapabilities_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal::getProviderCapabilities failure: "
- << hidl_retval.description();
- return;
- }
- if (capabilities_2_1_.empty()) {
- LOG(WARNING) << __func__ << ": SessionType="
- << toString(transport_->GetSessionType_2_1())
- << " Not supported by BluetoothAudioHal";
- return;
- }
- LOG(INFO) << __func__ << ": BluetoothAudioHal SessionType="
- << toString(transport_->GetSessionType_2_1()) << " has "
- << capabilities_2_1_.size() << " AudioCapabilities";
-
- std::promise<void> openProvider_promise;
- auto openProvider_future = openProvider_promise.get_future();
- auto openProvider_cb =
- [&provider_2_1_ = this->provider_2_1_, &openProvider_promise](
- BluetoothAudioStatus status,
- const android::sp<IBluetoothAudioProvider_2_1>& provider_2_1) {
- LOG(INFO) << "openProvider_cb(" << toString(status) << ")";
- if (status == BluetoothAudioStatus::SUCCESS) {
- provider_2_1_ = provider_2_1;
- }
- ALOGE_IF(!provider_2_1_, "Failed to open BluetoothAudio provider_2_1");
- openProvider_promise.set_value();
- };
- hidl_retval = providersFactory->openProvider_2_1(
- transport_->GetSessionType_2_1(), openProvider_cb);
- openProvider_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioHal::openProvider failure: "
- << hidl_retval.description();
- }
- CHECK(provider_2_1_ != nullptr);
-
- if (!provider_2_1_->linkToDeath(death_recipient_, 0).isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
-
- LOG(INFO) << "IBluetoothAudioProvidersFactory::openProvider() returned "
- << provider_2_1_.get()
- << (provider_2_1_->isRemote() ? " (remote)" : " (local)");
-}
-
-BluetoothAudioSinkClientInterface::BluetoothAudioSinkClientInterface(
- IBluetoothSinkTransportInstance* sink,
- bluetooth::common::MessageLoopThread* message_loop)
- : BluetoothAudioClientInterface{new BluetoothAudioDeathRecipient(
- this, message_loop),
- sink},
- sink_(sink) {
- if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
- return;
- }
-
- if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_1) &&
- (sink_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_1();
- return;
- }
- FetchAudioProvider();
-}
-
-BluetoothAudioSinkClientInterface::~BluetoothAudioSinkClientInterface() {
- if (provider_ != nullptr) {
- auto hidl_retval = provider_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
- if (provider_2_1_ != nullptr) {
- auto hidl_retval = provider_2_1_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
-}
-
-BluetoothAudioSourceClientInterface::BluetoothAudioSourceClientInterface(
- IBluetoothSourceTransportInstance* source,
- bluetooth::common::MessageLoopThread* message_loop)
- : BluetoothAudioClientInterface{new BluetoothAudioDeathRecipient(
- this, message_loop),
- source},
- source_(source) {
- if (HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_UNAVAILABLE) {
- return;
- }
-
- if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_1) &&
- (source_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_1();
- return;
- }
- FetchAudioProvider();
-}
-
-BluetoothAudioSourceClientInterface::~BluetoothAudioSourceClientInterface() {
- if (provider_ != nullptr) {
- auto hidl_retval = provider_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
- if (provider_2_1_ != nullptr) {
- auto hidl_retval = provider_2_1_->unlinkToDeath(death_recipient_);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": BluetoothAudioDeathRecipient failure: "
- << hidl_retval.description();
- }
- }
-}
-
-bool BluetoothAudioClientInterface::UpdateAudioConfig(
- const AudioConfiguration& audio_config) {
- bool is_software_session =
- (transport_->GetSessionType() ==
- SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType() ==
- SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
- bool is_offload_session = (transport_->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- auto audio_config_discriminator = audio_config.getDiscriminator();
- bool is_software_audio_config =
- (is_software_session &&
- audio_config_discriminator ==
- AudioConfiguration::hidl_discriminator::pcmConfig);
- bool is_offload_audio_config =
- (is_offload_session &&
- audio_config_discriminator ==
- AudioConfiguration::hidl_discriminator::codecConfig);
- if (!is_software_audio_config && !is_offload_audio_config) {
- return false;
- }
- transport_->UpdateAudioConfiguration(audio_config);
- return true;
-}
-
-bool BluetoothAudioClientInterface::UpdateAudioConfig_2_1(
- const AudioConfiguration_2_1& audio_config_2_1) {
- bool is_software_session =
- (transport_->GetSessionType_2_1() ==
- SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
- transport_->GetSessionType_2_1() ==
- SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
- bool is_offload_session = (transport_->GetSessionType_2_1() ==
- SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- auto audio_config_discriminator = audio_config_2_1.getDiscriminator();
- bool is_software_audio_config =
- (is_software_session &&
- audio_config_discriminator ==
- AudioConfiguration_2_1::hidl_discriminator::pcmConfig);
- bool is_offload_audio_config =
- (is_offload_session &&
- audio_config_discriminator ==
- AudioConfiguration_2_1::hidl_discriminator::codecConfig);
- if (!is_software_audio_config && !is_offload_audio_config) {
- return false;
- }
- transport_->UpdateAudioConfiguration_2_1(audio_config_2_1);
- return true;
-}
-
-int BluetoothAudioClientInterface::StartSession() {
- std::lock_guard<std::mutex> guard(internal_mutex_);
- if (provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- session_started_ = false;
- return -EINVAL;
- }
- if (session_started_) {
- LOG(ERROR) << __func__ << ": session started already";
- return -EBUSY;
- }
-
- android::sp<IBluetoothAudioPort> stack_if =
- new BluetoothAudioPortImpl(transport_, provider_);
-
- std::unique_ptr<DataMQ> tempDataMQ;
- BluetoothAudioStatus session_status;
-
- std::promise<void> hidl_startSession_promise;
- auto hidl_startSession_future = hidl_startSession_promise.get_future();
- auto hidl_cb = [&session_status, &tempDataMQ, &hidl_startSession_promise](
- BluetoothAudioStatus status,
- const DataMQ::Descriptor& dataMQ) {
- LOG(INFO) << "startSession_cb(" << toString(status) << ")";
- session_status = status;
- if (status == BluetoothAudioStatus::SUCCESS && dataMQ.isHandleValid()) {
- tempDataMQ.reset(new DataMQ(dataMQ));
- }
- hidl_startSession_promise.set_value();
- };
- auto hidl_retval = provider_->startSession(
- stack_if, transport_->GetAudioConfiguration(), hidl_cb);
- hidl_startSession_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- return -EPROTO;
- }
-
- if (tempDataMQ && tempDataMQ->isValid()) {
- mDataMQ = std::move(tempDataMQ);
- } else if (transport_->GetSessionType() ==
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH &&
- session_status == BluetoothAudioStatus::SUCCESS) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- }
- if (mDataMQ && mDataMQ->isValid()) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- } else {
- ALOGE_IF(!mDataMQ, "Failed to obtain audio data path");
- ALOGE_IF(mDataMQ && !mDataMQ->isValid(), "Audio data path is invalid");
- session_started_ = false;
- return -EIO;
- }
-}
-
-int BluetoothAudioClientInterface::StartSession_2_1() {
- std::lock_guard<std::mutex> guard(internal_mutex_);
- if (provider_2_1_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- session_started_ = false;
- return -EINVAL;
- }
- if (session_started_) {
- LOG(ERROR) << __func__ << ": session started already";
- return -EBUSY;
- }
-
- android::sp<IBluetoothAudioPort> stack_if =
- new BluetoothAudioPortImpl(transport_, provider_2_1_);
-
- std::unique_ptr<DataMQ> tempDataMQ;
- BluetoothAudioStatus session_status;
-
- std::promise<void> hidl_startSession_promise;
- auto hidl_startSession_future = hidl_startSession_promise.get_future();
- auto hidl_cb = [&session_status, &tempDataMQ, &hidl_startSession_promise](
- BluetoothAudioStatus status,
- const DataMQ::Descriptor& dataMQ) {
- LOG(INFO) << "startSession_cb(" << toString(status) << ")";
- session_status = status;
- if (status == BluetoothAudioStatus::SUCCESS && dataMQ.isHandleValid()) {
- tempDataMQ.reset(new DataMQ(dataMQ));
- }
- hidl_startSession_promise.set_value();
- };
- auto hidl_retval = provider_2_1_->startSession_2_1(
- stack_if, transport_->GetAudioConfiguration_2_1(), hidl_cb);
- hidl_startSession_future.get();
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- return -EPROTO;
- }
-
- if (tempDataMQ && tempDataMQ->isValid()) {
- mDataMQ = std::move(tempDataMQ);
- } else if (transport_->GetSessionType_2_1() ==
- SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH &&
- session_status == BluetoothAudioStatus::SUCCESS) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- }
- if (mDataMQ && mDataMQ->isValid()) {
- transport_->ResetPresentationPosition();
- session_started_ = true;
- return 0;
- } else {
- ALOGE_IF(!mDataMQ, "Failed to obtain audio data path");
- ALOGE_IF(mDataMQ && !mDataMQ->isValid(), "Audio data path is invalid");
- session_started_ = false;
- return -EIO;
- }
-}
-
-void BluetoothAudioClientInterface::StreamStarted(
- const BluetoothAudioCtrlAck& ack) {
- if (provider_ == nullptr && provider_2_1_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return;
- }
- if (ack == BluetoothAudioCtrlAck::PENDING) {
- LOG(INFO) << __func__ << ": " << ack << " ignored";
- return;
- }
- BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
-
- ::android::hardware::Return<void> hidl_retval;
- if (provider_2_1_ != nullptr)
- hidl_retval = provider_2_1_->streamStarted(status);
- else
- hidl_retval = provider_->streamStarted(status);
-
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- }
-}
-
-void BluetoothAudioClientInterface::StreamSuspended(
- const BluetoothAudioCtrlAck& ack) {
- if (provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return;
- }
- if (ack == BluetoothAudioCtrlAck::PENDING) {
- LOG(INFO) << __func__ << ": " << ack << " ignored";
- return;
- }
- BluetoothAudioStatus status = BluetoothAudioCtrlAckToHalStatus(ack);
-
- ::android::hardware::Return<void> hidl_retval;
- if (provider_2_1_ != nullptr)
- hidl_retval = provider_2_1_->streamSuspended(status);
- else
- hidl_retval = provider_->streamSuspended(status);
-
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- }
-}
-
-int BluetoothAudioClientInterface::EndSession() {
- std::lock_guard<std::mutex> guard(internal_mutex_);
- if (!session_started_) {
- LOG(INFO) << __func__ << ": session ended already";
- return 0;
- }
-
- session_started_ = false;
- if (provider_2_1_ == nullptr && provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return -EINVAL;
- }
- mDataMQ = nullptr;
-
- ::android::hardware::Return<void> hidl_retval;
- if (provider_2_1_ != nullptr)
- hidl_retval = provider_2_1_->endSession();
- else
- hidl_retval = provider_->endSession();
-
- if (!hidl_retval.isOk()) {
- LOG(ERROR) << __func__
- << ": BluetoothAudioHal failure: " << hidl_retval.description();
- return -EPROTO;
- }
- return 0;
-}
-
-void BluetoothAudioClientInterface::FlushAudioData() {
- size_t size = mDataMQ->availableToRead();
- uint8_t p_buf[size];
-
- if (mDataMQ->read(p_buf, size) != size)
- LOG(WARNING) << __func__ << ", failed to flush data queue!";
-}
-
-size_t BluetoothAudioSinkClientInterface::ReadAudioData(uint8_t* p_buf,
- uint32_t len) {
- if (!IsValid()) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal is not valid";
- return 0;
- }
- if (p_buf == nullptr || len == 0) return 0;
-
- std::lock_guard<std::mutex> guard(internal_mutex_);
-
- size_t total_read = 0;
- int timeout_ms = kDefaultDataReadTimeoutMs;
- do {
- if (mDataMQ == nullptr || !mDataMQ->isValid()) break;
-
- size_t avail_to_read = mDataMQ->availableToRead();
- if (avail_to_read) {
- if (avail_to_read > len - total_read) {
- avail_to_read = len - total_read;
- }
- if (mDataMQ->read(p_buf + total_read, avail_to_read) == 0) {
- LOG(WARNING) << __func__ << ": len=" << len
- << " total_read=" << total_read << " failed";
- break;
- }
- total_read += avail_to_read;
- } else if (timeout_ms >= kDefaultDataReadPollIntervalMs) {
- std::this_thread::sleep_for(
- std::chrono::milliseconds(kDefaultDataReadPollIntervalMs));
- timeout_ms -= kDefaultDataReadPollIntervalMs;
- continue;
- } else {
- LOG(WARNING) << __func__ << ": " << (len - total_read) << "/" << len
- << " no data " << (kDefaultDataReadTimeoutMs - timeout_ms)
- << " ms";
- break;
- }
- } while (total_read < len);
-
- if (timeout_ms <
- (kDefaultDataReadTimeoutMs - kDefaultDataReadPollIntervalMs) &&
- timeout_ms >= kDefaultDataReadPollIntervalMs) {
- VLOG(1) << __func__ << ": underflow " << len << " -> " << total_read
- << " read " << (kDefaultDataReadTimeoutMs - timeout_ms) << " ms";
- } else {
- VLOG(2) << __func__ << ": " << len << " -> " << total_read << " read";
- }
-
- sink_->LogBytesRead(total_read);
- return total_read;
-}
-
-void BluetoothAudioClientInterface::RenewAudioProviderAndSession() {
- // NOTE: must be invoked on the same thread where this
- // BluetoothAudioClientInterface is running
- if ((HalVersionManager::GetHalVersion() ==
- BluetoothAudioHalVersion::VERSION_2_1) &&
- (transport_->GetSessionType_2_1() != SessionType_2_1::UNKNOWN)) {
- FetchAudioProvider_2_1();
- } else if (transport_->GetSessionType() != SessionType::UNKNOWN) {
- FetchAudioProvider();
- } else {
- LOG(FATAL) << __func__ << ", cannot renew audio provider";
- return;
- }
-
- if (session_started_) {
- LOG(INFO) << __func__ << ": Restart the session while audio HAL recovering";
- session_started_ = false;
-
- if (provider_2_1_ != nullptr)
- StartSession_2_1();
- else
- StartSession();
- }
-}
-
-size_t BluetoothAudioSourceClientInterface::WriteAudioData(const uint8_t* p_buf,
- uint32_t len) {
- if (provider_ == nullptr) {
- LOG(ERROR) << __func__ << ": BluetoothAudioHal nullptr";
- return 0;
- }
- if (p_buf == nullptr || len == 0) return 0;
-
- std::lock_guard<std::mutex> guard(internal_mutex_);
-
- size_t total_written = 0;
- int timeout_ms = kDefaultDataWriteTimeoutMs;
- do {
- if (mDataMQ == nullptr || !mDataMQ->isValid()) break;
-
- size_t avail_to_write = mDataMQ->availableToWrite();
- if (avail_to_write) {
- if (avail_to_write > len - total_written) {
- avail_to_write = len - total_written;
- }
- if (mDataMQ->write(p_buf + total_written, avail_to_write) == 0) {
- LOG(WARNING) << __func__ << ": len=" << len
- << " total_written=" << total_written << " failed";
- break;
- }
- total_written += avail_to_write;
- } else if (timeout_ms >= kDefaultDataWritePollIntervalMs) {
- std::this_thread::sleep_for(
- std::chrono::milliseconds(kDefaultDataWritePollIntervalMs));
- timeout_ms -= kDefaultDataWritePollIntervalMs;
- continue;
- } else {
- LOG(WARNING) << __func__ << ": " << (len - total_written) << "/" << len
- << " no data " << (kDefaultDataWriteTimeoutMs - timeout_ms)
- << " ms";
- break;
- }
- } while (total_written < len);
-
- if (timeout_ms <
- (kDefaultDataWriteTimeoutMs - kDefaultDataWritePollIntervalMs) &&
- timeout_ms >= kDefaultDataWritePollIntervalMs) {
- VLOG(1) << __func__ << ": underflow " << len << " -> " << total_written
- << " read " << (kDefaultDataWriteTimeoutMs - timeout_ms) << " ms";
- } else {
- VLOG(2) << __func__ << ": " << len << " -> " << total_written << " written";
- }
-
- source_->LogBytesWritten(total_written);
- return total_written;
-}
-
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/client_interface.h b/audio_hal_interface/client_interface.h
deleted file mode 100644
index b9f18b9..0000000
--- a/audio_hal_interface/client_interface.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright 2019 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 <time.h>
-#include <mutex>
-#include <vector>
-
-#include <android/hardware/bluetooth/audio/2.1/IBluetoothAudioProvider.h>
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-#include <fmq/MessageQueue.h>
-#include <hardware/audio.h>
-
-#include "common/message_loop_thread.h"
-
-#define BLUETOOTH_AUDIO_HAL_PROP_DISABLED "persist.bluetooth.bluetooth_audio_hal.disabled"
-
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
-using AudioCapabilities =
- ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
-using AudioCapabilities_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::AudioCapabilities;
-using AudioConfiguration =
- ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
-using AudioConfiguration_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using IBluetoothAudioProvider =
- ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioProvider;
-using IBluetoothAudioProvider_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::IBluetoothAudioProvider;
-using PcmParameters =
- ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
-using PcmParameters_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using SampleRate = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-using SessionType = ::android::hardware::bluetooth::audio::V2_0::SessionType;
-using SessionType_2_1 =
- ::android::hardware::bluetooth::audio::V2_1::SessionType;
-using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
-using BluetoothAudioStatus =
- ::android::hardware::bluetooth::audio::V2_0::Status;
-
-enum class BluetoothAudioCtrlAck : uint8_t {
- SUCCESS_FINISHED = 0,
- PENDING,
- FAILURE_UNSUPPORTED,
- FAILURE_BUSY,
- FAILURE_DISCONNECTING,
- FAILURE
-};
-
-std::ostream& operator<<(std::ostream& os, const BluetoothAudioCtrlAck& ack);
-
-inline BluetoothAudioStatus BluetoothAudioCtrlAckToHalStatus(
- const BluetoothAudioCtrlAck& ack) {
- switch (ack) {
- case BluetoothAudioCtrlAck::SUCCESS_FINISHED:
- return BluetoothAudioStatus::SUCCESS;
- case BluetoothAudioCtrlAck::FAILURE_UNSUPPORTED:
- return BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION;
- case BluetoothAudioCtrlAck::PENDING:
- return BluetoothAudioStatus::FAILURE;
- case BluetoothAudioCtrlAck::FAILURE_BUSY:
- return BluetoothAudioStatus::FAILURE;
- case BluetoothAudioCtrlAck::FAILURE_DISCONNECTING:
- return BluetoothAudioStatus::FAILURE;
- default:
- return BluetoothAudioStatus::FAILURE;
- }
-}
-
-// An IBluetoothTransportInstance needs to be implemented by a Bluetooth
-// audio transport, such as A2DP or Hearing Aid, to handle callbacks from Audio
-// HAL.
-class IBluetoothTransportInstance {
- public:
- IBluetoothTransportInstance(SessionType sessionType,
- AudioConfiguration audioConfig)
- : session_type_(sessionType),
- session_type_2_1_(SessionType_2_1::UNKNOWN),
- audio_config_(std::move(audioConfig)),
- audio_config_2_1_({}){};
- IBluetoothTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_1 audioConfig_2_1)
- : session_type_(SessionType::UNKNOWN),
- session_type_2_1_(sessionType_2_1),
- audio_config_({}),
- audio_config_2_1_(std::move(audioConfig_2_1)){};
- virtual ~IBluetoothTransportInstance() = default;
-
- SessionType GetSessionType() const { return session_type_; }
- SessionType_2_1 GetSessionType_2_1() const { return session_type_2_1_; }
-
- AudioConfiguration GetAudioConfiguration() const { return audio_config_; }
- AudioConfiguration_2_1 GetAudioConfiguration_2_1() const {
- return audio_config_2_1_;
- }
-
- void UpdateAudioConfiguration(const AudioConfiguration& audio_config) {
- audio_config_ = audio_config;
- }
- void UpdateAudioConfiguration_2_1(
- const AudioConfiguration_2_1& audio_config_2_1) {
- audio_config_2_1_ = audio_config_2_1;
- }
-
- virtual BluetoothAudioCtrlAck StartRequest() = 0;
-
- virtual BluetoothAudioCtrlAck SuspendRequest() = 0;
-
- virtual void StopRequest() = 0;
-
- virtual bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position) = 0;
-
- virtual void MetadataChanged(const source_metadata_t& source_metadata) = 0;
-
- // Invoked when the transport is requested to reset presentation position
- virtual void ResetPresentationPosition() = 0;
-
- private:
- const SessionType session_type_;
- const SessionType_2_1 session_type_2_1_;
- AudioConfiguration audio_config_;
- AudioConfiguration_2_1 audio_config_2_1_;
-};
-
-// An IBluetoothSinkTransportInstance needs to be implemented by a Bluetooth
-// audio transport, such as A2DP, Hearing Aid or LeAudio, to handle callbacks
-// from Audio HAL.
-class IBluetoothSinkTransportInstance : public IBluetoothTransportInstance {
- public:
- IBluetoothSinkTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_1 audioConfig_2_1)
- : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
- IBluetoothSinkTransportInstance(SessionType sessionType,
- AudioConfiguration audioConfig)
- : IBluetoothTransportInstance{sessionType, audioConfig} {}
- virtual ~IBluetoothSinkTransportInstance() = default;
-
- // Invoked when the transport is requested to log bytes read
- virtual void LogBytesRead(size_t bytes_readed) = 0;
-};
-
-class IBluetoothSourceTransportInstance : public IBluetoothTransportInstance {
- public:
- IBluetoothSourceTransportInstance(SessionType sessionType,
- AudioConfiguration audioConfig)
- : IBluetoothTransportInstance{sessionType, audioConfig} {}
- IBluetoothSourceTransportInstance(SessionType_2_1 sessionType_2_1,
- AudioConfiguration_2_1 audioConfig_2_1)
- : IBluetoothTransportInstance{sessionType_2_1, audioConfig_2_1} {}
- virtual ~IBluetoothSourceTransportInstance() = default;
-
- // Invoked when the transport is requested to log bytes written
- virtual void LogBytesWritten(size_t bytes_written) = 0;
-};
-
-// common object is shared between different kind of SessionType
-class BluetoothAudioDeathRecipient;
-
-// The client interface connects an IBluetoothTransportInstance to
-// IBluetoothAudioProvider and helps to route callbacks to
-// IBluetoothTransportInstance
-class BluetoothAudioClientInterface {
- public:
- BluetoothAudioClientInterface(
- android::sp<BluetoothAudioDeathRecipient> death_recipient,
- IBluetoothTransportInstance* instance);
- virtual ~BluetoothAudioClientInterface() = default;
-
- bool IsValid() const {
- return provider_ != nullptr || provider_2_1_ != nullptr;
- }
-
- std::vector<AudioCapabilities> GetAudioCapabilities() const;
- std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1() const;
- static std::vector<AudioCapabilities> GetAudioCapabilities(
- SessionType session_type);
- static std::vector<AudioCapabilities_2_1> GetAudioCapabilities_2_1(
- SessionType_2_1 session_type_2_1);
-
- void StreamStarted(const BluetoothAudioCtrlAck& ack);
-
- void StreamSuspended(const BluetoothAudioCtrlAck& ack);
-
- int StartSession();
- int StartSession_2_1();
-
- // Renew the connection and usually is used when HIDL restarted
- void RenewAudioProviderAndSession();
-
- int EndSession();
-
- bool UpdateAudioConfig(const AudioConfiguration& audioConfig);
- bool UpdateAudioConfig_2_1(const AudioConfiguration_2_1& audioConfig_2_1);
-
- void FlushAudioData();
-
- static constexpr PcmParameters kInvalidPcmConfiguration = {
- .sampleRate = SampleRate::RATE_UNKNOWN,
- .channelMode = ChannelMode::UNKNOWN,
- .bitsPerSample = BitsPerSample::BITS_UNKNOWN};
-
- protected:
- mutable std::mutex internal_mutex_;
- // Helper function to connect to an IBluetoothAudioProvider
- void FetchAudioProvider();
- // Helper function to connect to an IBluetoothAudioProvider 2.1
- void FetchAudioProvider_2_1();
-
- android::sp<IBluetoothAudioProvider> provider_;
- android::sp<IBluetoothAudioProvider_2_1> provider_2_1_;
- bool session_started_;
- std::unique_ptr<::android::hardware::MessageQueue<
- uint8_t, ::android::hardware::kSynchronizedReadWrite>>
- mDataMQ;
- android::sp<BluetoothAudioDeathRecipient> death_recipient_;
-
- private:
- IBluetoothTransportInstance* transport_;
- std::vector<AudioCapabilities> capabilities_;
- std::vector<AudioCapabilities_2_1> capabilities_2_1_;
-};
-
-// The client interface connects an IBluetoothTransportInstance to
-// IBluetoothAudioProvider and helps to route callbacks to
-// IBluetoothTransportInstance
-class BluetoothAudioSinkClientInterface : public BluetoothAudioClientInterface {
- public:
- // Constructs an BluetoothAudioSinkClientInterface to communicate to
- // BluetoothAudio HAL. |sink| is the implementation for the transport, and
- // |message_loop| is the thread where callbacks are invoked.
- BluetoothAudioSinkClientInterface(
- IBluetoothSinkTransportInstance* sink,
- bluetooth::common::MessageLoopThread* message_loop);
- virtual ~BluetoothAudioSinkClientInterface();
-
- IBluetoothSinkTransportInstance* GetTransportInstance() const {
- return sink_;
- }
-
- // Read data from audio HAL through fmq
- size_t ReadAudioData(uint8_t* p_buf, uint32_t len);
-
- private:
- IBluetoothSinkTransportInstance* sink_;
-};
-
-class BluetoothAudioSourceClientInterface
- : public BluetoothAudioClientInterface {
- public:
- // Constructs an BluetoothAudioSourceClientInterface to communicate to
- // BluetoothAudio HAL. |source| is the implementation for the transport, and
- // |message_loop| is the thread where callbacks are invoked.
- BluetoothAudioSourceClientInterface(
- IBluetoothSourceTransportInstance* source,
- bluetooth::common::MessageLoopThread* message_loop);
- virtual ~BluetoothAudioSourceClientInterface();
-
- // Write data to audio HAL through fmq
- size_t WriteAudioData(const uint8_t* p_buf, uint32_t len);
-
- private:
- IBluetoothSourceTransportInstance* source_;
-};
-
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/client_interface_unittest.cc b/audio_hal_interface/client_interface_unittest.cc
deleted file mode 100644
index 33954c7..0000000
--- a/audio_hal_interface/client_interface_unittest.cc
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Copyright 2019 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 "bluetooth"
-
-#include <gtest/gtest.h>
-
-#include "client_interface.h"
-#include "codec_status.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
-using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
-using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
-using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
-using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
-using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
-using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
-using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
-
-using ::bluetooth::audio::AudioCapabilities;
-using ::bluetooth::audio::AudioCapabilities_2_1;
-using ::bluetooth::audio::AudioConfiguration;
-using ::bluetooth::audio::AudioConfiguration_2_1;
-using ::bluetooth::audio::BluetoothAudioClientInterface;
-using ::bluetooth::audio::BluetoothAudioSinkClientInterface;
-using ::bluetooth::audio::BluetoothAudioSourceClientInterface;
-using ::bluetooth::audio::BluetoothAudioStatus;
-using ::bluetooth::audio::PcmParameters;
-using ::bluetooth::audio::PcmParameters_2_1;
-using ::bluetooth::audio::SampleRate;
-using ::bluetooth::audio::SampleRate_2_1;
-using ::bluetooth::audio::SessionType;
-using ::bluetooth::audio::SessionType_2_1;
-using ::bluetooth::audio::codec::A2dpCodecToHalBitsPerSample;
-using ::bluetooth::audio::codec::A2dpCodecToHalChannelMode;
-using ::bluetooth::audio::codec::A2dpCodecToHalSampleRate;
-using ::bluetooth::audio::codec::BitsPerSample;
-using ::bluetooth::audio::codec::ChannelMode;
-using ::bluetooth::audio::codec::CodecConfiguration;
-using ::bluetooth::audio::codec::IsCodecOffloadingEnabled;
-using ::bluetooth::audio::codec::UpdateOffloadingCapabilities;
-using ::testing::Test;
-
-struct SampleRatePair {
- SampleRate hal_sample_rate_;
- btav_a2dp_codec_sample_rate_t btav_sample_rate_;
-};
-constexpr SampleRatePair kSampleRatePairs[9] = {
- {.hal_sample_rate_ = SampleRate::RATE_UNKNOWN,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE},
- {.hal_sample_rate_ = SampleRate::RATE_44100,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_44100},
- {.hal_sample_rate_ = SampleRate::RATE_48000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_48000},
- {.hal_sample_rate_ = SampleRate::RATE_88200,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_88200},
- {.hal_sample_rate_ = SampleRate::RATE_96000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_96000},
- {.hal_sample_rate_ = SampleRate::RATE_176400,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_176400},
- {.hal_sample_rate_ = SampleRate::RATE_192000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_192000},
- {.hal_sample_rate_ = SampleRate::RATE_16000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_16000},
- {.hal_sample_rate_ = SampleRate::RATE_24000,
- .btav_sample_rate_ = BTAV_A2DP_CODEC_SAMPLE_RATE_24000}};
-
-constexpr SampleRate_2_1 kSampleRates_2_1[] = {
- SampleRate_2_1::RATE_UNKNOWN, SampleRate_2_1::RATE_8000,
- SampleRate_2_1::RATE_16000, SampleRate_2_1::RATE_24000,
- SampleRate_2_1::RATE_32000, SampleRate_2_1::RATE_44100,
- SampleRate_2_1::RATE_48000};
-
-constexpr uint32_t kDataIntervalUs[] = {0 /* Invalid */,
- 10000 /* Valid 10ms */};
-
-struct BitsPerSamplePair {
- BitsPerSample hal_bits_per_sample_;
- btav_a2dp_codec_bits_per_sample_t btav_bits_per_sample_;
-};
-constexpr BitsPerSamplePair kBitsPerSamplePairs[4] = {
- {.hal_bits_per_sample_ = BitsPerSample::BITS_UNKNOWN,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE},
- {.hal_bits_per_sample_ = BitsPerSample::BITS_16,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16},
- {.hal_bits_per_sample_ = BitsPerSample::BITS_24,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24},
- {.hal_bits_per_sample_ = BitsPerSample::BITS_32,
- .btav_bits_per_sample_ = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32}};
-
-struct ChannelModePair {
- ChannelMode hal_channel_mode_;
- btav_a2dp_codec_channel_mode_t btav_channel_mode_;
-};
-constexpr ChannelModePair kChannelModePairs[3] = {
- {.hal_channel_mode_ = ChannelMode::UNKNOWN,
- .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE},
- {.hal_channel_mode_ = ChannelMode::MONO,
- .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO},
- {.hal_channel_mode_ = ChannelMode::STEREO,
- .btav_channel_mode_ = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO}};
-
-constexpr btav_a2dp_codec_index_t codec_indexes[] = {
- BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
- BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
- BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC, BTAV_A2DP_CODEC_INDEX_SINK_SBC,
- BTAV_A2DP_CODEC_INDEX_SINK_AAC, BTAV_A2DP_CODEC_INDEX_SINK_LDAC};
-constexpr uint16_t kPeerMtus[5] = {660, 663, 883, 1005, 1500};
-
-class TestSinkTransport
- : public bluetooth::audio::IBluetoothSinkTransportInstance {
- private:
- static constexpr uint64_t kRemoteDelayReportMs = 200;
-
- public:
- TestSinkTransport(SessionType session_type)
- : bluetooth::audio::IBluetoothSinkTransportInstance(session_type, {}){};
- TestSinkTransport(SessionType_2_1 session_type_2_1)
- : bluetooth::audio::IBluetoothSinkTransportInstance(session_type_2_1,
- {}){};
- bluetooth::audio::BluetoothAudioCtrlAck StartRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- void StopRequest() override {}
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position) override {
- if (remote_delay_report_ns) {
- *remote_delay_report_ns = kRemoteDelayReportMs * 1000000;
- }
- if (total_bytes_readed) {
- *total_bytes_readed = 0;
- }
- if (data_position) {
- clock_gettime(CLOCK_MONOTONIC, data_position);
- }
- return true;
- }
- void MetadataChanged(
- const source_metadata_t& source_metadata __unused) override {}
- void ResetPresentationPosition() override{};
- void LogBytesRead(size_t bytes_readed __unused) override{};
-};
-
-class TestSourceTransport
- : public bluetooth::audio::IBluetoothSourceTransportInstance {
- private:
- static constexpr uint64_t kRemoteDelayReportMs = 200;
-
- public:
- TestSourceTransport(SessionType session_type)
- : bluetooth::audio::IBluetoothSourceTransportInstance(session_type, {}){};
- TestSourceTransport(SessionType_2_1 session_type_2_1)
- : bluetooth::audio::IBluetoothSourceTransportInstance(session_type_2_1,
- {}){};
- bluetooth::audio::BluetoothAudioCtrlAck StartRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- bluetooth::audio::BluetoothAudioCtrlAck SuspendRequest() override {
- return bluetooth::audio::BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- void StopRequest() override {}
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_written,
- timespec* data_position) override {
- if (remote_delay_report_ns) {
- *remote_delay_report_ns = kRemoteDelayReportMs * 1000000;
- }
- if (total_bytes_written) {
- *total_bytes_written = 0;
- }
- if (data_position) {
- clock_gettime(CLOCK_MONOTONIC, data_position);
- }
- return true;
- }
- void MetadataChanged(
- const source_metadata_t& source_metadata __unused) override {}
- void ResetPresentationPosition() override{};
- void LogBytesWritten(size_t bytes_written __unused) override{};
-};
-
-class BluetoothAudioClientInterfaceTest : public Test {
- protected:
- TestSinkTransport* test_sink_transport_ = nullptr;
- TestSourceTransport* test_source_transport_ = nullptr;
- BluetoothAudioSinkClientInterface* clientif_sink_ = nullptr;
- BluetoothAudioSourceClientInterface* clientif_source_ = nullptr;
-
- static constexpr int kClientIfReturnSuccess = 0;
-
- void SetUp() override {}
-
- void TearDown() override {
- if (clientif_sink_ != nullptr) delete clientif_sink_;
- clientif_sink_ = nullptr;
- if (test_sink_transport_ != nullptr) delete test_sink_transport_;
- test_sink_transport_ = nullptr;
-
- if (clientif_source_ != nullptr) delete clientif_source_;
- clientif_source_ = nullptr;
- if (test_source_transport_ != nullptr) delete test_source_transport_;
- test_source_transport_ = nullptr;
- }
-
- bool IsSoftwarePcmParametersSupported(const PcmParameters& pcm_config) {
- const std::vector<AudioCapabilities>& capabilities =
- clientif_sink_->GetAudioCapabilities();
- PcmParameters pcm_capabilities = capabilities[0].pcmCapabilities();
- bool is_pcm_config_valid =
- (pcm_config.sampleRate != SampleRate::RATE_UNKNOWN &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config.channelMode != ChannelMode::UNKNOWN);
- bool is_pcm_config_supported =
- (pcm_config.sampleRate & pcm_capabilities.sampleRate &&
- pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample &&
- pcm_config.channelMode & pcm_capabilities.channelMode);
- return (is_pcm_config_valid && is_pcm_config_supported);
- }
-
- bool IsSinkSoftwarePcmParameters_2_1_Supported(
- const PcmParameters_2_1& pcm_config) {
- return IsSoftwarePcmParameters_2_1_Supported(pcm_config, clientif_sink_);
- }
-
- bool IsSourceSoftwarePcmParameters_2_1_Supported(
- const PcmParameters_2_1& pcm_config) {
- return IsSoftwarePcmParameters_2_1_Supported(pcm_config, clientif_source_);
- }
-
- bool IsCodecOffloadingSupported(const CodecConfiguration& codec_config) {
- CodecCapabilities codec_capability = {};
- for (auto audio_capability : clientif_sink_->GetAudioCapabilities()) {
- if (audio_capability.codecCapabilities().codecType ==
- codec_config.codecType) {
- codec_capability = audio_capability.codecCapabilities();
- }
- }
- if (codec_capability.codecType != codec_config.codecType) {
- // codec is unsupported
- return false;
- }
- bool is_codec_config_supported = false;
- switch (codec_config.codecType) {
- case CodecType::SBC: {
- SbcParameters sbc_config = codec_config.config.sbcConfig();
- SbcParameters sbc_capability =
- codec_capability.capabilities.sbcCapabilities();
- is_codec_config_supported =
- (sbc_config.sampleRate & sbc_capability.sampleRate &&
- sbc_config.channelMode & sbc_capability.channelMode &&
- sbc_config.blockLength & sbc_capability.blockLength &&
- sbc_config.numSubbands & sbc_capability.numSubbands &&
- sbc_config.allocMethod & sbc_capability.allocMethod &&
- sbc_config.bitsPerSample & sbc_capability.bitsPerSample &&
- (sbc_capability.minBitpool <= sbc_config.minBitpool &&
- sbc_config.minBitpool <= sbc_config.maxBitpool &&
- sbc_config.maxBitpool <= sbc_capability.maxBitpool));
- return is_codec_config_supported;
- }
- case CodecType::AAC: {
- AacParameters aac_config = codec_config.config.aacConfig();
- AacParameters aac_capability =
- codec_capability.capabilities.aacCapabilities();
- is_codec_config_supported =
- (aac_config.objectType & aac_capability.objectType &&
- aac_config.sampleRate & aac_capability.sampleRate &&
- aac_config.channelMode & aac_capability.channelMode &&
- (aac_config.variableBitRateEnabled ==
- AacVariableBitRate::DISABLED ||
- aac_capability.variableBitRateEnabled ==
- AacVariableBitRate::ENABLED) &&
- aac_config.bitsPerSample & aac_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::LDAC: {
- LdacParameters ldac_config = codec_config.config.ldacConfig();
- LdacParameters ldac_capability =
- codec_capability.capabilities.ldacCapabilities();
- is_codec_config_supported =
- (ldac_config.sampleRate & ldac_capability.sampleRate &&
- ldac_config.channelMode & ldac_capability.channelMode &&
- ldac_config.bitsPerSample & ldac_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::APTX:
- [[fallthrough]];
- case CodecType::APTX_HD: {
- AptxParameters aptx_config = codec_config.config.aptxConfig();
- AptxParameters aptx_capability =
- codec_capability.capabilities.aptxCapabilities();
- is_codec_config_supported =
- (aptx_config.sampleRate & aptx_capability.sampleRate &&
- aptx_config.channelMode & aptx_capability.channelMode &&
- aptx_config.bitsPerSample & aptx_capability.bitsPerSample);
- return is_codec_config_supported;
- }
- case CodecType::UNKNOWN:
- return false;
- }
- }
-
- private:
- bool IsSoftwarePcmParameters_2_1_Supported(
- const PcmParameters_2_1& pcm_config,
- const BluetoothAudioClientInterface* clientif_) {
- const std::vector<AudioCapabilities_2_1>& capabilities =
- clientif_->GetAudioCapabilities_2_1();
- PcmParameters_2_1 pcm_capabilities = capabilities[0].pcmCapabilities();
- bool is_pcm_config_valid =
- (pcm_config.sampleRate != SampleRate_2_1::RATE_UNKNOWN &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_UNKNOWN &&
- pcm_config.channelMode != ChannelMode::UNKNOWN &&
- pcm_config.dataIntervalUs != 0);
- bool is_pcm_config_supported =
- (pcm_config.sampleRate & pcm_capabilities.sampleRate &&
- pcm_config.bitsPerSample & pcm_capabilities.bitsPerSample &&
- pcm_config.channelMode & pcm_capabilities.channelMode);
- return (is_pcm_config_valid && is_pcm_config_supported);
- }
-};
-
-} // namespace
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpCodecToHalPcmConfig) {
- btav_a2dp_codec_config_t a2dp_codec_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- a2dp_codec_config.sample_rate = sample_rate_pair.btav_sample_rate_;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- a2dp_codec_config.bits_per_sample =
- bits_per_sample_pair.btav_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- a2dp_codec_config.channel_mode = channel_mode_pair.btav_channel_mode_;
- ASSERT_EQ(A2dpCodecToHalSampleRate(a2dp_codec_config),
- sample_rate_pair.hal_sample_rate_);
- ASSERT_EQ(A2dpCodecToHalBitsPerSample(a2dp_codec_config),
- bits_per_sample_pair.hal_bits_per_sample_);
- ASSERT_EQ(A2dpCodecToHalChannelMode(a2dp_codec_config),
- channel_mode_pair.hal_channel_mode_);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpSoftwareSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- PcmParameters pcm_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- pcm_config.sampleRate = sample_rate_pair.hal_sample_rate_;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- audio_config.pcmConfig(pcm_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsSoftwarePcmParametersSupported(pcm_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-struct CodecOffloadingPreference {
- bool is_target_codec_included_;
- std::vector<btav_a2dp_codec_config_t> preference_;
-};
-
-std::vector<CodecOffloadingPreference> CodecOffloadingPreferenceGenerator(
- btav_a2dp_codec_index_t target_codec_index) {
- std::vector<CodecOffloadingPreference> codec_offloading_preferences = {
- {.is_target_codec_included_ = false,
- .preference_ = std::vector<btav_a2dp_codec_config_t>(0)}};
- btav_a2dp_codec_config_t a2dp_codec_config = {};
- for (auto codec_index : codec_indexes) {
- a2dp_codec_config.codec_type = codec_index;
- auto duplicated_preferences = codec_offloading_preferences;
- for (auto iter = duplicated_preferences.begin();
- iter != duplicated_preferences.end(); ++iter) {
- if (codec_index == target_codec_index) {
- iter->is_target_codec_included_ = true;
- }
- iter->preference_.push_back(a2dp_codec_config);
- }
- codec_offloading_preferences.insert(codec_offloading_preferences.end(),
- duplicated_preferences.begin(),
- duplicated_preferences.end());
- }
- return codec_offloading_preferences;
-}
-
-std::vector<CodecConfiguration> SbcCodecConfigurationsGenerator() {
- std::vector<CodecConfiguration> sbc_codec_configs;
- CodecConfiguration codec_config = {};
- SbcBlockLength block_lengths[4] = {
- SbcBlockLength::BLOCKS_4, SbcBlockLength::BLOCKS_8,
- SbcBlockLength::BLOCKS_12, SbcBlockLength::BLOCKS_16};
- SbcNumSubbands num_subbands[2] = {SbcNumSubbands::SUBBAND_4,
- SbcNumSubbands::SUBBAND_8};
- SbcAllocMethod alloc_methods[2] = {SbcAllocMethod::ALLOC_MD_S,
- SbcAllocMethod::ALLOC_MD_L};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto block_length : block_lengths) {
- for (auto num_subband : num_subbands) {
- for (auto alloc_method : alloc_methods) {
- codec_config.codecType = CodecType::SBC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- // A2DP_SBC_DEFAULT_BITRATE
- codec_config.encodedAudioBitrate = 328000;
- SbcParameters sbc = {
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode = (channel_mode_pair.hal_channel_mode_ ==
- ChannelMode::MONO
- ? SbcChannelMode::MONO
- : SbcChannelMode::JOINT_STEREO),
- .blockLength = block_length,
- .numSubbands = num_subband,
- .allocMethod = alloc_method,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_,
- .minBitpool = 2,
- .maxBitpool = 53};
- codec_config.config.sbcConfig(sbc);
- sbc_codec_configs.push_back(codec_config);
- } // SbcAllocMethod
- } // SbcNumSubbands
- } // SbcBlockLength
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return sbc_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpSbcCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto sbc_codec_configs = SbcCodecConfigurationsGenerator();
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_SBC)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : sbc_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadSbcSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config : SbcCodecConfigurationsGenerator()) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-std::vector<CodecConfiguration> AacCodecConfigurationsGenerator() {
- std::vector<CodecConfiguration> aac_codec_configs;
- CodecConfiguration codec_config = {};
- AacObjectType object_types[4] = {
- AacObjectType::MPEG2_LC, AacObjectType::MPEG4_LC,
- AacObjectType::MPEG4_LTP, AacObjectType::MPEG4_SCALABLE};
- AacVariableBitRate variable_bitrates[2] = {AacVariableBitRate::DISABLED,
- AacVariableBitRate::ENABLED};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto object_type : object_types) {
- for (auto variable_bitrate : variable_bitrates) {
- codec_config.codecType = CodecType::AAC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- // A2DP_AAC_DEFAULT_BITRATE
- codec_config.encodedAudioBitrate = 320000;
- AacParameters aac = {
- .objectType = object_type,
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode = channel_mode_pair.hal_channel_mode_,
- .variableBitRateEnabled = variable_bitrate,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
- codec_config.config.aacConfig(aac);
- aac_codec_configs.push_back(codec_config);
- } // AacVariableBitRate
- } // AacObjectType
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return aac_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpAacCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto aac_codec_configs = AacCodecConfigurationsGenerator();
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_AAC)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : aac_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAacSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config : AacCodecConfigurationsGenerator()) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-std::vector<CodecConfiguration> LdacCodecConfigurationsGenerator() {
- std::vector<CodecConfiguration> ldac_codec_configs;
- CodecConfiguration codec_config = {};
- LdacQualityIndex quality_indexes[4] = {
- LdacQualityIndex::QUALITY_HIGH, LdacQualityIndex::QUALITY_MID,
- LdacQualityIndex::QUALITY_LOW, LdacQualityIndex::QUALITY_ABR};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- for (auto quality_index : quality_indexes) {
- codec_config.codecType = CodecType::LDAC;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 990000;
- LdacParameters ldac = {
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode =
- (channel_mode_pair.hal_channel_mode_ == ChannelMode::MONO
- ? LdacChannelMode::MONO
- : LdacChannelMode::STEREO),
- .qualityIndex = quality_index,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
- codec_config.config.ldacConfig(ldac);
- ldac_codec_configs.push_back(codec_config);
- } // LdacQualityIndex
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return ldac_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpLdacCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto ldac_codec_configs = LdacCodecConfigurationsGenerator();
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : ldac_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadLdacSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config : LdacCodecConfigurationsGenerator()) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-std::vector<CodecConfiguration> AptxCodecConfigurationsGenerator(
- CodecType codec_type) {
- std::vector<CodecConfiguration> aptx_codec_configs;
- if (codec_type != CodecType::APTX && codec_type != CodecType::APTX_HD)
- return aptx_codec_configs;
- CodecConfiguration codec_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- for (auto channel_mode_pair : kChannelModePairs) {
- for (auto peer_mtu : kPeerMtus) {
- codec_config.codecType = codec_type;
- codec_config.peerMtu = peer_mtu;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate =
- (codec_type == CodecType::APTX ? 352000 : 576000);
- AptxParameters aptx = {
- .sampleRate = sample_rate_pair.hal_sample_rate_,
- .channelMode = channel_mode_pair.hal_channel_mode_,
- .bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_};
- codec_config.config.aptxConfig(aptx);
- aptx_codec_configs.push_back(codec_config);
- } // peerMtu
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
- return aptx_codec_configs;
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpAptxCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto aptx_codec_configs = AptxCodecConfigurationsGenerator(CodecType::APTX);
- for (auto codec_offloading_preference :
- CodecOffloadingPreferenceGenerator(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : aptx_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config :
- AptxCodecConfigurationsGenerator(CodecType::APTX)) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, A2dpAptxHdCodecOffloadingState) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- auto aptx_hd_codec_configs =
- AptxCodecConfigurationsGenerator(CodecType::APTX_HD);
- for (auto codec_offloading_preference : CodecOffloadingPreferenceGenerator(
- BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD)) {
- UpdateOffloadingCapabilities(codec_offloading_preference.preference_);
- for (CodecConfiguration codec_config : aptx_hd_codec_configs) {
- if (IsCodecOffloadingSupported(codec_config) &&
- codec_offloading_preference.is_target_codec_included_) {
- ASSERT_TRUE(IsCodecOffloadingEnabled(codec_config));
- } else {
- ASSERT_FALSE(IsCodecOffloadingEnabled(codec_config));
- }
- }
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest, StartAndEndA2dpOffloadAptxHdSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- for (CodecConfiguration codec_config :
- AptxCodecConfigurationsGenerator(CodecType::APTX_HD)) {
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- }
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndA2dpOffloadUnknownSession) {
- test_sink_transport_ =
- new TestSinkTransport(SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- CodecConfiguration codec_config = {};
- codec_config.codecType = CodecType::UNKNOWN;
- codec_config.peerMtu = 1005;
- codec_config.isScmstEnabled = false;
- codec_config.encodedAudioBitrate = 328000;
- codec_config.config = {};
- audio_config.codecConfig(codec_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsCodecOffloadingSupported(codec_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndHearingAidSoftwareSession) {
- test_sink_transport_ = new TestSinkTransport(
- SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration audio_config = {};
- PcmParameters pcm_config = {};
- for (auto sample_rate_pair : kSampleRatePairs) {
- pcm_config.sampleRate = sample_rate_pair.hal_sample_rate_;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- audio_config.pcmConfig(pcm_config);
- clientif_sink_->UpdateAudioConfig(audio_config);
- if (IsSoftwarePcmParametersSupported(pcm_config)) {
- ASSERT_EQ(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession(), kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndLeAudioEncodingSoftwareSession) {
- test_sink_transport_ = new TestSinkTransport(
- SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH);
- clientif_sink_ =
- new BluetoothAudioSinkClientInterface(test_sink_transport_, nullptr);
- AudioConfiguration_2_1 audio_config = {};
- PcmParameters_2_1 pcm_config = {};
- for (auto sample_rate : kSampleRates_2_1) {
- pcm_config.sampleRate = sample_rate;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- for (auto data_interval_us : kDataIntervalUs) {
- pcm_config.dataIntervalUs = data_interval_us;
- audio_config.pcmConfig(pcm_config);
- clientif_sink_->UpdateAudioConfig_2_1(audio_config);
- if (IsSinkSoftwarePcmParameters_2_1_Supported(pcm_config)) {
- ASSERT_EQ(clientif_sink_->StartSession_2_1(),
- kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_sink_->StartSession_2_1(),
- kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_sink_->EndSession(), kClientIfReturnSuccess);
- } // dataIntervalUs
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
-
-TEST_F(BluetoothAudioClientInterfaceTest,
- StartAndEndLeAudioDecodedSoftwareSession) {
- test_source_transport_ = new TestSourceTransport(
- SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
- clientif_source_ =
- new BluetoothAudioSourceClientInterface(test_source_transport_, nullptr);
- AudioConfiguration_2_1 audio_config = {};
- PcmParameters_2_1 pcm_config = {};
- for (auto sample_rate : kSampleRates_2_1) {
- pcm_config.sampleRate = sample_rate;
- for (auto bits_per_sample_pair : kBitsPerSamplePairs) {
- pcm_config.bitsPerSample = bits_per_sample_pair.hal_bits_per_sample_;
- for (auto channel_mode_pair : kChannelModePairs) {
- pcm_config.channelMode = channel_mode_pair.hal_channel_mode_;
- for (auto data_interval_us : kDataIntervalUs) {
- pcm_config.dataIntervalUs = data_interval_us;
- audio_config.pcmConfig(pcm_config);
- clientif_source_->UpdateAudioConfig_2_1(audio_config);
- if (IsSourceSoftwarePcmParameters_2_1_Supported(pcm_config)) {
- ASSERT_EQ(clientif_source_->StartSession_2_1(),
- kClientIfReturnSuccess);
- } else {
- ASSERT_NE(clientif_source_->StartSession_2_1(),
- kClientIfReturnSuccess);
- }
- ASSERT_EQ(clientif_source_->EndSession(), kClientIfReturnSuccess);
- } // dataIntervalUs
- } // ChannelMode
- } // BitsPerSampple
- } // SampleRate
-}
diff --git a/audio_hal_interface/codec_status.cc b/audio_hal_interface/codec_status.cc
deleted file mode 100644
index 1287066..0000000
--- a/audio_hal_interface/codec_status.cc
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright 2019 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 "bluetooth"
-
-#include "codec_status.h"
-#include "client_interface.h"
-
-#include "a2dp_aac_constants.h"
-#include "a2dp_sbc_constants.h"
-#include "a2dp_vendor_aptx_constants.h"
-#include "a2dp_vendor_aptx_hd_constants.h"
-#include "a2dp_vendor_ldac_constants.h"
-#include "bta/av/bta_av_int.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
-using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
-using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
-using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
-using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
-using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
-using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
-using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
-using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
-
-// capabilities from BluetoothAudioSinkClientInterface::GetAudioCapabilities()
-std::vector<AudioCapabilities> audio_hal_capabilities(0);
-// capabilities that audio HAL supports and frameworks / Bluetooth SoC / runtime
-// preference would like to use.
-std::vector<AudioCapabilities> offloading_preference(0);
-
-bool sbc_offloading_capability_match(const SbcParameters& sbc_capability,
- const SbcParameters& sbc_config) {
- if ((static_cast<SampleRate>(sbc_capability.sampleRate &
- sbc_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<SbcChannelMode>(sbc_capability.channelMode &
- sbc_config.channelMode) ==
- SbcChannelMode::UNKNOWN) ||
- (static_cast<SbcBlockLength>(sbc_capability.blockLength &
- sbc_config.blockLength) ==
- static_cast<SbcBlockLength>(0)) ||
- (static_cast<SbcNumSubbands>(sbc_capability.numSubbands &
- sbc_config.numSubbands) ==
- static_cast<SbcNumSubbands>(0)) ||
- (static_cast<SbcAllocMethod>(sbc_capability.allocMethod &
- sbc_config.allocMethod) ==
- static_cast<SbcAllocMethod>(0)) ||
- (static_cast<BitsPerSample>(sbc_capability.bitsPerSample &
- sbc_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN) ||
- (sbc_config.minBitpool < sbc_capability.minBitpool ||
- sbc_config.maxBitpool < sbc_config.minBitpool ||
- sbc_capability.maxBitpool < sbc_config.maxBitpool)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(sbc_config)
- << " capability=" << toString(sbc_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(sbc_config)
- << " capability=" << toString(sbc_capability);
- return true;
-}
-
-bool aac_offloading_capability_match(const AacParameters& aac_capability,
- const AacParameters& aac_config) {
- if ((static_cast<AacObjectType>(aac_capability.objectType &
- aac_config.objectType) ==
- static_cast<AacObjectType>(0)) ||
- (static_cast<SampleRate>(aac_capability.sampleRate &
- aac_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<ChannelMode>(aac_capability.channelMode &
- aac_config.channelMode) ==
- ChannelMode::UNKNOWN) ||
- (aac_capability.variableBitRateEnabled != AacVariableBitRate::ENABLED &&
- aac_config.variableBitRateEnabled != AacVariableBitRate::DISABLED) ||
- (static_cast<BitsPerSample>(aac_capability.bitsPerSample &
- aac_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(aac_config)
- << " capability=" << toString(aac_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(aac_config)
- << " capability=" << toString(aac_capability);
- return true;
-}
-
-bool aptx_offloading_capability_match(const AptxParameters& aptx_capability,
- const AptxParameters& aptx_config) {
- if ((static_cast<SampleRate>(aptx_capability.sampleRate &
- aptx_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<ChannelMode>(aptx_capability.channelMode &
- aptx_config.channelMode) ==
- ChannelMode::UNKNOWN) ||
- (static_cast<BitsPerSample>(aptx_capability.bitsPerSample &
- aptx_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(aptx_config)
- << " capability=" << toString(aptx_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(aptx_config)
- << " capability=" << toString(aptx_capability);
- return true;
-}
-
-bool ldac_offloading_capability_match(const LdacParameters& ldac_capability,
- const LdacParameters& ldac_config) {
- if ((static_cast<SampleRate>(ldac_capability.sampleRate &
- ldac_config.sampleRate) ==
- SampleRate::RATE_UNKNOWN) ||
- (static_cast<LdacChannelMode>(ldac_capability.channelMode &
- ldac_config.channelMode) ==
- LdacChannelMode::UNKNOWN) ||
- (static_cast<BitsPerSample>(ldac_capability.bitsPerSample &
- ldac_config.bitsPerSample) ==
- BitsPerSample::BITS_UNKNOWN)) {
- LOG(WARNING) << __func__ << ": software codec=" << toString(ldac_config)
- << " capability=" << toString(ldac_capability);
- return false;
- }
- VLOG(1) << __func__ << ": offloading codec=" << toString(ldac_config)
- << " capability=" << toString(ldac_capability);
- return true;
-}
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace codec {
-
-const CodecConfiguration kInvalidCodecConfiguration = {
- .codecType = CodecType::UNKNOWN,
- .encodedAudioBitrate = 0x00000000,
- .peerMtu = 0xffff,
- .isScmstEnabled = false,
- .config = {}};
-
-SampleRate A2dpCodecToHalSampleRate(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- return SampleRate::RATE_44100;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- return SampleRate::RATE_48000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- return SampleRate::RATE_88200;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- return SampleRate::RATE_96000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- return SampleRate::RATE_176400;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- return SampleRate::RATE_192000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- return SampleRate::RATE_16000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- return SampleRate::RATE_24000;
- default:
- return SampleRate::RATE_UNKNOWN;
- }
-}
-
-BitsPerSample A2dpCodecToHalBitsPerSample(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- return BitsPerSample::BITS_16;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- return BitsPerSample::BITS_24;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- return BitsPerSample::BITS_32;
- default:
- return BitsPerSample::BITS_UNKNOWN;
- }
-}
-
-ChannelMode A2dpCodecToHalChannelMode(
- const btav_a2dp_codec_config_t& a2dp_codec_config) {
- switch (a2dp_codec_config.channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- return ChannelMode::MONO;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- return ChannelMode::STEREO;
- default:
- return ChannelMode::UNKNOWN;
- }
-}
-
-bool A2dpSbcToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
- current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_SBC) {
- *codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- codec_config->codecType = CodecType::SBC;
- codec_config->config.sbcConfig({});
- auto sbc_config = codec_config->config.sbcConfig();
- sbc_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (sbc_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown SBC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
- switch (channel_mode) {
- case A2DP_SBC_IE_CH_MD_JOINT:
- sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
- break;
- case A2DP_SBC_IE_CH_MD_STEREO:
- sbc_config.channelMode = SbcChannelMode::STEREO;
- break;
- case A2DP_SBC_IE_CH_MD_DUAL:
- sbc_config.channelMode = SbcChannelMode::DUAL;
- break;
- case A2DP_SBC_IE_CH_MD_MONO:
- sbc_config.channelMode = SbcChannelMode::MONO;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC channel_mode=" << channel_mode;
- sbc_config.channelMode = SbcChannelMode::UNKNOWN;
- return false;
- }
- uint8_t block_length = a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
- switch (block_length) {
- case A2DP_SBC_IE_BLOCKS_4:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_4;
- break;
- case A2DP_SBC_IE_BLOCKS_8:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_8;
- break;
- case A2DP_SBC_IE_BLOCKS_12:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_12;
- break;
- case A2DP_SBC_IE_BLOCKS_16:
- sbc_config.blockLength = SbcBlockLength::BLOCKS_16;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC block_length=" << block_length;
- return false;
- }
- uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
- switch (sub_bands) {
- case A2DP_SBC_IE_SUBBAND_4:
- sbc_config.numSubbands = SbcNumSubbands::SUBBAND_4;
- break;
- case A2DP_SBC_IE_SUBBAND_8:
- sbc_config.numSubbands = SbcNumSubbands::SUBBAND_8;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC Subbands=" << sub_bands;
- return false;
- }
- uint8_t alloc_method = a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
- switch (alloc_method) {
- case A2DP_SBC_IE_ALLOC_MD_S:
- sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
- break;
- case A2DP_SBC_IE_ALLOC_MD_L:
- sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown SBC alloc_method=" << alloc_method;
- return false;
- }
- sbc_config.minBitpool = a2dp_offload.codec_info[1];
- sbc_config.maxBitpool = a2dp_offload.codec_info[2];
- sbc_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (sbc_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown SBC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.sbcConfig(sbc_config);
- return true;
-}
-
-bool A2dpAacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_AAC &&
- current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_AAC) {
- *codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- codec_config->codecType = CodecType::AAC;
- codec_config->config.aacConfig({});
- auto aac_config = codec_config->config.aacConfig();
- uint8_t object_type = a2dp_offload.codec_info[0];
- switch (object_type) {
- case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
- aac_config.objectType = AacObjectType::MPEG2_LC;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
- aac_config.objectType = AacObjectType::MPEG4_LC;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
- aac_config.objectType = AacObjectType::MPEG4_LTP;
- break;
- case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
- aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown AAC object_type=" << +object_type;
- return false;
- }
- aac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (aac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown AAC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- aac_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
- if (aac_config.channelMode == ChannelMode::UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown AAC channel_mode=" << current_codec.channel_mode;
- return false;
- }
- uint8_t vbr_enabled =
- a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
- switch (vbr_enabled) {
- case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
- aac_config.variableBitRateEnabled = AacVariableBitRate::ENABLED;
- break;
- case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
- aac_config.variableBitRateEnabled = AacVariableBitRate::DISABLED;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown AAC VBR=" << +vbr_enabled;
- return false;
- }
- aac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (aac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown AAC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.aacConfig(aac_config);
- return true;
-}
-
-bool A2dpAptxToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX &&
- current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD) {
- *codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
- codec_config->codecType = CodecType::APTX;
- } else {
- codec_config->codecType = CodecType::APTX_HD;
- }
- codec_config->config.aptxConfig({});
- auto aptx_config = codec_config->config.aptxConfig();
- aptx_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (aptx_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown aptX sample_rate=" << current_codec.sample_rate;
- return false;
- }
- aptx_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
- if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown aptX channel_mode=" << current_codec.channel_mode;
- return false;
- }
- aptx_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (aptx_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown aptX bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.aptxConfig(aptx_config);
- return true;
-}
-
-bool A2dpLdacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config) {
- btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
- if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC) {
- codec_config = {};
- return false;
- }
- tBT_A2DP_OFFLOAD a2dp_offload;
- a2dp_config->getCodecSpecificConfig(&a2dp_offload);
- codec_config->codecType = CodecType::LDAC;
- codec_config->config.ldacConfig({});
- auto ldac_config = codec_config->config.ldacConfig();
- ldac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
- if (ldac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
- LOG(ERROR) << __func__
- << ": Unknown LDAC sample_rate=" << current_codec.sample_rate;
- return false;
- }
- switch (a2dp_offload.codec_info[7]) {
- case A2DP_LDAC_CHANNEL_MODE_STEREO:
- ldac_config.channelMode = LdacChannelMode::STEREO;
- break;
- case A2DP_LDAC_CHANNEL_MODE_DUAL:
- ldac_config.channelMode = LdacChannelMode::DUAL;
- break;
- case A2DP_LDAC_CHANNEL_MODE_MONO:
- ldac_config.channelMode = LdacChannelMode::MONO;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown LDAC channel_mode="
- << a2dp_offload.codec_info[7];
- ldac_config.channelMode = LdacChannelMode::UNKNOWN;
- return false;
- }
- switch (a2dp_offload.codec_info[6]) {
- case A2DP_LDAC_QUALITY_HIGH:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_HIGH;
- break;
- case A2DP_LDAC_QUALITY_MID:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_MID;
- break;
- case A2DP_LDAC_QUALITY_LOW:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_LOW;
- break;
- case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
- ldac_config.qualityIndex = LdacQualityIndex::QUALITY_ABR;
- break;
- default:
- LOG(ERROR) << __func__ << ": Unknown LDAC QualityIndex="
- << a2dp_offload.codec_info[6];
- return false;
- }
- ldac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
- if (ldac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
- LOG(ERROR) << __func__ << ": Unknown LDAC bits_per_sample="
- << current_codec.bits_per_sample;
- return false;
- }
- codec_config->config.ldacConfig(ldac_config);
- return true;
-}
-
-bool UpdateOffloadingCapabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
- audio_hal_capabilities =
- BluetoothAudioSinkClientInterface::GetAudioCapabilities(
- SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
- uint32_t codec_type_masks = static_cast<uint32_t>(CodecType::UNKNOWN);
- for (auto preference : framework_preference) {
- switch (preference.codec_type) {
- case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
- codec_type_masks |= CodecType::SBC;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
- codec_type_masks |= CodecType::AAC;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
- codec_type_masks |= CodecType::APTX;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
- codec_type_masks |= CodecType::APTX_HD;
- break;
- case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
- codec_type_masks |= CodecType::LDAC;
- break;
- case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
- [[fallthrough]];
- case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
- LOG(WARNING) << __func__
- << ": Ignore sink codec_type=" << preference.codec_type;
- break;
- case BTAV_A2DP_CODEC_INDEX_MAX:
- [[fallthrough]];
- default:
- LOG(ERROR) << __func__
- << ": Unknown codec_type=" << preference.codec_type;
- return false;
- }
- }
- offloading_preference.clear();
- for (auto capability : audio_hal_capabilities) {
- if (static_cast<CodecType>(capability.codecCapabilities().codecType &
- codec_type_masks) != CodecType::UNKNOWN) {
- LOG(INFO) << __func__
- << ": enabled offloading capability=" << toString(capability);
- offloading_preference.push_back(capability);
- } else {
- LOG(INFO) << __func__
- << ": disabled offloading capability=" << toString(capability);
- }
- }
- // TODO: Bluetooth SoC and runtime property
- return true;
-}
-
-// Check whether this codec is supported by the audio HAL and is allowed to use
-// by prefernece of framework / Bluetooth SoC / runtime property.
-bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config) {
- for (auto preference : offloading_preference) {
- if (codec_config.codecType != preference.codecCapabilities().codecType)
- continue;
- auto codec_capability = preference.codecCapabilities();
- switch (codec_capability.codecType) {
- case CodecType::SBC: {
- auto sbc_capability = codec_capability.capabilities.sbcCapabilities();
- auto sbc_config = codec_config.config.sbcConfig();
- return sbc_offloading_capability_match(sbc_capability, sbc_config);
- }
- case CodecType::AAC: {
- auto aac_capability = codec_capability.capabilities.aacCapabilities();
- auto aac_config = codec_config.config.aacConfig();
- return aac_offloading_capability_match(aac_capability, aac_config);
- }
- case CodecType::APTX:
- [[fallthrough]];
- case CodecType::APTX_HD: {
- auto aptx_capability = codec_capability.capabilities.aptxCapabilities();
- auto aptx_config = codec_config.config.aptxConfig();
- return aptx_offloading_capability_match(aptx_capability, aptx_config);
- }
- case CodecType::LDAC: {
- auto ldac_capability = codec_capability.capabilities.ldacCapabilities();
- auto ldac_config = codec_config.config.ldacConfig();
- return ldac_offloading_capability_match(ldac_capability, ldac_config);
- }
- case CodecType::UNKNOWN:
- [[fallthrough]];
- default:
- LOG(ERROR) << __func__ << ": Unknown codecType="
- << toString(codec_capability.codecType);
- return false;
- }
- }
- LOG(INFO) << __func__ << ": software codec=" << toString(codec_config);
- return false;
-}
-
-} // namespace codec
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/codec_status.h b/audio_hal_interface/codec_status.h
deleted file mode 100644
index 7f2591b..0000000
--- a/audio_hal_interface/codec_status.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2019 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.1/types.h>
-
-#include <vector>
-
-#include "a2dp_codec_api.h"
-
-namespace bluetooth {
-namespace audio {
-namespace codec {
-
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
-using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
-
-extern const CodecConfiguration kInvalidCodecConfiguration;
-
-SampleRate A2dpCodecToHalSampleRate(
- const btav_a2dp_codec_config_t& a2dp_codec_config);
-BitsPerSample A2dpCodecToHalBitsPerSample(
- const btav_a2dp_codec_config_t& a2dp_codec_config);
-ChannelMode A2dpCodecToHalChannelMode(
- const btav_a2dp_codec_config_t& a2dp_codec_config);
-
-bool A2dpSbcToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-bool A2dpAacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-bool A2dpAptxToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-bool A2dpLdacToHalConfig(CodecConfiguration* codec_config,
- A2dpCodecConfig* a2dp_config);
-
-bool UpdateOffloadingCapabilities(
- const std::vector<btav_a2dp_codec_config_t>& framework_preference);
-// Check whether this codec is supported by the audio HAL and is allowed to use
-// by prefernece of framework / Bluetooth SoC / runtime property.
-bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config);
-
-} // namespace codec
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hal_version_manager.h b/audio_hal_interface/hal_version_manager.h
deleted file mode 100644
index 779ea3e..0000000
--- a/audio_hal_interface/hal_version_manager.h
+++ /dev/null
@@ -1,136 +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.1/IBluetoothAudioProvidersFactory.h>
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-#include <android/hidl/manager/1.2/IServiceManager.h>
-#include <base/logging.h>
-#include <hidl/ServiceManagement.h>
-
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::hidl_vec;
-
-using IBluetoothAudioProvidersFactory_2_0 = ::android::hardware::bluetooth::
- audio::V2_0::IBluetoothAudioProvidersFactory;
-using IBluetoothAudioProvidersFactory_2_1 = ::android::hardware::bluetooth::
- audio::V2_1::IBluetoothAudioProvidersFactory;
-
-constexpr char kFullyQualifiedInterfaceName_2_0[] =
- "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory";
-constexpr char kFullyQualifiedInterfaceName_2_1[] =
- "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory";
-
-enum class BluetoothAudioHalVersion : uint8_t {
- VERSION_2_0 = 0,
- VERSION_2_1,
- VERSION_UNAVAILABLE,
-};
-
-class HalVersionManager {
- public:
- static BluetoothAudioHalVersion GetHalVersion() {
- std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
- return instance_ptr->hal_version_;
- }
-
- static android::sp<IBluetoothAudioProvidersFactory_2_1>
- GetProvidersFactory_2_1() {
- std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
- if (instance_ptr->hal_version_ != BluetoothAudioHalVersion::VERSION_2_1) {
- return nullptr;
- }
- android::sp<IBluetoothAudioProvidersFactory_2_1> providers_factory =
- IBluetoothAudioProvidersFactory_2_1::getService();
- CHECK(providers_factory)
- << "V2_1::IBluetoothAudioProvidersFactory::getService() failed";
-
- LOG(INFO) << "V2_1::IBluetoothAudioProvidersFactory::getService() returned "
- << providers_factory.get()
- << (providers_factory->isRemote() ? " (remote)" : " (local)");
- return providers_factory;
- }
-
- static android::sp<IBluetoothAudioProvidersFactory_2_0>
- GetProvidersFactory_2_0() {
- std::unique_lock<std::mutex> guard(instance_ptr->mutex_);
- if (instance_ptr->hal_version_ == BluetoothAudioHalVersion::VERSION_2_1) {
- guard.unlock();
- return instance_ptr->GetProvidersFactory_2_1();
- }
- android::sp<IBluetoothAudioProvidersFactory_2_0> providers_factory =
- IBluetoothAudioProvidersFactory_2_0::getService();
- CHECK(providers_factory)
- << "V2_0::IBluetoothAudioProvidersFactory::getService() failed";
-
- LOG(INFO) << "V2_0::IBluetoothAudioProvidersFactory::getService() returned "
- << providers_factory.get()
- << (providers_factory->isRemote() ? " (remote)" : " (local)");
- guard.unlock();
- return providers_factory;
- }
-
- HalVersionManager() {
- auto service_manager = android::hardware::defaultServiceManager1_2();
- CHECK(service_manager != nullptr);
- size_t instance_count = 0;
- auto listManifestByInterface_cb =
- [&instance_count](
- const hidl_vec<android::hardware::hidl_string>& instanceNames) {
- instance_count = instanceNames.size();
- };
- auto hidl_retval = service_manager->listManifestByInterface(
- kFullyQualifiedInterfaceName_2_1, listManifestByInterface_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: "
- << hidl_retval.description();
- return;
- }
-
- if (instance_count > 0) {
- hal_version_ = BluetoothAudioHalVersion::VERSION_2_1;
- return;
- }
-
- hidl_retval = service_manager->listManifestByInterface(
- kFullyQualifiedInterfaceName_2_0, listManifestByInterface_cb);
- if (!hidl_retval.isOk()) {
- LOG(FATAL) << __func__ << ": IServiceManager::listByInterface failure: "
- << hidl_retval.description();
- return;
- }
-
- if (instance_count > 0) {
- hal_version_ = BluetoothAudioHalVersion::VERSION_2_0;
- return;
- }
-
- hal_version_ = BluetoothAudioHalVersion::VERSION_UNAVAILABLE;
- LOG(ERROR) << __func__ << " No supported HAL version";
- }
-
- private:
- static std::unique_ptr<HalVersionManager> instance_ptr;
- std::mutex mutex_;
-
- BluetoothAudioHalVersion hal_version_;
-};
-
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hearing_aid_software_encoding.cc b/audio_hal_interface/hearing_aid_software_encoding.cc
deleted file mode 100644
index 2482502..0000000
--- a/audio_hal_interface/hearing_aid_software_encoding.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright 2019 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 "BTAudioClientHearingAid"
-
-#include "hearing_aid_software_encoding.h"
-#include "client_interface.h"
-
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::bluetooth::audio::AudioConfiguration;
-using ::bluetooth::audio::BitsPerSample;
-using ::bluetooth::audio::BluetoothAudioCtrlAck;
-using ::bluetooth::audio::ChannelMode;
-using ::bluetooth::audio::PcmParameters;
-using ::bluetooth::audio::SampleRate;
-using ::bluetooth::audio::SessionType;
-using ::bluetooth::audio::SessionType_2_1;
-using ::bluetooth::audio::hearing_aid::StreamCallbacks;
-
-// Transport implementation for Hearing Aids
-class HearingAidTransport
- : public bluetooth::audio::IBluetoothSinkTransportInstance {
- public:
- HearingAidTransport(StreamCallbacks stream_cb)
- : IBluetoothSinkTransportInstance(
- SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH, {}),
- stream_cb_(std::move(stream_cb)),
- remote_delay_report_ms_(0),
- total_bytes_read_(0),
- data_position_({}){};
-
- BluetoothAudioCtrlAck StartRequest() override {
- LOG(INFO) << __func__;
- if (stream_cb_.on_resume_(true)) {
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- }
- return BluetoothAudioCtrlAck::FAILURE;
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
- ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf));
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- } else {
- return BluetoothAudioCtrlAck::FAILURE;
- }
- }
-
- void StopRequest() override {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- // flush
- uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
- ::bluetooth::audio::hearing_aid::read(p_buf, sizeof(p_buf));
- }
- }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_read,
- timespec* data_position) override {
- VLOG(2) << __func__ << ": data=" << total_bytes_read_
- << " byte(s), timestamp=" << data_position_.tv_sec << "."
- << data_position_.tv_nsec
- << "s, delay report=" << remote_delay_report_ms_ << " msec.";
- if (remote_delay_report_ns != nullptr) {
- *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
- }
- if (total_bytes_read != nullptr) *total_bytes_read = total_bytes_read_;
- if (data_position != nullptr) *data_position = data_position_;
-
- return true;
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- auto track_count = source_metadata.track_count;
- auto tracks = source_metadata.tracks;
- LOG(INFO) << __func__ << ": " << track_count << " track(s) received";
- while (track_count) {
- VLOG(1) << __func__ << ": usage=" << tracks->usage
- << ", content_type=" << tracks->content_type
- << ", gain=" << tracks->gain;
- --track_count;
- ++tracks;
- }
- }
-
- void ResetPresentationPosition() override {
- VLOG(2) << __func__ << ": called.";
- remote_delay_report_ms_ = 0;
- total_bytes_read_ = 0;
- data_position_ = {};
- }
-
- void LogBytesRead(size_t bytes_read) override {
- if (bytes_read) {
- total_bytes_read_ += bytes_read;
- clock_gettime(CLOCK_MONOTONIC, &data_position_);
- }
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report=" << delay_report_ms << " msec";
- remote_delay_report_ms_ = delay_report_ms;
- }
-
- private:
- StreamCallbacks stream_cb_;
- uint16_t remote_delay_report_ms_;
- uint64_t total_bytes_read_;
- timespec data_position_;
-};
-
-bool HearingAidGetSelectedHalPcmConfig(PcmParameters* hal_pcm_config) {
- if (hal_pcm_config == nullptr) return false;
- // TODO: we only support one config for now!
- hal_pcm_config->sampleRate = SampleRate::RATE_16000;
- hal_pcm_config->bitsPerSample = BitsPerSample::BITS_16;
- hal_pcm_config->channelMode = ChannelMode::STEREO;
- return true;
-}
-
-// Sink instance of Hearing Aids to provide call-in APIs for Bluetooth Audio Hal
-HearingAidTransport* hearing_aid_sink = nullptr;
-// Common interface to call-out into Bluetooth Audio Hal
-bluetooth::audio::BluetoothAudioSinkClientInterface*
- hearing_aid_hal_clientinterface = nullptr;
-bool btaudio_hearing_aid_disabled = false;
-bool is_configured = false;
-
-// Save the value if the remote reports its delay before hearing_aid_sink is
-// initialized
-uint16_t remote_delay_ms = 0;
-
-bool is_hal_2_0_force_disabled() {
- if (!is_configured) {
- btaudio_hearing_aid_disabled = osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
- is_configured = true;
- }
- return btaudio_hearing_aid_disabled;
-}
-
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace hearing_aid {
-
-bool is_hal_2_0_enabled() { return hearing_aid_hal_clientinterface != nullptr; }
-
-bool init(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- LOG(INFO) << __func__;
-
- if (is_hal_2_0_force_disabled()) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
- return false;
- }
-
- hearing_aid_sink = new HearingAidTransport(std::move(stream_cb));
- hearing_aid_hal_clientinterface =
- new bluetooth::audio::BluetoothAudioSinkClientInterface(hearing_aid_sink,
- message_loop);
- if (!hearing_aid_hal_clientinterface->IsValid()) {
- LOG(WARNING) << __func__ << ": BluetoothAudio HAL for Hearing Aid is invalid?!";
- delete hearing_aid_hal_clientinterface;
- hearing_aid_hal_clientinterface = nullptr;
- delete hearing_aid_sink;
- hearing_aid_sink = nullptr;
- return false;
- }
-
- if (remote_delay_ms != 0) {
- LOG(INFO) << __func__ << ": restore DELAY " << remote_delay_ms << " ms";
- hearing_aid_sink->SetRemoteDelay(remote_delay_ms);
- remote_delay_ms = 0;
- }
-
- return true;
-}
-
-void cleanup() {
- LOG(INFO) << __func__;
- if (!is_hal_2_0_enabled()) return;
- end_session();
- delete hearing_aid_hal_clientinterface;
- hearing_aid_hal_clientinterface = nullptr;
- delete hearing_aid_sink;
- hearing_aid_sink = nullptr;
- remote_delay_ms = 0;
-}
-
-void start_session() {
- LOG(INFO) << __func__;
- if (!is_hal_2_0_enabled()) return;
- AudioConfiguration audio_config;
- PcmParameters pcm_config{};
- if (!HearingAidGetSelectedHalPcmConfig(&pcm_config)) {
- LOG(ERROR) << __func__ << ": cannot get PCM config";
- return;
- }
- audio_config.pcmConfig(pcm_config);
- if (!hearing_aid_hal_clientinterface->UpdateAudioConfig(audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- hearing_aid_hal_clientinterface->StartSession();
-}
-
-void end_session() {
- LOG(INFO) << __func__;
- if (!is_hal_2_0_enabled()) return;
- hearing_aid_hal_clientinterface->EndSession();
-}
-
-size_t read(uint8_t* p_buf, uint32_t len) {
- if (!is_hal_2_0_enabled()) return 0;
- return hearing_aid_hal_clientinterface->ReadAudioData(p_buf, len);
-}
-
-// Update Hearing Aids delay report to BluetoothAudio HAL
-void set_remote_delay(uint16_t delay_report_ms) {
- if (!is_hal_2_0_enabled()) {
- LOG(INFO) << __func__ << ": not ready for DelayReport " << delay_report_ms
- << " ms";
- remote_delay_ms = delay_report_ms;
- return;
- }
- LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
- hearing_aid_sink->SetRemoteDelay(delay_report_ms);
-}
-
-} // namespace hearing_aid
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hearing_aid_software_encoding.h b/audio_hal_interface/hearing_aid_software_encoding.h
deleted file mode 100644
index 8a64fcd..0000000
--- a/audio_hal_interface/hearing_aid_software_encoding.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2019 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 <functional>
-#include "common/message_loop_thread.h"
-
-namespace bluetooth {
-namespace audio {
-namespace hearing_aid {
-
-struct StreamCallbacks {
- std::function<bool(bool start_media_task)> on_resume_;
- std::function<bool(void)> on_suspend_;
-};
-
-// Check if new bluetooth_audio is enabled
-bool is_hal_2_0_enabled();
-
-// Initialize BluetoothAudio HAL: openProvider
-bool init(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop);
-
-// Clean up BluetoothAudio HAL
-void cleanup();
-
-// Send command to the BluetoothAudio HAL: StartSession, EndSession
-void start_session();
-void end_session();
-
-void set_remote_delay(uint16_t delay_report_ms);
-
-// Read from the FMQ of BluetoothAudio HAL
-size_t read(uint8_t* p_buf, uint32_t len);
-
-} // namespace hearing_aid
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/hearing_aid_software_encoding_host.cc b/audio_hal_interface/hearing_aid_software_encoding_host.cc
deleted file mode 100644
index 37d5bb2..0000000
--- a/audio_hal_interface/hearing_aid_software_encoding_host.cc
+++ /dev/null
@@ -1,42 +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.
- */
-
-#include "audio_hal_interface/hearing_aid_software_encoding.h"
-
-namespace bluetooth {
-namespace audio {
-namespace hearing_aid {
-
-bool is_hal_2_0_enabled() { return false; }
-
-bool init(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- return false;
-}
-
-void cleanup() {}
-
-void start_session() {}
-
-void end_session() {}
-
-size_t read(uint8_t* p_buf, uint32_t len) { return 0; }
-
-void set_remote_delay(uint16_t delay_report_ms) {}
-
-} // namespace hearing_aid
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/le_audio_software.cc b/audio_hal_interface/le_audio_software.cc
deleted file mode 100644
index 39e3a52..0000000
--- a/audio_hal_interface/le_audio_software.cc
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
- * www.ehima.com
- *
- * 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 "BTAudioClientLeAudio"
-
-#include "le_audio_software.h"
-
-#include "client_interface.h"
-#include "osi/include/log.h"
-#include "osi/include/properties.h"
-
-namespace {
-
-using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
-using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using ::bluetooth::audio::BluetoothAudioCtrlAck;
-using ::bluetooth::audio::SampleRate_2_1;
-using ::bluetooth::audio::SessionType;
-using ::bluetooth::audio::SessionType_2_1;
-using ::bluetooth::audio::le_audio::LeAudioClientInterface;
-using ::bluetooth::audio::le_audio::StreamCallbacks;
-
-bluetooth::audio::BluetoothAudioSinkClientInterface*
- le_audio_sink_hal_clientinterface = nullptr;
-bluetooth::audio::BluetoothAudioSourceClientInterface*
- le_audio_source_hal_clientinterface = nullptr;
-
-static bool is_source_hal_enabled() {
- return le_audio_source_hal_clientinterface != nullptr;
-}
-
-static bool is_sink_hal_enabled() {
- return le_audio_sink_hal_clientinterface != nullptr;
-}
-
-class LeAudioTransport {
- public:
- LeAudioTransport(void (*flush)(void), StreamCallbacks stream_cb,
- PcmParameters pcm_config)
- : flush_(std::move(flush)),
- stream_cb_(std::move(stream_cb)),
- remote_delay_report_ms_(0),
- total_bytes_processed_(0),
- data_position_({}),
- pcm_config_(std::move(pcm_config)),
- is_pending_start_request_(false){};
-
- BluetoothAudioCtrlAck StartRequest() {
- LOG(INFO) << __func__;
-
- /*
- * Set successful state as initial, it may be overwritten with cancelation
- * during on_resume handling
- */
- pending_start_request_state_ = BluetoothAudioCtrlAck::PENDING;
-
- if (stream_cb_.on_resume_(true)) {
- if (pending_start_request_state_ == BluetoothAudioCtrlAck::PENDING)
- is_pending_start_request_ = true;
-
- return pending_start_request_state_;
- }
-
- return BluetoothAudioCtrlAck::FAILURE;
- }
-
- BluetoothAudioCtrlAck SuspendRequest() {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- flush_();
- return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
- } else {
- return BluetoothAudioCtrlAck::FAILURE;
- }
- }
-
- void StopRequest() {
- LOG(INFO) << __func__;
- if (stream_cb_.on_suspend_()) {
- flush_();
- }
- }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_processed,
- timespec* data_position) {
- VLOG(2) << __func__ << ": data=" << total_bytes_processed_
- << " byte(s), timestamp=" << data_position_.tv_sec << "."
- << data_position_.tv_nsec
- << "s, delay report=" << remote_delay_report_ms_ << " msec.";
- if (remote_delay_report_ns != nullptr) {
- *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
- }
- if (total_bytes_processed != nullptr)
- *total_bytes_processed = total_bytes_processed_;
- if (data_position != nullptr) *data_position = data_position_;
-
- return true;
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) {
- auto track_count = source_metadata.track_count;
-
- if (track_count == 0) {
- LOG(WARNING) << ", invalid number of metadata changed tracks";
- return;
- }
-
- stream_cb_.on_metadata_update_(source_metadata);
- }
-
- void ResetPresentationPosition() {
- VLOG(2) << __func__ << ": called.";
- remote_delay_report_ms_ = 0;
- total_bytes_processed_ = 0;
- data_position_ = {};
- }
-
- void LogBytesProcessed(size_t bytes_processed) {
- if (bytes_processed) {
- total_bytes_processed_ += bytes_processed;
- clock_gettime(CLOCK_MONOTONIC, &data_position_);
- }
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report=" << delay_report_ms << " msec";
- remote_delay_report_ms_ = delay_report_ms;
- }
-
- const PcmParameters& LeAudioGetSelectedHalPcmConfig() { return pcm_config_; }
-
- void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
- BitsPerSample bit_rate,
- ChannelMode channel_mode,
- uint32_t data_interval) {
- pcm_config_.sampleRate = sample_rate;
- pcm_config_.bitsPerSample = bit_rate;
- pcm_config_.channelMode = channel_mode;
- pcm_config_.dataIntervalUs = data_interval;
- }
-
- bool SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck state) {
- bool ret = is_pending_start_request_;
- is_pending_start_request_ = false;
- pending_start_request_state_ = state;
-
- return ret;
- }
-
- private:
- void (*flush_)(void);
- StreamCallbacks stream_cb_;
- uint16_t remote_delay_report_ms_;
- uint64_t total_bytes_processed_;
- timespec data_position_;
- PcmParameters pcm_config_;
- bool is_pending_start_request_;
- BluetoothAudioCtrlAck pending_start_request_state_;
-};
-
-static void flush_sink() {
- if (!is_sink_hal_enabled()) return;
-
- le_audio_sink_hal_clientinterface->FlushAudioData();
-}
-
-// Sink transport implementation for Le Audio
-class LeAudioSinkTransport
- : public bluetooth::audio::IBluetoothSinkTransportInstance {
- public:
- LeAudioSinkTransport(StreamCallbacks stream_cb)
- : IBluetoothSinkTransportInstance(
- SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH, {}) {
- transport_ =
- new LeAudioTransport(flush_sink, std::move(stream_cb),
- {SampleRate_2_1::RATE_16000, ChannelMode::STEREO,
- BitsPerSample::BITS_16, 0});
- };
-
- ~LeAudioSinkTransport() { delete transport_; }
-
- BluetoothAudioCtrlAck StartRequest() override {
- return transport_->StartRequest();
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- return transport_->SuspendRequest();
- }
-
- void StopRequest() override { transport_->StopRequest(); }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_read,
- timespec* data_position) override {
- return transport_->GetPresentationPosition(remote_delay_report_ns,
- total_bytes_read, data_position);
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- transport_->MetadataChanged(source_metadata);
- }
-
- void ResetPresentationPosition() override {
- transport_->ResetPresentationPosition();
- }
-
- void LogBytesRead(size_t bytes_read) override {
- transport_->LogBytesProcessed(bytes_read);
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- transport_->SetRemoteDelay(delay_report_ms);
- }
-
- const PcmParameters& LeAudioGetSelectedHalPcmConfig() {
- return transport_->LeAudioGetSelectedHalPcmConfig();
- }
-
- void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
- BitsPerSample bit_rate,
- ChannelMode channel_mode,
- uint32_t data_interval) {
- transport_->LeAudioSetSelectedHalPcmConfig(sample_rate, bit_rate,
- channel_mode, data_interval);
- }
-
- bool SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck state = BluetoothAudioCtrlAck::PENDING) {
- return transport_->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- state);
- }
-
- private:
- LeAudioTransport* transport_;
-};
-
-static void flush_source() {
- if (le_audio_source_hal_clientinterface == nullptr) return;
-
- le_audio_source_hal_clientinterface->FlushAudioData();
-}
-
-class LeAudioSourceTransport
- : public bluetooth::audio::IBluetoothSourceTransportInstance {
- public:
- LeAudioSourceTransport(StreamCallbacks stream_cb)
- : IBluetoothSourceTransportInstance(
- SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH, {}) {
- transport_ =
- new LeAudioTransport(flush_source, std::move(stream_cb),
- {SampleRate_2_1::RATE_16000, ChannelMode::MONO,
- BitsPerSample::BITS_16, 0});
- };
-
- ~LeAudioSourceTransport() { delete transport_; }
-
- BluetoothAudioCtrlAck StartRequest() override {
- return transport_->StartRequest();
- }
-
- BluetoothAudioCtrlAck SuspendRequest() override {
- return transport_->SuspendRequest();
- }
-
- void StopRequest() override { transport_->StopRequest(); }
-
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_written,
- timespec* data_position) override {
- return transport_->GetPresentationPosition(
- remote_delay_report_ns, total_bytes_written, data_position);
- }
-
- void MetadataChanged(const source_metadata_t& source_metadata) override {
- transport_->MetadataChanged(source_metadata);
- }
-
- void ResetPresentationPosition() override {
- transport_->ResetPresentationPosition();
- }
-
- void LogBytesWritten(size_t bytes_written) override {
- transport_->LogBytesProcessed(bytes_written);
- }
-
- void SetRemoteDelay(uint16_t delay_report_ms) {
- transport_->SetRemoteDelay(delay_report_ms);
- }
-
- const PcmParameters& LeAudioGetSelectedHalPcmConfig() {
- return transport_->LeAudioGetSelectedHalPcmConfig();
- }
-
- void LeAudioSetSelectedHalPcmConfig(SampleRate_2_1 sample_rate,
- BitsPerSample bit_rate,
- ChannelMode channel_mode,
- uint32_t data_interval) {
- transport_->LeAudioSetSelectedHalPcmConfig(sample_rate, bit_rate,
- channel_mode, data_interval);
- }
-
- bool SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck state = BluetoothAudioCtrlAck::PENDING) {
- return transport_->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- state);
- }
-
- private:
- LeAudioTransport* transport_;
-};
-
-// Instance of Le Audio to provide call-in APIs for Bluetooth Audio Hal
-LeAudioSinkTransport* le_audio_sink = nullptr;
-LeAudioSourceTransport* le_audio_source = nullptr;
-} // namespace
-
-namespace bluetooth {
-namespace audio {
-namespace le_audio {
-
-LeAudioClientInterface* LeAudioClientInterface::interface = nullptr;
-LeAudioClientInterface* LeAudioClientInterface::Get() {
- if (osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false)) {
- LOG(ERROR) << __func__ << ": BluetoothAudio HAL is disabled";
- return nullptr;
- }
-
- if (LeAudioClientInterface::interface == nullptr)
- LeAudioClientInterface::interface = new LeAudioClientInterface();
-
- return LeAudioClientInterface::interface;
-}
-
-static SampleRate_2_1 le_audio_sample_rate2audio_hal(uint32_t sample_rate_2_1) {
- switch (sample_rate_2_1) {
- case 8000:
- return SampleRate_2_1::RATE_8000;
- case 16000:
- return SampleRate_2_1::RATE_16000;
- case 24000:
- return SampleRate_2_1::RATE_24000;
- case 32000:
- return SampleRate_2_1::RATE_32000;
- case 44100:
- return SampleRate_2_1::RATE_44100;
- case 48000:
- return SampleRate_2_1::RATE_48000;
- case 88200:
- return SampleRate_2_1::RATE_88200;
- case 96000:
- return SampleRate_2_1::RATE_96000;
- case 176400:
- return SampleRate_2_1::RATE_176400;
- case 192000:
- return SampleRate_2_1::RATE_192000;
- };
- return SampleRate_2_1::RATE_UNKNOWN;
-}
-
-static BitsPerSample le_audio_bit_rate2audio_hal(uint8_t bits_per_sample) {
- switch (bits_per_sample) {
- case 16:
- return BitsPerSample::BITS_16;
- case 24:
- return BitsPerSample::BITS_24;
- case 32:
- return BitsPerSample::BITS_32;
- };
- return BitsPerSample::BITS_UNKNOWN;
-}
-
-static ChannelMode le_audio_channel_mode2audio_hal(uint8_t channels_count) {
- switch (channels_count) {
- case 1:
- return ChannelMode::MONO;
- case 2:
- return ChannelMode::STEREO;
- }
- return ChannelMode::UNKNOWN;
-}
-
-void LeAudioClientInterface::Sink::Cleanup() {
- LOG(INFO) << __func__ << " sink";
- StopSession();
- delete le_audio_sink_hal_clientinterface;
- le_audio_sink_hal_clientinterface = nullptr;
- delete le_audio_sink;
- le_audio_sink = nullptr;
-}
-
-void LeAudioClientInterface::Sink::SetPcmParameters(
- const PcmParameters& params) {
- le_audio_sink->LeAudioSetSelectedHalPcmConfig(
- le_audio_sample_rate2audio_hal(params.sample_rate),
- le_audio_bit_rate2audio_hal(params.bits_per_sample),
- le_audio_channel_mode2audio_hal(params.channels_count),
- params.data_interval_us);
-}
-
-// Update Le Audio delay report to BluetoothAudio HAL
-void LeAudioClientInterface::Sink::SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
- le_audio_sink->SetRemoteDelay(delay_report_ms);
-}
-
-void LeAudioClientInterface::Sink::StartSession() {
- LOG(INFO) << __func__;
- AudioConfiguration_2_1 audio_config;
- audio_config.pcmConfig(le_audio_sink->LeAudioGetSelectedHalPcmConfig());
- if (!le_audio_sink_hal_clientinterface->UpdateAudioConfig_2_1(audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- le_audio_sink_hal_clientinterface->StartSession_2_1();
-}
-
-void LeAudioClientInterface::Sink::ConfirmStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_sink->SetAudioCtrlAckStateAndResetPendingStartStreamFlag()) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_sink_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::SUCCESS_FINISHED);
-}
-
-void LeAudioClientInterface::Sink::CancelStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_sink->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck::FAILURE)) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_sink_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::FAILURE);
-}
-
-void LeAudioClientInterface::Sink::StopSession() {
- LOG(INFO) << __func__ << " sink";
- le_audio_sink->SetAudioCtrlAckStateAndResetPendingStartStreamFlag();
- le_audio_sink_hal_clientinterface->EndSession();
-}
-
-size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
- return le_audio_sink_hal_clientinterface->ReadAudioData(p_buf, len);
-}
-
-void LeAudioClientInterface::Source::Cleanup() {
- LOG(INFO) << __func__ << " source";
- StopSession();
- delete le_audio_source_hal_clientinterface;
- le_audio_source_hal_clientinterface = nullptr;
- delete le_audio_source;
- le_audio_source = nullptr;
-}
-
-void LeAudioClientInterface::Source::SetPcmParameters(
- const PcmParameters& params) {
- le_audio_source->LeAudioSetSelectedHalPcmConfig(
- le_audio_sample_rate2audio_hal(params.sample_rate),
- le_audio_bit_rate2audio_hal(params.bits_per_sample),
- le_audio_channel_mode2audio_hal(params.channels_count),
- params.data_interval_us);
-}
-
-void LeAudioClientInterface::Source::SetRemoteDelay(uint16_t delay_report_ms) {
- LOG(INFO) << __func__ << ": delay_report_ms=" << delay_report_ms << " ms";
- le_audio_source->SetRemoteDelay(delay_report_ms);
-}
-
-void LeAudioClientInterface::Source::StartSession() {
- LOG(INFO) << __func__;
- if (!is_source_hal_enabled()) return;
- AudioConfiguration_2_1 audio_config;
- audio_config.pcmConfig(le_audio_source->LeAudioGetSelectedHalPcmConfig());
- if (!le_audio_source_hal_clientinterface->UpdateAudioConfig_2_1(
- audio_config)) {
- LOG(ERROR) << __func__ << ": cannot update audio config to HAL";
- return;
- }
- le_audio_source_hal_clientinterface->StartSession_2_1();
-}
-
-void LeAudioClientInterface::Source::ConfirmStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_source->SetAudioCtrlAckStateAndResetPendingStartStreamFlag()) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_source_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::SUCCESS_FINISHED);
-}
-
-void LeAudioClientInterface::Source::CancelStreamingRequest() {
- LOG(INFO) << __func__;
- if (!le_audio_source->SetAudioCtrlAckStateAndResetPendingStartStreamFlag(
- BluetoothAudioCtrlAck::FAILURE)) {
- LOG(WARNING) << ", no pending start stream request";
- return;
- }
-
- le_audio_source_hal_clientinterface->StreamStarted(
- BluetoothAudioCtrlAck::FAILURE);
-}
-
-void LeAudioClientInterface::Source::StopSession() {
- LOG(INFO) << __func__ << " source";
- le_audio_source->SetAudioCtrlAckStateAndResetPendingStartStreamFlag();
- le_audio_source_hal_clientinterface->EndSession();
-}
-
-size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf,
- uint32_t len) {
- return le_audio_source_hal_clientinterface->WriteAudioData(p_buf, len);
-}
-
-LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- if (sink_ == nullptr) {
- sink_ = new Sink();
- } else {
- LOG(WARNING) << __func__ << ", Sink is already acquired";
- return nullptr;
- }
-
- LOG(INFO) << __func__;
-
- le_audio_sink = new LeAudioSinkTransport(std::move(stream_cb));
- le_audio_sink_hal_clientinterface =
- new bluetooth::audio::BluetoothAudioSinkClientInterface(le_audio_sink,
- message_loop);
- if (!le_audio_sink_hal_clientinterface->IsValid()) {
- LOG(WARNING) << __func__
- << ": BluetoothAudio HAL for Le Audio is invalid?!";
- delete le_audio_sink_hal_clientinterface;
- le_audio_sink_hal_clientinterface = nullptr;
- delete le_audio_sink;
- le_audio_sink = nullptr;
- delete sink_;
- sink_ = nullptr;
-
- return nullptr;
- }
-
- return sink_;
-}
-
-bool LeAudioClientInterface::IsSinkAcquired() { return sink_ != nullptr; }
-
-bool LeAudioClientInterface::ReleaseSink(LeAudioClientInterface::Sink* sink) {
- if (sink != sink_) {
- LOG(WARNING) << __func__ << ", can't release not acquired sink";
- return false;
- }
-
- if (le_audio_sink_hal_clientinterface && le_audio_sink) sink->Cleanup();
-
- delete (sink_);
- sink_ = nullptr;
-
- return true;
-}
-
-LeAudioClientInterface::Source* LeAudioClientInterface::GetSource(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- if (source_ == nullptr) {
- source_ = new Source();
- } else {
- LOG(WARNING) << __func__ << ", Source is already acquired";
- return nullptr;
- }
-
- LOG(INFO) << __func__;
-
- le_audio_source = new LeAudioSourceTransport(std::move(stream_cb));
- le_audio_source_hal_clientinterface =
- new bluetooth::audio::BluetoothAudioSourceClientInterface(le_audio_source,
- message_loop);
- if (!le_audio_source_hal_clientinterface->IsValid()) {
- LOG(WARNING) << __func__
- << ": BluetoothAudio HAL for Le Audio is invalid?!";
- delete le_audio_source_hal_clientinterface;
- le_audio_source_hal_clientinterface = nullptr;
- delete le_audio_source;
- le_audio_source = nullptr;
- delete source_;
- source_ = nullptr;
-
- return nullptr;
- }
-
- return source_;
-}
-
-bool LeAudioClientInterface::IsSourceAcquired() { return source_ != nullptr; }
-
-bool LeAudioClientInterface::ReleaseSource(
- LeAudioClientInterface::Source* source) {
- if (source != source_) {
- LOG(WARNING) << __func__ << ", can't release not acquired source";
- return false;
- }
-
- if (le_audio_source_hal_clientinterface && le_audio_source) source->Cleanup();
-
- delete (source_);
- source_ = nullptr;
-
- return true;
-}
-
-} // namespace le_audio
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/le_audio_software.h b/audio_hal_interface/le_audio_software.h
deleted file mode 100644
index d595e6d..0000000
--- a/audio_hal_interface/le_audio_software.h
+++ /dev/null
@@ -1,132 +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 <hardware/audio.h>
-
-#include <functional>
-
-#include "common/message_loop_thread.h"
-
-namespace bluetooth {
-namespace audio {
-namespace le_audio {
-
-constexpr uint8_t kChannelNumberMono = 1;
-constexpr uint8_t kChannelNumberStereo = 2;
-
-constexpr uint32_t kSampleRate48000 = 48000;
-constexpr uint32_t kSampleRate44100 = 44100;
-constexpr uint32_t kSampleRate32000 = 32000;
-constexpr uint32_t kSampleRate24000 = 24000;
-constexpr uint32_t kSampleRate16000 = 16000;
-constexpr uint32_t kSampleRate8000 = 8000;
-
-constexpr uint8_t kBitsPerSample16 = 16;
-constexpr uint8_t kBitsPerSample24 = 24;
-constexpr uint8_t kBitsPerSample32 = 32;
-
-struct StreamCallbacks {
- std::function<bool(bool start_media_task)> on_resume_;
- std::function<bool(void)> on_suspend_;
- std::function<bool(const source_metadata_t&)> on_metadata_update_;
-};
-
-class LeAudioClientInterface {
- public:
- struct PcmParameters {
- uint32_t data_interval_us;
- uint32_t sample_rate;
- uint8_t bits_per_sample;
- uint8_t channels_count;
- };
-
- private:
- class IClientInterfaceEndpoint {
- public:
- virtual ~IClientInterfaceEndpoint() = default;
- virtual void Cleanup() = 0;
- virtual void SetPcmParameters(const PcmParameters& params) = 0;
- virtual void SetRemoteDelay(uint16_t delay_report_ms) = 0;
- virtual void StartSession() = 0;
- virtual void StopSession() = 0;
- virtual void ConfirmStreamingRequest() = 0;
- virtual void CancelStreamingRequest() = 0;
- };
-
- public:
- class Sink : public IClientInterfaceEndpoint {
- public:
- virtual ~Sink() = default;
-
- void Cleanup() override;
- void SetPcmParameters(const PcmParameters& params) override;
- void SetRemoteDelay(uint16_t delay_report_ms) override;
- void StartSession() override;
- void StopSession() override;
- void ConfirmStreamingRequest() override;
- void CancelStreamingRequest() override;
-
- // Read the stream of bytes sinked to us by the upper layers
- size_t Read(uint8_t* p_buf, uint32_t len);
- };
- class Source : public IClientInterfaceEndpoint {
- public:
- virtual ~Source() = default;
-
- void Cleanup() override;
- void SetPcmParameters(const PcmParameters& params) override;
- void SetRemoteDelay(uint16_t delay_report_ms) override;
- void StartSession() override;
- void StopSession() override;
- void ConfirmStreamingRequest() override;
- void CancelStreamingRequest() override;
-
- // Source the given stream of bytes to be sinked into the upper layers
- size_t Write(const uint8_t* p_buf, uint32_t len);
- };
-
- // Get LE Audio sink client interface if it's not previously acquired and not
- // yet released.
- Sink* GetSink(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop);
- // This should be called before trying to get sink interface
- bool IsSinkAcquired();
- // Release sink interface if belongs to LE audio client interface
- bool ReleaseSink(Sink* sink);
-
- // Get LE Audio source client interface if it's not previously acquired and
- // not yet released.
- Source* GetSource(StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop);
- // This should be called before trying to get source interface
- bool IsSourceAcquired();
- // Release source interface if belongs to LE audio client interface
- bool ReleaseSource(Source* source);
-
- // Get interface, if previously not initialized - it'll initialize singleton.
- static LeAudioClientInterface* Get();
-
- private:
- static LeAudioClientInterface* interface;
- Sink* sink_ = nullptr;
- Source* source_ = nullptr;
-};
-
-} // namespace le_audio
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hal_interface/le_audio_software_host.cc b/audio_hal_interface/le_audio_software_host.cc
deleted file mode 100644
index 5ce552a..0000000
--- a/audio_hal_interface/le_audio_software_host.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
- * www.ehima.com
- *
- * 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 "audio_hal_interface/hal_version_manager.h"
-#include "audio_hal_interface/le_audio_software.h"
-
-namespace bluetooth {
-namespace audio {
-
-namespace le_audio {
-
-LeAudioClientInterface* LeAudioClientInterface::Get() { return nullptr; }
-
-bool LeAudioClientInterface::IsSinkAcquired() { return false; }
-
-bool LeAudioClientInterface::ReleaseSink(LeAudioClientInterface::Sink* sink) {
- return false;
-}
-
-LeAudioClientInterface::Sink* LeAudioClientInterface::GetSink(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- return nullptr;
-}
-
-size_t LeAudioClientInterface::Sink::Read(uint8_t* p_buf, uint32_t len) {
- return 0;
-}
-
-LeAudioClientInterface::Source* LeAudioClientInterface::GetSource(
- StreamCallbacks stream_cb,
- bluetooth::common::MessageLoopThread* message_loop) {
- return nullptr;
-}
-
-size_t LeAudioClientInterface::Source::Write(const uint8_t* p_buf,
- uint32_t len) {
- return 0;
-}
-
-bool LeAudioClientInterface::IsSourceAcquired() { return false; }
-
-bool LeAudioClientInterface::ReleaseSource(
- LeAudioClientInterface::Source* source) {
- return false;
-}
-
-} // namespace le_audio
-} // namespace audio
-} // namespace bluetooth
diff --git a/audio_hearing_aid_hw/Android.bp b/audio_hearing_aid_hw/Android.bp
deleted file mode 100644
index 07fa15f..0000000
--- a/audio_hearing_aid_hw/Android.bp
+++ /dev/null
@@ -1,51 +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 "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_defaults {
- name: "audio_hearing_aid_hw_defaults",
- defaults: ["libchrome_support_defaults"],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/include",
- "system/bt/types",
- ],
-}
-
-// Audio A2DP shared library for target
-cc_library {
- name: "audio.hearing_aid.default",
- defaults: ["audio_hearing_aid_hw_defaults"],
- relative_install_path: "hw",
- srcs: [
- "src/audio_hearing_aid_hw.cc",
- "src/audio_hearing_aid_hw_utils.cc",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: ["libosi"],
-}
-
-// Audio A2DP library unit tests for target and host
-cc_test {
- name: "net_test_audio_hearing_aid_hw",
- test_suites: ["device-tests"],
- defaults: ["audio_hearing_aid_hw_defaults"],
- srcs: [
- "test/audio_hearing_aid_hw_test.cc",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: [
- "audio.hearing_aid.default",
- "libosi",
- ],
-}
diff --git a/audio_hearing_aid_hw/include/audio_hearing_aid_hw.h b/audio_hearing_aid_hw/include/audio_hearing_aid_hw.h
deleted file mode 100644
index 8e4f255..0000000
--- a/audio_hearing_aid_hw/include/audio_hearing_aid_hw.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2016 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.
- *
- ******************************************************************************/
-
-/*****************************************************************************
- *
- * Filename: audio_hearing_aid_hw.h
- *
- * Description:
- *
- *****************************************************************************/
-
-#ifndef AUDIO_HEARING_AID_HW_H
-#define AUDIO_HEARING_AID_HW_H
-
-#include <stdint.h>
-
-#include <hardware/bt_av.h>
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define HEARING_AID_AUDIO_HARDWARE_INTERFACE "audio.hearing_aid"
-#define HEARING_AID_CTRL_PATH "/data/misc/bluedroid/.hearing_aid_ctrl"
-#define HEARING_AID_DATA_PATH "/data/misc/bluedroid/.hearing_aid_data"
-
-// AUDIO_STREAM_OUTPUT_BUFFER_SZ controls the size of the audio socket buffer.
-// If one assumes the write buffer is always full during normal BT playback,
-// then increasing this value increases our playback latency.
-//
-// FIXME: The BT HAL should consume data at a constant rate.
-// AudioFlinger assumes that the HAL draws data at a constant rate, which is
-// true for most audio devices; however, the BT engine reads data at a variable
-// rate (over the short term), which confuses both AudioFlinger as well as
-// applications which deliver data at a (generally) fixed rate.
-//
-// 20 * 512 is not sufficient to smooth the variability for some BT devices,
-// resulting in mixer sleep and throttling. We increase this to 28 * 512 to help
-// reduce the effect of variable data consumption.
-#define AUDIO_STREAM_OUTPUT_BUFFER_SZ (28 * 512)
-#define AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ 256
-
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is divided
-// for AudioFlinger data delivery. The AudioFlinger mixer delivers data in
-// chunks of AUDIO_STREAM_OUTPUT_BUFFER_SZ / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS.
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// In general, AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 * 4 should be a divisor
-// of AUDIO_STREAM_OUTPUT_BUFFER_SZ.
-//
-// These values should be chosen such that
-//
-// AUDIO_STREAM_BUFFER_SIZE * 1000 / (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS
-// * AUDIO_STREAM_DEFAULT_RATE * 4) > 20 (ms)
-//
-// to avoid introducing the FastMixer in AudioFlinger. Using the FastMixer
-// results in unnecessary latency and CPU overhead for Bluetooth.
-#define AUDIO_STREAM_OUTPUT_BUFFER_PERIODS 2
-
-#define AUDIO_SKT_DISCONNECTED (-1)
-
-typedef enum {
- HEARING_AID_CTRL_CMD_NONE,
- HEARING_AID_CTRL_CMD_CHECK_READY,
- HEARING_AID_CTRL_CMD_START,
- HEARING_AID_CTRL_CMD_STOP,
- HEARING_AID_CTRL_CMD_SUSPEND,
- HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG,
- HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG,
- HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG,
- HEARING_AID_CTRL_CMD_OFFLOAD_START,
-} tHEARING_AID_CTRL_CMD;
-
-typedef enum {
- HEARING_AID_CTRL_ACK_SUCCESS,
- HEARING_AID_CTRL_ACK_FAILURE,
- HEARING_AID_CTRL_ACK_INCALL_FAILURE, /* Failure when in Call*/
- HEARING_AID_CTRL_ACK_UNSUPPORTED
-} tHEARING_AID_CTRL_ACK;
-
-typedef uint32_t tHA_SAMPLE_RATE;
-typedef uint8_t tHA_CHANNEL_COUNT;
-
-/*****************************************************************************
- * Type definitions for callback functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Type definitions and return values
- *****************************************************************************/
-
-/*****************************************************************************
- * Extern variables and functions
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-
-// Computes the Audio Hearing Aid HAL output buffer size.
-// |codec_sample_rate| is the sample rate of the output stream.
-// |codec_bits_per_sample| is the number of bits per sample of the output
-// stream.
-// |codec_channel_mode| is the channel mode of the output stream.
-//
-// The buffer size is computed by using the following formula:
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
-// (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
-// SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
-//
-// AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
-// divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
-// data in chunks of
-// (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
-// If the number of periods is 2, the socket buffer represents "double
-// buffering" of the AudioFlinger mixer buffer.
-//
-// Furthermore, the AudioFlinger expects the buffer size to be a multiple
-// of 16 frames.
-//
-// NOTE: Currently, the computation uses the conservative 20ms time period.
-//
-// Returns the computed buffer size. If any of the input parameters is
-// invalid, the return value is the default |AUDIO_STREAM_OUTPUT_BUFFER_SZ|.
-extern size_t audio_ha_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode);
-
-#endif /* AUDIO_HEARING_AID_HW_H */
diff --git a/audio_hearing_aid_hw/src/audio_hearing_aid_hw.cc b/audio_hearing_aid_hw/src/audio_hearing_aid_hw.cc
deleted file mode 100644
index 4a9191e..0000000
--- a/audio_hearing_aid_hw/src/audio_hearing_aid_hw.cc
+++ /dev/null
@@ -1,1921 +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.
- *
- ******************************************************************************/
-
-/* Implements hal for bluedroid ha audio device */
-
-#define LOG_TAG "bt_hearing_aid_hw"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <sys/errno.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <mutex>
-
-#include <hardware/audio.h>
-#include <hardware/hardware.h>
-#include <log/log.h>
-#include <system/audio.h>
-
-#include "osi/include/hash_map_utils.h"
-#include "osi/include/osi.h"
-#include "osi/include/socket_utils/sockets.h"
-
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-
-/*****************************************************************************
- * Constants & Macros
- *****************************************************************************/
-
-#define CTRL_CHAN_RETRY_COUNT 3
-#define USEC_PER_SEC 1000000L
-#define SOCK_SEND_TIMEOUT_MS 2000 /* Timeout for sending */
-#define SOCK_RECV_TIMEOUT_MS 5000 /* Timeout for receiving */
-
-// set WRITE_POLL_MS to 0 for blocking sockets, nonzero for polled non-blocking
-// sockets
-#define WRITE_POLL_MS 20
-
-#define FNLOG() ALOGV("%s:%d %s: ", __FILE__, __LINE__, __func__)
-#define DEBUG(fmt, args...) \
- ALOGD("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define INFO(fmt, args...) \
- ALOGI("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define WARN(fmt, args...) \
- ALOGW("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-#define ERROR(fmt, args...) \
- ALOGE("%s:%d %s: " fmt, __FILE__, __LINE__, __func__, ##args)
-
-#define ASSERTC(cond, msg, val) \
- if (!(cond)) { \
- ERROR("### ASSERT : %s line %d %s (%d) ###", __FILE__, __LINE__, msg, \
- val); \
- }
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-static const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event) {
- switch (event) {
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_NONE)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_CHECK_READY)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_START)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_STOP)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_SUSPEND)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_OFFLOAD_START)
- default:
- break;
- }
-
- return "UNKNOWN HEARING_AID_CTRL_CMD";
-}
-
-/*****************************************************************************
- * Local type definitions
- *****************************************************************************/
-
-typedef enum {
- AUDIO_HA_STATE_STARTING,
- AUDIO_HA_STATE_STARTED,
- AUDIO_HA_STATE_STOPPING,
- AUDIO_HA_STATE_STOPPED,
- /* need explicit set param call to resume (suspend=false) */
- AUDIO_HA_STATE_SUSPENDED,
- AUDIO_HA_STATE_STANDBY /* allows write to autoresume */
-} ha_state_t;
-
-struct ha_stream_in;
-struct ha_stream_out;
-
-struct ha_audio_device {
- // Important: device must be first as an audio_hw_device* may be cast to
- // ha_audio_device* when the type is implicitly known.
- struct audio_hw_device device;
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- struct ha_stream_in* input;
- struct ha_stream_out* output;
-};
-
-struct ha_config {
- uint32_t rate;
- uint32_t channel_mask;
- bool is_stereo_to_mono; // True if fetching Stereo and mixing into Mono
- int format;
-};
-
-/* move ctrl_fd outside output stream and keep open until HAL unloaded ? */
-
-struct ha_stream_common {
- std::recursive_mutex* mutex; // See note below on mutex acquisition order.
- int ctrl_fd;
- int audio_fd;
- size_t buffer_sz;
- struct ha_config cfg;
- ha_state_t state;
-};
-
-struct ha_stream_out {
- struct audio_stream_out stream;
- struct ha_stream_common common;
- uint64_t frames_presented; // frames written, never reset
- uint64_t frames_rendered; // frames written, reset on standby
-};
-
-struct ha_stream_in {
- struct audio_stream_in stream;
- struct ha_stream_common common;
-};
-
-/*
- * Mutex acquisition order:
- *
- * The ha_audio_device (adev) mutex must be acquired before
- * the ha_stream_common (out or in) mutex.
- *
- * This may differ from other audio HALs.
- */
-
-/*****************************************************************************
- * Static variables
- *****************************************************************************/
-
-/*****************************************************************************
- * Static functions
- *****************************************************************************/
-static void hash_map_utils_dump_string_keys_string_values(
- std::unordered_map<std::string, std::string>& map) {
- for (const auto& ptr : map) {
- INFO("key: '%s' value: '%s'\n", ptr.first.c_str(), ptr.second.c_str());
- }
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream);
-
-/*****************************************************************************
- * Externs
- *****************************************************************************/
-
-/*****************************************************************************
- * Functions
- *****************************************************************************/
-static void ha_open_ctrl_path(struct ha_stream_common* common);
-
-/*****************************************************************************
- * Miscellaneous helper functions
- *****************************************************************************/
-
-/* logs timestamp with microsec precision
- pprev is optional in case a dedicated diff is required */
-static void ts_log(UNUSED_ATTR const char* tag, UNUSED_ATTR int val,
- struct timespec* pprev_opt) {
- struct timespec now;
- static struct timespec prev = {0, 0};
- unsigned long long now_us;
- unsigned long long diff_us;
-
- clock_gettime(CLOCK_MONOTONIC, &now);
-
- now_us = now.tv_sec * USEC_PER_SEC + now.tv_nsec / 1000;
-
- if (pprev_opt) {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- *pprev_opt = now;
- DEBUG("[%s] ts %08lld, *diff %08lld, val %d", tag, now_us, diff_us, val);
- } else {
- diff_us = (now.tv_sec - prev.tv_sec) * USEC_PER_SEC +
- (now.tv_nsec - prev.tv_nsec) / 1000;
- prev = now;
- DEBUG("[%s] ts %08lld, diff %08lld, val %d", tag, now_us, diff_us, val);
- }
-}
-
-static int calc_audiotime_usec(struct ha_config cfg, int bytes) {
- int chan_count = audio_channel_count_from_out_mask(cfg.channel_mask);
- int bytes_per_sample;
-
- switch (cfg.format) {
- case AUDIO_FORMAT_PCM_8_BIT:
- bytes_per_sample = 1;
- break;
- case AUDIO_FORMAT_PCM_16_BIT:
- bytes_per_sample = 2;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- bytes_per_sample = 3;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- bytes_per_sample = 4;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- bytes_per_sample = 4;
- break;
- default:
- ASSERTC(false, "unsupported sample format", cfg.format);
- bytes_per_sample = 2;
- break;
- }
-
- return (
- int)(((int64_t)bytes * (USEC_PER_SEC / (chan_count * bytes_per_sample))) /
- cfg.rate);
-}
-
-/*****************************************************************************
- *
- * bluedroid stack adaptation
- *
- ****************************************************************************/
-
-static int skt_connect(const char* path, size_t buffer_sz) {
- int ret;
- int skt_fd;
- int len;
-
- INFO("connect to %s (sz %zu)", path, buffer_sz);
-
- skt_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
-
- if (osi_socket_local_client_connect(
- skt_fd, path, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) < 0) {
- ERROR("failed to connect (%s)", strerror(errno));
- close(skt_fd);
- return -1;
- }
-
- len = buffer_sz;
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- ret =
- setsockopt(skt_fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, (int)sizeof(len));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- /* Socket send/receive timeout value */
- struct timeval tv;
- tv.tv_sec = SOCK_SEND_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_SEND_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- tv.tv_sec = SOCK_RECV_TIMEOUT_MS / 1000;
- tv.tv_usec = (SOCK_RECV_TIMEOUT_MS % 1000) * 1000;
-
- ret = setsockopt(skt_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
- if (ret < 0) ERROR("setsockopt failed (%s)", strerror(errno));
-
- INFO("connected to stack fd = %d", skt_fd);
-
- return skt_fd;
-}
-
-static int skt_read(int fd, void* p, size_t len) {
- ssize_t read;
-
- FNLOG();
-
- ts_log("skt_read recv", len, NULL);
-
- OSI_NO_INTR(read = recv(fd, p, len, MSG_NOSIGNAL));
- if (read == -1) ERROR("read failed with errno=%d\n", errno);
-
- return (int)read;
-}
-
-static int skt_write(int fd, const void* p, size_t len) {
- ssize_t sent;
- FNLOG();
-
- ts_log("skt_write", len, NULL);
-
- if (WRITE_POLL_MS == 0) {
- // do not poll, use blocking send
- OSI_NO_INTR(sent = send(fd, p, len, MSG_NOSIGNAL));
- if (sent == -1) ERROR("write failed with error(%s)", strerror(errno));
-
- return (int)sent;
- }
-
- // use non-blocking send, poll
- int ms_timeout = SOCK_SEND_TIMEOUT_MS;
- size_t count = 0;
- while (count < len) {
- OSI_NO_INTR(sent = send(fd, p, len - count, MSG_NOSIGNAL | MSG_DONTWAIT));
- if (sent == -1) {
- if (errno != EAGAIN && errno != EWOULDBLOCK) {
- ERROR("write failed with error(%s)", strerror(errno));
- return -1;
- }
- if (ms_timeout >= WRITE_POLL_MS) {
- usleep(WRITE_POLL_MS * 1000);
- ms_timeout -= WRITE_POLL_MS;
- continue;
- }
- WARN("write timeout exceeded, sent %zu bytes", count);
- return -1;
- }
- count += sent;
- p = (const uint8_t*)p + sent;
- }
- return (int)count;
-}
-
-static int skt_disconnect(int fd) {
- INFO("fd %d", fd);
-
- if (fd != AUDIO_SKT_DISCONNECTED) {
- shutdown(fd, SHUT_RDWR);
- close(fd);
- }
- return 0;
-}
-
-/*****************************************************************************
- *
- * AUDIO CONTROL PATH
- *
- ****************************************************************************/
-
-static int ha_ctrl_receive(struct ha_stream_common* common, void* buffer,
- size_t length) {
- ssize_t ret;
- int i;
-
- for (i = 0;; i++) {
- OSI_NO_INTR(ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
- if (ret > 0) {
- break;
- }
- if (ret == 0) {
- ERROR("receive control data failed: peer closed");
- break;
- }
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("receive control data failed: error(%s)", strerror(errno));
- break;
- }
- if (i == (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("receive control data failed: max retry count");
- break;
- }
- INFO("receive control data failed (%s), retrying", strerror(errno));
- }
- if (ret <= 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- return ret;
-}
-
-// Sends control info for stream |common|. The data to send is stored in
-// |buffer| and has size |length|.
-// On success, returns the number of octets sent, otherwise -1.
-static int ha_ctrl_send(struct ha_stream_common* common, const void* buffer,
- size_t length) {
- ssize_t sent;
- size_t remaining = length;
- int i;
-
- if (length == 0) return 0; // Nothing to do
-
- for (i = 0;; i++) {
- OSI_NO_INTR(sent = send(common->ctrl_fd, buffer, remaining, MSG_NOSIGNAL));
- if (sent == static_cast<ssize_t>(remaining)) {
- remaining = 0;
- break;
- }
- if (sent > 0) {
- buffer = (static_cast<const char*>(buffer) + sent);
- remaining -= sent;
- continue;
- }
- if (sent < 0) {
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- ERROR("send control data failed: error(%s)", strerror(errno));
- break;
- }
- INFO("send control data failed (%s), retrying", strerror(errno));
- }
- if (i >= (CTRL_CHAN_RETRY_COUNT - 1)) {
- ERROR("send control data failed: max retry count");
- break;
- }
- }
- if (remaining > 0) {
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
- return length;
-}
-
-static int ha_command(struct ha_stream_common* common,
- tHEARING_AID_CTRL_CMD cmd) {
- char ack;
-
- DEBUG("HEARING_AID COMMAND %s", audio_ha_hw_dump_ctrl_event(cmd));
-
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- INFO("starting up or recovering from previous error");
- ha_open_ctrl_path(common);
- if (common->ctrl_fd == AUDIO_SKT_DISCONNECTED) {
- ERROR("failure to open ctrl path");
- return -1;
- }
- }
-
- /* send command */
- ssize_t sent;
- OSI_NO_INTR(sent = send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL));
- if (sent == -1) {
- ERROR("cmd failed (%s)", strerror(errno));
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- return -1;
- }
-
- /* wait for ack byte */
- if (ha_ctrl_receive(common, &ack, 1) < 0) {
- ERROR("HEARING_AID COMMAND %s: no ACK", audio_ha_hw_dump_ctrl_event(cmd));
- return -1;
- }
-
- DEBUG("HEARING_AID COMMAND %s DONE STATUS %d",
- audio_ha_hw_dump_ctrl_event(cmd), ack);
-
- if (ack == HEARING_AID_CTRL_ACK_INCALL_FAILURE) return ack;
- if (ack != HEARING_AID_CTRL_ACK_SUCCESS) {
- ERROR("HEARING_AID COMMAND %s error %d", audio_ha_hw_dump_ctrl_event(cmd),
- ack);
- return -1;
- }
-
- return 0;
-}
-
-static int check_ha_ready(struct ha_stream_common* common) {
- if (ha_command(common, HEARING_AID_CTRL_CMD_CHECK_READY) < 0) {
- ERROR("check ha ready failed");
- return -1;
- }
- return 0;
-}
-
-static int ha_read_input_audio_config(struct ha_stream_common* common) {
- tHA_SAMPLE_RATE sample_rate;
- tHA_CHANNEL_COUNT channel_count;
-
- if (ha_command(common, HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG) < 0) {
- ERROR("get ha input audio config failed");
- return -1;
- }
-
- if (ha_ctrl_receive(common, &sample_rate, sizeof(tHA_SAMPLE_RATE)) < 0)
- return -1;
- if (ha_ctrl_receive(common, &channel_count, sizeof(tHA_CHANNEL_COUNT)) < 0) {
- return -1;
- }
-
- switch (sample_rate) {
- case 16000:
- case 24000:
- case 44100:
- case 48000:
- common->cfg.rate = sample_rate;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, sample_rate);
- return -1;
- }
-
- switch (channel_count) {
- case 1:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_MONO;
- break;
- case 2:
- common->cfg.channel_mask = AUDIO_CHANNEL_IN_STEREO;
- break;
- default:
- ERROR("Invalid channel count: %" PRIu32, channel_count);
- return -1;
- }
-
- // TODO: For now input audio format is always hard-coded as PCM 16-bit
- common->cfg.format = AUDIO_FORMAT_PCM_16_BIT;
-
- INFO("got input audio config %d %d", common->cfg.format, common->cfg.rate);
-
- return 0;
-}
-
-static int ha_read_output_audio_config(
- struct ha_stream_common* common, btav_a2dp_codec_config_t* codec_config,
- btav_a2dp_codec_config_t* codec_capability, bool update_stream_config) {
- struct ha_config stream_config;
-
- if (ha_command(common, HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("get ha output audio config failed");
- return -1;
- }
-
- // Receive the current codec config
- if (ha_ctrl_receive(common, &codec_config->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_config->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_config->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Receive the current codec capability
- if (ha_ctrl_receive(common, &codec_capability->sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_capability->bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_receive(common, &codec_capability->channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- // Check the codec config sample rate
- switch (codec_config->sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- stream_config.rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- stream_config.rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- stream_config.rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- stream_config.rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- stream_config.rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- stream_config.rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- stream_config.rate = 16000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- stream_config.rate = 24000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_config->sample_rate);
- return -1;
- }
-
- // Check the codec config bits per sample
- switch (codec_config->bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- stream_config.format = AUDIO_FORMAT_PCM_16_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- stream_config.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- stream_config.format = AUDIO_FORMAT_PCM_32_BIT;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_config->bits_per_sample);
- return -1;
- }
-
- // Check the codec config channel mode
- switch (codec_config->channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_MONO;
- stream_config.is_stereo_to_mono = true;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- stream_config.is_stereo_to_mono = false;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_config->channel_mode);
- return -1;
- }
- if (stream_config.is_stereo_to_mono) {
- stream_config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
- }
-
- // Update the output stream configuration
- if (update_stream_config) {
- common->cfg.rate = stream_config.rate;
- common->cfg.channel_mask = stream_config.channel_mask;
- common->cfg.is_stereo_to_mono = stream_config.is_stereo_to_mono;
- common->cfg.format = stream_config.format;
- common->buffer_sz = audio_ha_hw_stream_compute_buffer_size(
- codec_config->sample_rate, codec_config->bits_per_sample,
- codec_config->channel_mode);
- if (common->cfg.is_stereo_to_mono) {
- // We need to fetch twice as much data from the Audio framework
- common->buffer_sz *= 2;
- }
- }
-
- INFO(
- "got output codec config (update_stream_config=%s): "
- "sample_rate=0x%x bits_per_sample=0x%x channel_mode=0x%x",
- update_stream_config ? "true" : "false", codec_config->sample_rate,
- codec_config->bits_per_sample, codec_config->channel_mode);
-
- INFO(
- "got output codec capability: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_capability->sample_rate, codec_capability->bits_per_sample,
- codec_capability->channel_mode);
-
- return 0;
-}
-
-static int ha_write_output_audio_config(struct ha_stream_common* common) {
- btav_a2dp_codec_config_t codec_config;
-
- if (ha_command(common, HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG) < 0) {
- ERROR("set ha output audio config failed");
- return -1;
- }
-
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
-
- switch (common->cfg.rate) {
- case 44100:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
- break;
- case 48000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
- break;
- case 88200:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_88200;
- break;
- case 96000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_96000;
- break;
- case 176400:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_176400;
- break;
- case 192000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_192000;
- break;
- case 16000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
- break;
- case 24000:
- codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
- break;
- default:
- ERROR("Invalid sample rate: %" PRIu32, common->cfg.rate);
- return -1;
- }
-
- switch (common->cfg.format) {
- case AUDIO_FORMAT_PCM_16_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
- break;
- case AUDIO_FORMAT_PCM_24_BIT_PACKED:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
- break;
- case AUDIO_FORMAT_PCM_32_BIT:
- codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32;
- break;
- case AUDIO_FORMAT_PCM_8_24_BIT:
- // All 24-bit audio is expected in AUDIO_FORMAT_PCM_24_BIT_PACKED format
- FALLTHROUGH_INTENDED; /* FALLTHROUGH */
- default:
- ERROR("Invalid audio format: 0x%x", common->cfg.format);
- return -1;
- }
-
- switch (common->cfg.channel_mask) {
- case AUDIO_CHANNEL_OUT_MONO:
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- break;
- case AUDIO_CHANNEL_OUT_STEREO:
- if (common->cfg.is_stereo_to_mono) {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
- } else {
- codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
- }
- break;
- default:
- ERROR("Invalid channel mask: 0x%x", common->cfg.channel_mask);
- return -1;
- }
-
- // Send the current codec config that has been selected by us
- if (ha_ctrl_send(common, &codec_config.sample_rate,
- sizeof(btav_a2dp_codec_sample_rate_t)) < 0)
- return -1;
- if (ha_ctrl_send(common, &codec_config.bits_per_sample,
- sizeof(btav_a2dp_codec_bits_per_sample_t)) < 0) {
- return -1;
- }
- if (ha_ctrl_send(common, &codec_config.channel_mode,
- sizeof(btav_a2dp_codec_channel_mode_t)) < 0) {
- return -1;
- }
-
- INFO(
- "sent output codec config: sample_rate=0x%x bits_per_sample=0x%x "
- "channel_mode=0x%x",
- codec_config.sample_rate, codec_config.bits_per_sample,
- codec_config.channel_mode);
-
- return 0;
-}
-
-static void ha_open_ctrl_path(struct ha_stream_common* common) {
- int i;
-
- if (common->ctrl_fd != AUDIO_SKT_DISCONNECTED) return; // already connected
-
- /* retry logic to catch any timing variations on control channel */
- for (i = 0; i < CTRL_CHAN_RETRY_COUNT; i++) {
- /* connect control channel if not already connected */
- if ((common->ctrl_fd = skt_connect(
- HEARING_AID_CTRL_PATH, AUDIO_STREAM_CONTROL_OUTPUT_BUFFER_SZ)) >=
- 0) {
- /* success, now check if stack is ready */
- if (check_ha_ready(common) == 0) break;
-
- ERROR("error : ha not ready, wait 250 ms and retry");
- usleep(250000);
- skt_disconnect(common->ctrl_fd);
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- /* ctrl channel not ready, wait a bit */
- usleep(250000);
- }
-}
-
-/*****************************************************************************
- *
- * AUDIO DATA PATH
- *
- ****************************************************************************/
-
-static void ha_stream_common_init(struct ha_stream_common* common) {
- FNLOG();
-
- common->mutex = new std::recursive_mutex;
-
- common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
- common->state = AUDIO_HA_STATE_STOPPED;
-
- /* manages max capacity of socket pipe */
- common->buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ;
-}
-
-static void ha_stream_common_destroy(struct ha_stream_common* common) {
- FNLOG();
-
- delete common->mutex;
- common->mutex = NULL;
-}
-
-static int start_audio_datapath(struct ha_stream_common* common) {
- INFO("state %d", common->state);
-
- int oldstate = common->state;
- common->state = AUDIO_HA_STATE_STARTING;
-
- int ha_status = ha_command(common, HEARING_AID_CTRL_CMD_START);
- if (ha_status < 0) {
- ERROR("Audiopath start failed (status %d)", ha_status);
- goto error;
- } else if (ha_status == HEARING_AID_CTRL_ACK_INCALL_FAILURE) {
- ERROR("Audiopath start failed - in call, move to suspended");
- goto error;
- }
-
- /* connect socket if not yet connected */
- if (common->audio_fd == AUDIO_SKT_DISCONNECTED) {
- common->audio_fd = skt_connect(HEARING_AID_DATA_PATH, common->buffer_sz);
- if (common->audio_fd < 0) {
- ERROR("Audiopath start failed - error opening data socket");
- goto error;
- }
- }
- common->state = (ha_state_t)AUDIO_HA_STATE_STARTED;
- return 0;
-
-error:
- common->state = (ha_state_t)oldstate;
- return -1;
-}
-
-static int stop_audio_datapath(struct ha_stream_common* common) {
- int oldstate = common->state;
-
- INFO("state %d", common->state);
-
- /* prevent any stray output writes from autostarting the stream
- while stopping audiopath */
- common->state = AUDIO_HA_STATE_STOPPING;
-
- if (ha_command(common, HEARING_AID_CTRL_CMD_STOP) < 0) {
- ERROR("audiopath stop failed");
- common->state = (ha_state_t)oldstate;
- return -1;
- }
-
- common->state = (ha_state_t)AUDIO_HA_STATE_STOPPED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-static int suspend_audio_datapath(struct ha_stream_common* common,
- bool standby) {
- INFO("state %d", common->state);
-
- if (common->state == AUDIO_HA_STATE_STOPPING) return -1;
-
- if (ha_command(common, HEARING_AID_CTRL_CMD_SUSPEND) < 0) return -1;
-
- if (standby)
- common->state = AUDIO_HA_STATE_STANDBY;
- else
- common->state = AUDIO_HA_STATE_SUSPENDED;
-
- /* disconnect audio path */
- skt_disconnect(common->audio_fd);
-
- common->audio_fd = AUDIO_SKT_DISCONNECTED;
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * audio output callbacks
- *
- ****************************************************************************/
-
-static ssize_t out_write(struct audio_stream_out* stream, const void* buffer,
- size_t bytes) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- int sent = -1;
- size_t write_bytes = bytes;
-
- DEBUG("write %zu bytes (fd %d)", bytes, out->common.audio_fd);
-
- std::unique_lock<std::recursive_mutex> lock(*out->common.mutex);
- if (out->common.state == AUDIO_HA_STATE_SUSPENDED ||
- out->common.state == AUDIO_HA_STATE_STOPPING) {
- DEBUG("stream suspended or closing");
- goto finish;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((out->common.state == AUDIO_HA_STATE_STOPPED) ||
- (out->common.state == AUDIO_HA_STATE_STANDBY)) {
- if (start_audio_datapath(&out->common) < 0) {
- goto finish;
- }
- } else if (out->common.state != AUDIO_HA_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto finish;
- }
-
- // Mix the stereo into mono if necessary
- if (out->common.cfg.is_stereo_to_mono) {
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- int16_t* src = (int16_t*)buffer;
- int16_t* dst = (int16_t*)buffer;
- for (size_t i = 0; i < frames; i++, dst++, src += 2) {
- *dst = (int16_t)(((int32_t)src[0] + (int32_t)src[1]) >> 1);
- }
- write_bytes /= 2;
- DEBUG("stereo-to-mono mixing: write %zu bytes (fd %d)", write_bytes,
- out->common.audio_fd);
- }
-
- lock.unlock();
- sent = skt_write(out->common.audio_fd, buffer, write_bytes);
- lock.lock();
-
- if (sent == -1) {
- skt_disconnect(out->common.audio_fd);
- out->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((out->common.state != AUDIO_HA_STATE_SUSPENDED) &&
- (out->common.state != AUDIO_HA_STATE_STOPPING)) {
- out->common.state = AUDIO_HA_STATE_STOPPED;
- } else {
- ERROR("write failed : stream suspended, avoid resetting state");
- }
- goto finish;
- }
-
-finish:;
- const size_t frames = bytes / audio_stream_out_frame_size(stream);
- out->frames_rendered += frames;
- out->frames_presented += frames;
- lock.unlock();
-
- // If send didn't work out, sleep to emulate write delay.
- if (sent == -1) {
- const int us_delay = calc_audiotime_usec(out->common.cfg, bytes);
- DEBUG("emulate ha write delay (%d us)", us_delay);
- usleep(us_delay);
- }
- return bytes;
-}
-
-static uint32_t out_get_sample_rate(const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- DEBUG("rate %" PRIu32, out->common.cfg.rate);
-
- return out->common.cfg.rate;
-}
-
-static int out_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- DEBUG("out_set_sample_rate : %" PRIu32, rate);
-
- out->common.cfg.rate = rate;
-
- return 0;
-}
-
-static size_t out_get_buffer_size(const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- // period_size is the AudioFlinger mixer buffer size.
- const size_t period_size =
- out->common.buffer_sz / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS;
-
- DEBUG("socket buffer size: %zu period size: %zu", out->common.buffer_sz,
- period_size);
-
- return period_size;
-}
-
-size_t audio_ha_hw_stream_compute_buffer_size(
- btav_a2dp_codec_sample_rate_t codec_sample_rate,
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample,
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- size_t buffer_sz = AUDIO_STREAM_OUTPUT_BUFFER_SZ; // Default value
- const uint64_t time_period_ms = 20; // Conservative 20ms
- uint32_t sample_rate;
- uint32_t bits_per_sample;
- uint32_t number_of_channels;
-
- // Check the codec config sample rate
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- sample_rate = 44100;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- sample_rate = 48000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- sample_rate = 88200;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- sample_rate = 96000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- sample_rate = 176400;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- sample_rate = 192000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- sample_rate = 16000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- sample_rate = 24000;
- break;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- default:
- ERROR("Invalid sample rate: 0x%x", codec_sample_rate);
- return buffer_sz;
- }
-
- // Check the codec config bits per sample
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- bits_per_sample = 16;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- bits_per_sample = 24;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- bits_per_sample = 32;
- break;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- default:
- ERROR("Invalid bits per sample: 0x%x", codec_bits_per_sample);
- return buffer_sz;
- }
-
- // Check the codec config channel mode
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- number_of_channels = 1;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- number_of_channels = 2;
- break;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- default:
- ERROR("Invalid channel mode: 0x%x", codec_channel_mode);
- return buffer_sz;
- }
-
- //
- // The buffer size is computed by using the following formula:
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_SIZE =
- // (TIME_PERIOD_MS * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- // SAMPLE_RATE_HZ * NUMBER_OF_CHANNELS * (BITS_PER_SAMPLE / 8)) / 1000
- //
- // AUDIO_STREAM_OUTPUT_BUFFER_PERIODS controls how the socket buffer is
- // divided for AudioFlinger data delivery. The AudioFlinger mixer delivers
- // data in chunks of
- // (AUDIO_STREAM_OUTPUT_BUFFER_SIZE / AUDIO_STREAM_OUTPUT_BUFFER_PERIODS) .
- // If the number of periods is 2, the socket buffer represents "double
- // buffering" of the AudioFlinger mixer buffer.
- //
- // Furthermore, the AudioFlinger expects the buffer size to be a multiple
- // of 16 frames.
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
-
- buffer_sz = (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS *
- sample_rate * number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Adjust the buffer size so it can be divided by the divisor
- const size_t remainder = buffer_sz % divisor;
- if (remainder != 0) {
- buffer_sz += divisor - remainder;
- }
-
- return buffer_sz;
-}
-
-static audio_channel_mask_t out_get_channels(
- const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- DEBUG("channels 0x%" PRIx32, out->common.cfg.channel_mask);
-
- return (audio_channel_mask_t)out->common.cfg.channel_mask;
-}
-
-static audio_format_t out_get_format(const struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- DEBUG("format 0x%x", out->common.cfg.format);
- return (audio_format_t)out->common.cfg.format;
-}
-
-static int out_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- DEBUG("setting format not yet supported (0x%x)", format);
- return -ENOSYS;
-}
-
-static int out_standby(struct audio_stream* stream) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
- int retVal = 0;
-
- FNLOG();
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- // Do nothing in SUSPENDED state.
- if (out->common.state != AUDIO_HA_STATE_SUSPENDED)
- retVal = suspend_audio_datapath(&out->common, true);
- out->frames_rendered = 0; // rendered is reset, presented is not
-
- return retVal;
-}
-
-static int out_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int out_set_parameters(struct audio_stream* stream,
- const char* kvpairs) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- INFO("state %d kvpairs %s", out->common.state, kvpairs);
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(kvpairs);
- int status = 0;
-
- if (params.empty()) return status;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- /* dump params */
- hash_map_utils_dump_string_keys_string_values(params);
-
- if (params["closing"].compare("true") == 0) {
- DEBUG("stream closing, disallow any writes");
- out->common.state = AUDIO_HA_STATE_STOPPING;
- }
-
- if (params["HearingAidSuspended"].compare("true") == 0) {
- if (out->common.state == AUDIO_HA_STATE_STARTED)
- status = suspend_audio_datapath(&out->common, false);
- } else {
- /* Do not start the streaming automatically. If the phone was streaming
- * prior to being suspended, the next out_write shall trigger the
- * AVDTP start procedure */
- if (out->common.state == AUDIO_HA_STATE_SUSPENDED)
- out->common.state = AUDIO_HA_STATE_STANDBY;
- /* Irrespective of the state, return 0 */
- }
-
- return status;
-}
-
-static char* out_get_parameters(const struct audio_stream* stream,
- const char* keys) {
- FNLOG();
-
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
-
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- std::unordered_map<std::string, std::string> return_params;
-
- if (params.empty()) return strdup("");
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
-
- if (ha_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- false /* update_stream_config */) < 0) {
- ERROR("ha_read_output_audio_config failed");
- goto done;
- }
-
- // Add the format
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_FORMATS) != params.end()) {
- std::string param;
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_16_BIT";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_24_BIT_PACKED";
- }
- if (codec_capability.bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32) {
- if (!param.empty()) param += "|";
- param += "AUDIO_FORMAT_PCM_32_BIT";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability bits_per_sample=0x%x",
- codec_capability.bits_per_sample);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_FORMATS] = param;
- }
- }
-
- // Add the sample rate
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES) != params.end()) {
- std::string param;
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_44100) {
- if (!param.empty()) param += "|";
- param += "44100";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_48000) {
- if (!param.empty()) param += "|";
- param += "48000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_88200) {
- if (!param.empty()) param += "|";
- param += "88200";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_96000) {
- if (!param.empty()) param += "|";
- param += "96000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_176400) {
- if (!param.empty()) param += "|";
- param += "176400";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_192000) {
- if (!param.empty()) param += "|";
- param += "192000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_16000) {
- if (!param.empty()) param += "|";
- param += "16000";
- }
- if (codec_capability.sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_24000) {
- if (!param.empty()) param += "|";
- param += "24000";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability sample_rate=0x%x",
- codec_capability.sample_rate);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES] = param;
- }
- }
-
- // Add the channel mask
- if (params.find(AUDIO_PARAMETER_STREAM_SUP_CHANNELS) != params.end()) {
- std::string param;
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_MONO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_MONO";
- }
- if (codec_capability.channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) {
- if (!param.empty()) param += "|";
- param += "AUDIO_CHANNEL_OUT_STEREO";
- }
- if (param.empty()) {
- ERROR("Invalid codec capability channel_mode=0x%x",
- codec_capability.channel_mode);
- goto done;
- } else {
- return_params[AUDIO_PARAMETER_STREAM_SUP_CHANNELS] = param;
- }
- }
-
-done:
- std::string result;
- for (const auto& ptr : return_params) {
- result += ptr.first + "=" + ptr.second + ";";
- }
-
- INFO("get parameters result = %s", result.c_str());
-
- return strdup(result.c_str());
-}
-
-static uint32_t out_get_latency(const struct audio_stream_out* stream) {
- int latency_us;
-
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- FNLOG();
-
- latency_us =
- ((out->common.buffer_sz * 1000) /
- audio_stream_out_frame_size(&out->stream) / out->common.cfg.rate) *
- 1000;
-
- return (latency_us / 1000) + 200;
-}
-
-static int out_set_volume(UNUSED_ATTR struct audio_stream_out* stream,
- UNUSED_ATTR float left, UNUSED_ATTR float right) {
- FNLOG();
-
- /* volume controlled in audioflinger mixer (digital) */
-
- return -ENOSYS;
-}
-
-static int out_get_presentation_position(const struct audio_stream_out* stream,
- uint64_t* frames,
- struct timespec* timestamp) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || frames == NULL || timestamp == NULL) return -EINVAL;
-
- int ret = -EWOULDBLOCK;
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_presented >= latency_frames) {
- *frames = out->frames_presented - latency_frames;
- clock_gettime(CLOCK_MONOTONIC,
- timestamp); // could also be associated with out_write().
- ret = 0;
- }
- return ret;
-}
-
-static int out_get_render_position(const struct audio_stream_out* stream,
- uint32_t* dsp_frames) {
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- FNLOG();
- if (stream == NULL || dsp_frames == NULL) return -EINVAL;
-
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- uint64_t latency_frames =
- (uint64_t)out_get_latency(stream) * out->common.cfg.rate / 1000;
- if (out->frames_rendered >= latency_frames) {
- *dsp_frames = (uint32_t)(out->frames_rendered - latency_frames);
- } else {
- *dsp_frames = 0;
- }
- return 0;
-}
-
-static int out_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int out_remove_audio_effect(
- UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-/*
- * AUDIO INPUT STREAM
- */
-
-static uint32_t in_get_sample_rate(const struct audio_stream* stream) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- FNLOG();
- return in->common.cfg.rate;
-}
-
-static int in_set_sample_rate(struct audio_stream* stream, uint32_t rate) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- FNLOG();
-
- if (in->common.cfg.rate > 0 && in->common.cfg.rate == rate)
- return 0;
- else
- return -1;
-}
-
-static size_t in_get_buffer_size(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return 320;
-}
-
-static audio_channel_mask_t in_get_channels(const struct audio_stream* stream) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- FNLOG();
- return (audio_channel_mask_t)in->common.cfg.channel_mask;
-}
-
-static audio_format_t in_get_format(
- UNUSED_ATTR const struct audio_stream* stream) {
- FNLOG();
- return AUDIO_FORMAT_PCM_16_BIT;
-}
-
-static int in_set_format(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR audio_format_t format) {
- FNLOG();
- if (format == AUDIO_FORMAT_PCM_16_BIT)
- return 0;
- else
- return -1;
-}
-
-static int in_standby(UNUSED_ATTR struct audio_stream* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_dump(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR int fd) {
- FNLOG();
- return 0;
-}
-
-static int in_set_parameters(UNUSED_ATTR struct audio_stream* stream,
- UNUSED_ATTR const char* kvpairs) {
- FNLOG();
- return 0;
-}
-
-static char* in_get_parameters(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR const char* keys) {
- FNLOG();
- return strdup("");
-}
-
-static int in_set_gain(UNUSED_ATTR struct audio_stream_in* stream,
- UNUSED_ATTR float gain) {
- FNLOG();
- return 0;
-}
-
-static ssize_t in_read(struct audio_stream_in* stream, void* buffer,
- size_t bytes) {
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
- int read;
- int us_delay;
-
- DEBUG("read %zu bytes, state: %d", bytes, in->common.state);
-
- std::unique_lock<std::recursive_mutex> lock(*in->common.mutex);
- if (in->common.state == AUDIO_HA_STATE_SUSPENDED ||
- in->common.state == AUDIO_HA_STATE_STOPPING) {
- DEBUG("stream suspended");
- goto error;
- }
-
- /* only allow autostarting if we are in stopped or standby */
- if ((in->common.state == AUDIO_HA_STATE_STOPPED) ||
- (in->common.state == AUDIO_HA_STATE_STANDBY)) {
- if (start_audio_datapath(&in->common) < 0) {
- goto error;
- }
- } else if (in->common.state != AUDIO_HA_STATE_STARTED) {
- ERROR("stream not in stopped or standby");
- goto error;
- }
-
- lock.unlock();
- read = skt_read(in->common.audio_fd, buffer, bytes);
- lock.lock();
- if (read == -1) {
- skt_disconnect(in->common.audio_fd);
- in->common.audio_fd = AUDIO_SKT_DISCONNECTED;
- if ((in->common.state != AUDIO_HA_STATE_SUSPENDED) &&
- (in->common.state != AUDIO_HA_STATE_STOPPING)) {
- in->common.state = AUDIO_HA_STATE_STOPPED;
- } else {
- ERROR("read failed : stream suspended, avoid resetting state");
- }
- goto error;
- } else if (read == 0) {
- DEBUG("read time out - return zeros");
- memset(buffer, 0, bytes);
- read = bytes;
- }
- lock.unlock();
-
- DEBUG("read %d bytes out of %zu bytes", read, bytes);
- return read;
-
-error:
- memset(buffer, 0, bytes);
- us_delay = calc_audiotime_usec(in->common.cfg, bytes);
- DEBUG("emulate ha read delay (%d us)", us_delay);
-
- usleep(us_delay);
- return bytes;
-}
-
-static uint32_t in_get_input_frames_lost(
- UNUSED_ATTR struct audio_stream_in* stream) {
- FNLOG();
- return 0;
-}
-
-static int in_add_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
- return 0;
-}
-
-static int in_remove_audio_effect(UNUSED_ATTR const struct audio_stream* stream,
- UNUSED_ATTR effect_handle_t effect) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_open_output_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR audio_output_flags_t flags,
- struct audio_config* config,
- struct audio_stream_out** stream_out,
- UNUSED_ATTR const char* address)
-
-{
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_out* out;
- int ret = 0;
-
- INFO("opening output");
- // protect against adev->output and stream_out from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- out = (struct ha_stream_out*)calloc(1, sizeof(struct ha_stream_out));
-
- if (!out) return -ENOMEM;
-
- out->stream.common.get_sample_rate = out_get_sample_rate;
- out->stream.common.set_sample_rate = out_set_sample_rate;
- out->stream.common.get_buffer_size = out_get_buffer_size;
- out->stream.common.get_channels = out_get_channels;
- out->stream.common.get_format = out_get_format;
- out->stream.common.set_format = out_set_format;
- out->stream.common.standby = out_standby;
- out->stream.common.dump = out_dump;
- out->stream.common.set_parameters = out_set_parameters;
- out->stream.common.get_parameters = out_get_parameters;
- out->stream.common.add_audio_effect = out_add_audio_effect;
- out->stream.common.remove_audio_effect = out_remove_audio_effect;
- out->stream.get_latency = out_get_latency;
- out->stream.set_volume = out_set_volume;
- out->stream.write = out_write;
- out->stream.get_render_position = out_get_render_position;
- out->stream.get_presentation_position = out_get_presentation_position;
-
- /* initialize ha specifics */
- ha_stream_common_init(&out->common);
-
- // Make sure we always have the feeding parameters configured
- btav_a2dp_codec_config_t codec_config;
- btav_a2dp_codec_config_t codec_capability;
- if (ha_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("ha_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // ha_read_output_audio_config() opens the socket control path (or fails)
-
- /* set output config values */
- if (config != nullptr) {
- // Try to use the config parameters and send it to the remote side
- // TODO: Shall we use out_set_format() and similar?
- if (config->format != 0) out->common.cfg.format = config->format;
- if (config->sample_rate != 0) out->common.cfg.rate = config->sample_rate;
- if (config->channel_mask != 0)
- out->common.cfg.channel_mask = config->channel_mask;
- if ((out->common.cfg.format != 0) || (out->common.cfg.rate != 0) ||
- (out->common.cfg.channel_mask != 0)) {
- if (ha_write_output_audio_config(&out->common) < 0) {
- ERROR("ha_write_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- // Read again and make sure we use the same parameters as the remote side
- if (ha_read_output_audio_config(&out->common, &codec_config,
- &codec_capability,
- true /* update_stream_config */) < 0) {
- ERROR("ha_read_output_audio_config failed");
- ret = -1;
- goto err_open;
- }
- }
- config->format = out_get_format((const struct audio_stream*)&out->stream);
- config->sample_rate =
- out_get_sample_rate((const struct audio_stream*)&out->stream);
- config->channel_mask =
- out_get_channels((const struct audio_stream*)&out->stream);
-
- INFO(
- "Output stream config: format=0x%x sample_rate=%d channel_mask=0x%x "
- "buffer_sz=%zu",
- config->format, config->sample_rate, config->channel_mask,
- out->common.buffer_sz);
- }
- *stream_out = &out->stream;
- ha_dev->output = out;
-
- DEBUG("success");
- /* Delay to ensure Headset is in proper state when START is initiated from
- * DUT immediately after the connection due to ongoing music playback. */
- usleep(250000);
- return 0;
-
-err_open:
- ha_stream_common_destroy(&out->common);
- free(out);
- *stream_out = NULL;
- ha_dev->output = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_output_stream(struct audio_hw_device* dev,
- struct audio_stream_out* stream) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_out* out = (struct ha_stream_out*)stream;
-
- // prevent interference with adev_set_parameters.
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*out->common.mutex);
- const ha_state_t state = out->common.state;
- INFO("closing output (state %d)", (int)state);
- if ((state == AUDIO_HA_STATE_STARTED) ||
- (state == AUDIO_HA_STATE_STOPPING)) {
- stop_audio_datapath(&out->common);
- }
-
- skt_disconnect(out->common.ctrl_fd);
- out->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
-
- ha_stream_common_destroy(&out->common);
- free(stream);
- ha_dev->output = NULL;
-
- DEBUG("done");
-}
-
-static int adev_set_parameters(struct audio_hw_device* dev,
- const char* kvpairs) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- int retval = 0;
-
- // prevent interference with adev_close_output_stream
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- struct ha_stream_out* out = ha_dev->output;
-
- if (out == NULL) return retval;
-
- INFO("state %d", out->common.state);
-
- retval =
- out->stream.common.set_parameters((struct audio_stream*)out, kvpairs);
-
- return retval;
-}
-
-static char* adev_get_parameters(UNUSED_ATTR const struct audio_hw_device* dev,
- const char* keys) {
- FNLOG();
-
- std::unordered_map<std::string, std::string> params =
- hash_map_utils_new_from_string_params(keys);
- hash_map_utils_dump_string_keys_string_values(params);
-
- return strdup("");
-}
-
-static int adev_init_check(UNUSED_ATTR const struct audio_hw_device* dev) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_voice_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_master_volume(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR float volume) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_set_mode(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR audio_mode_t mode) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_set_mic_mute(UNUSED_ATTR struct audio_hw_device* dev,
- UNUSED_ATTR bool state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static int adev_get_mic_mute(UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR bool* state) {
- FNLOG();
-
- return -ENOSYS;
-}
-
-static size_t adev_get_input_buffer_size(
- UNUSED_ATTR const struct audio_hw_device* dev,
- UNUSED_ATTR const struct audio_config* config) {
- FNLOG();
-
- return 320;
-}
-
-static int adev_open_input_stream(struct audio_hw_device* dev,
- UNUSED_ATTR audio_io_handle_t handle,
- UNUSED_ATTR audio_devices_t devices,
- UNUSED_ATTR struct audio_config* config,
- struct audio_stream_in** stream_in,
- UNUSED_ATTR audio_input_flags_t flags,
- UNUSED_ATTR const char* address,
- UNUSED_ATTR audio_source_t source) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_in* in;
- int ret;
-
- FNLOG();
-
- // protect against adev->input and stream_in from being inconsistent
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- in = (struct ha_stream_in*)calloc(1, sizeof(struct ha_stream_in));
-
- if (!in) return -ENOMEM;
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- /* initialize ha specifics */
- ha_stream_common_init(&in->common);
-
- *stream_in = &in->stream;
- ha_dev->input = in;
-
- if (ha_read_input_audio_config(&in->common) < 0) {
- ERROR("ha_read_input_audio_config failed (%s)", strerror(errno));
- ret = -1;
- goto err_open;
- }
- // ha_read_input_audio_config() opens socket control path (or fails)
-
- DEBUG("success");
- return 0;
-
-err_open:
- ha_stream_common_destroy(&in->common);
- free(in);
- *stream_in = NULL;
- ha_dev->input = NULL;
- ERROR("failed");
- return ret;
-}
-
-static void adev_close_input_stream(struct audio_hw_device* dev,
- struct audio_stream_in* stream) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)dev;
- struct ha_stream_in* in = (struct ha_stream_in*)stream;
-
- std::lock_guard<std::recursive_mutex> lock(*ha_dev->mutex);
- {
- std::lock_guard<std::recursive_mutex> lock(*in->common.mutex);
- const ha_state_t state = in->common.state;
- INFO("closing input (state %d)", (int)state);
-
- if ((state == AUDIO_HA_STATE_STARTED) || (state == AUDIO_HA_STATE_STOPPING))
- stop_audio_datapath(&in->common);
-
- skt_disconnect(in->common.ctrl_fd);
- in->common.ctrl_fd = AUDIO_SKT_DISCONNECTED;
- }
- ha_stream_common_destroy(&in->common);
- free(stream);
- ha_dev->input = NULL;
-
- DEBUG("done");
-}
-
-static int adev_dump(UNUSED_ATTR const audio_hw_device_t* device,
- UNUSED_ATTR int fd) {
- FNLOG();
-
- return 0;
-}
-
-static int adev_close(hw_device_t* device) {
- struct ha_audio_device* ha_dev = (struct ha_audio_device*)device;
- FNLOG();
-
- delete ha_dev->mutex;
- ha_dev->mutex = nullptr;
- free(device);
- return 0;
-}
-
-static int adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device) {
- struct ha_audio_device* adev;
-
- INFO(" adev_open in ha_hw module");
- FNLOG();
-
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) {
- ERROR("interface %s not matching [%s]", name, AUDIO_HARDWARE_INTERFACE);
- return -EINVAL;
- }
-
- adev = (struct ha_audio_device*)calloc(1, sizeof(struct ha_audio_device));
-
- if (!adev) return -ENOMEM;
-
- adev->mutex = new std::recursive_mutex;
-
- adev->device.common.tag = HARDWARE_DEVICE_TAG;
- adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
- adev->device.common.module = (struct hw_module_t*)module;
- adev->device.common.close = adev_close;
-
- adev->device.init_check = adev_init_check;
- adev->device.set_voice_volume = adev_set_voice_volume;
- adev->device.set_master_volume = adev_set_master_volume;
- adev->device.set_mode = adev_set_mode;
- adev->device.set_mic_mute = adev_set_mic_mute;
- adev->device.get_mic_mute = adev_get_mic_mute;
- adev->device.set_parameters = adev_set_parameters;
- adev->device.get_parameters = adev_get_parameters;
- adev->device.get_input_buffer_size = adev_get_input_buffer_size;
- adev->device.open_output_stream = adev_open_output_stream;
- adev->device.close_output_stream = adev_close_output_stream;
- adev->device.open_input_stream = adev_open_input_stream;
- adev->device.close_input_stream = adev_close_input_stream;
- adev->device.dump = adev_dump;
-
- adev->output = NULL;
-
- *device = &adev->device.common;
-
- return 0;
-}
-
-static struct hw_module_methods_t hal_module_methods = {
- .open = adev_open,
-};
-
-__attribute__((
- visibility("default"))) struct audio_module HAL_MODULE_INFO_SYM = {
- .common =
- {
- .tag = HARDWARE_MODULE_TAG,
- .version_major = 1,
- .version_minor = 0,
- .id = AUDIO_HARDWARE_MODULE_ID,
- .name = "Hearing Aid Audio HW HAL",
- .author = "The Android Open Source Project",
- .methods = &hal_module_methods,
- },
-};
diff --git a/audio_hearing_aid_hw/src/audio_hearing_aid_hw_utils.cc b/audio_hearing_aid_hw/src/audio_hearing_aid_hw_utils.cc
deleted file mode 100644
index cb1eee7..0000000
--- a/audio_hearing_aid_hw/src/audio_hearing_aid_hw_utils.cc
+++ /dev/null
@@ -1,41 +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.
- *
- ******************************************************************************/
-
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-
-#define CASE_RETURN_STR(const) \
- case const: \
- return #const;
-
-const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event) {
- switch (event) {
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_NONE)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_CHECK_READY)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_START)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_STOP)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_SUSPEND)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_INPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG)
- CASE_RETURN_STR(HEARING_AID_CTRL_CMD_OFFLOAD_START)
- default:
- break;
- }
-
- return "UNKNOWN HEARING_AID_CTRL_CMD";
-}
diff --git a/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc b/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc
deleted file mode 100644
index c5d0e2b..0000000
--- a/audio_hearing_aid_hw/test/audio_hearing_aid_hw_test.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2017 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 <gtest/gtest.h>
-
-#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
-
-namespace {
-static uint32_t codec_sample_rate2value(
- btav_a2dp_codec_sample_rate_t codec_sample_rate) {
- switch (codec_sample_rate) {
- case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
- return 44100;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
- return 48000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
- return 88200;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
- return 96000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
- return 176400;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
- return 192000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
- return 16000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
- return 24000;
- case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_bits_per_sample2value(
- btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample) {
- switch (codec_bits_per_sample) {
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
- return 16;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
- return 24;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
- return 32;
- case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
- break;
- }
- return 0;
-}
-
-static uint32_t codec_channel_mode2value(
- btav_a2dp_codec_channel_mode_t codec_channel_mode) {
- switch (codec_channel_mode) {
- case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
- return 1;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
- return 2;
- case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
- break;
- }
- return 0;
-}
-
-} // namespace
-
-class AudioA2dpHwTest : public ::testing::Test {
- protected:
- AudioA2dpHwTest() {}
-
- private:
-};
-
-TEST_F(AudioA2dpHwTest, test_compute_buffer_size) {
- const btav_a2dp_codec_sample_rate_t codec_sample_rate_array[] = {
- BTAV_A2DP_CODEC_SAMPLE_RATE_NONE, BTAV_A2DP_CODEC_SAMPLE_RATE_44100,
- BTAV_A2DP_CODEC_SAMPLE_RATE_48000, BTAV_A2DP_CODEC_SAMPLE_RATE_88200,
- BTAV_A2DP_CODEC_SAMPLE_RATE_96000, BTAV_A2DP_CODEC_SAMPLE_RATE_176400,
- BTAV_A2DP_CODEC_SAMPLE_RATE_192000};
-
- const btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample_array[] = {
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16,
- BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24, BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32};
-
- const btav_a2dp_codec_channel_mode_t codec_channel_mode_array[] = {
- BTAV_A2DP_CODEC_CHANNEL_MODE_NONE, BTAV_A2DP_CODEC_CHANNEL_MODE_MONO,
- BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO};
-
- for (const auto codec_sample_rate : codec_sample_rate_array) {
- for (const auto codec_bits_per_sample : codec_bits_per_sample_array) {
- for (const auto codec_channel_mode : codec_channel_mode_array) {
- size_t buffer_size = audio_ha_hw_stream_compute_buffer_size(
- codec_sample_rate, codec_bits_per_sample, codec_channel_mode);
-
- // Check for invalid input
- if ((codec_sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) ||
- (codec_bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) ||
- (codec_channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE)) {
- EXPECT_EQ(buffer_size,
- static_cast<size_t>(AUDIO_STREAM_OUTPUT_BUFFER_SZ));
- continue;
- }
-
- uint32_t sample_rate = codec_sample_rate2value(codec_sample_rate);
- EXPECT_TRUE(sample_rate != 0);
-
- uint32_t bits_per_sample =
- codec_bits_per_sample2value(codec_bits_per_sample);
- EXPECT_TRUE(bits_per_sample != 0);
-
- uint32_t number_of_channels =
- codec_channel_mode2value(codec_channel_mode);
- EXPECT_TRUE(number_of_channels != 0);
-
- const uint64_t time_period_ms = 20; // TODO: Must be a parameter
- size_t expected_buffer_size =
- (time_period_ms * AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * sample_rate *
- number_of_channels * (bits_per_sample / 8)) /
- 1000;
-
- // Compute the divisor and adjust the buffer size
- const size_t divisor = (AUDIO_STREAM_OUTPUT_BUFFER_PERIODS * 16 *
- number_of_channels * bits_per_sample) /
- 8;
- const size_t remainder = expected_buffer_size % divisor;
- if (remainder != 0) {
- expected_buffer_size += divisor - remainder;
- }
-
- EXPECT_EQ(buffer_size, expected_buffer_size);
- }
- }
- }
-}
diff --git a/binder/Android.bp b/binder/Android.bp
deleted file mode 100644
index c5d6f6b..0000000
--- a/binder/Android.bp
+++ /dev/null
@@ -1,53 +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 "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-// AIDL interface between libbluetooth-binder and framework.jar
-filegroup {
- name: "libbluetooth-binder-aidl",
- srcs: [
- "android/bluetooth/IBluetooth.aidl",
- "android/bluetooth/IBluetoothA2dp.aidl",
- "android/bluetooth/IBluetoothA2dpSink.aidl",
- "android/bluetooth/IBluetoothAvrcpController.aidl",
- "android/bluetooth/IBluetoothAvrcpTarget.aidl",
- "android/bluetooth/IBluetoothCallback.aidl",
- "android/bluetooth/IBluetoothCsipSetCoordinator.aidl",
- "android/bluetooth/IBluetoothCsipSetCoordinatorCallback.aidl",
- "android/bluetooth/IBluetoothCsipSetCoordinatorLockCallback.aidl",
- "android/bluetooth/IBluetoothProfileServiceConnection.aidl",
- "android/bluetooth/IBluetoothHeadset.aidl",
- "android/bluetooth/IBluetoothHearingAid.aidl",
- "android/bluetooth/IBluetoothVolumeControl.aidl",
- "android/bluetooth/IBluetoothHidHost.aidl",
- "android/bluetooth/IBluetoothLeAudio.aidl",
- "android/bluetooth/IBluetoothPan.aidl",
- "android/bluetooth/IBluetoothManager.aidl",
- "android/bluetooth/IBluetoothManagerCallback.aidl",
- "android/bluetooth/IBluetoothMap.aidl",
- "android/bluetooth/IBluetoothMapClient.aidl",
- "android/bluetooth/IBluetoothMcpServiceManager.aidl",
- "android/bluetooth/IBluetoothPbap.aidl",
- "android/bluetooth/IBluetoothPbapClient.aidl",
- "android/bluetooth/IBluetoothSap.aidl",
- "android/bluetooth/IBluetoothSocketManager.aidl",
- "android/bluetooth/IBluetoothStateChangeCallback.aidl",
- "android/bluetooth/IBluetoothHeadsetClient.aidl",
- "android/bluetooth/IBluetoothHidDevice.aidl",
- "android/bluetooth/IBluetoothHidDeviceCallback.aidl",
- "android/bluetooth/IBluetoothGatt.aidl",
- "android/bluetooth/IBluetoothGattCallback.aidl",
- "android/bluetooth/IBluetoothMetadataListener.aidl",
- "android/bluetooth/IBluetoothGattServerCallback.aidl",
- "android/bluetooth/IBluetoothOobDataCallback.aidl",
- "android/bluetooth/le/IAdvertisingSetCallback.aidl",
- "android/bluetooth/le/IPeriodicAdvertisingCallback.aidl",
- "android/bluetooth/le/IScannerCallback.aidl",
- "android/bluetooth/IBluetoothConnectionCallback.aidl",
- ],
-}
diff --git a/binder/android/bluetooth/BluetoothActivityEnergyInfo.aidl b/binder/android/bluetooth/BluetoothActivityEnergyInfo.aidl
deleted file mode 100644
index 1410019..0000000
--- a/binder/android/bluetooth/BluetoothActivityEnergyInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2014 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.bluetooth;
-
-parcelable BluetoothActivityEnergyInfo;
diff --git a/binder/android/bluetooth/BluetoothAudioConfig.aidl b/binder/android/bluetooth/BluetoothAudioConfig.aidl
deleted file mode 100644
index 2ef113d..0000000
--- a/binder/android/bluetooth/BluetoothAudioConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2009 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.bluetooth;
-
-parcelable BluetoothAudioConfig;
diff --git a/binder/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl b/binder/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
deleted file mode 100644
index 41b8af6..0000000
--- a/binder/android/bluetooth/BluetoothAvrcpPlayerSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2015 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.bluetooth;
-
-parcelable BluetoothAvrcpPlayerSettings;
diff --git a/binder/android/bluetooth/BluetoothClass.aidl b/binder/android/bluetooth/BluetoothClass.aidl
deleted file mode 100644
index 8699b1e..0000000
--- a/binder/android/bluetooth/BluetoothClass.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2017, 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.bluetooth;
-
-parcelable BluetoothClass;
diff --git a/binder/android/bluetooth/BluetoothCodecConfig.aidl b/binder/android/bluetooth/BluetoothCodecConfig.aidl
deleted file mode 100644
index 5890637..0000000
--- a/binder/android/bluetooth/BluetoothCodecConfig.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2016 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.bluetooth;
-
-parcelable BluetoothCodecConfig;
diff --git a/binder/android/bluetooth/BluetoothCodecStatus.aidl b/binder/android/bluetooth/BluetoothCodecStatus.aidl
deleted file mode 100644
index f674db7..0000000
--- a/binder/android/bluetooth/BluetoothCodecStatus.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2017 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.bluetooth;
-
-parcelable BluetoothCodecStatus;
diff --git a/binder/android/bluetooth/BluetoothDevice.aidl b/binder/android/bluetooth/BluetoothDevice.aidl
deleted file mode 100644
index b9b0589..0000000
--- a/binder/android/bluetooth/BluetoothDevice.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2009 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.bluetooth;
-
-parcelable BluetoothDevice cpp_header "android/bluetooth/bluetooth_device.h";
diff --git a/binder/android/bluetooth/BluetoothGattCharacteristic.aidl b/binder/android/bluetooth/BluetoothGattCharacteristic.aidl
deleted file mode 100644
index 463b7a7..0000000
--- a/binder/android/bluetooth/BluetoothGattCharacteristic.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2016 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.bluetooth;
-
-parcelable BluetoothGattCharacteristic;
diff --git a/binder/android/bluetooth/BluetoothGattDescriptor.aidl b/binder/android/bluetooth/BluetoothGattDescriptor.aidl
deleted file mode 100644
index 6d4cdeb..0000000
--- a/binder/android/bluetooth/BluetoothGattDescriptor.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2016 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.bluetooth;
-
-parcelable BluetoothGattDescriptor;
diff --git a/binder/android/bluetooth/BluetoothGattIncludedService.aidl b/binder/android/bluetooth/BluetoothGattIncludedService.aidl
deleted file mode 100644
index d911973..0000000
--- a/binder/android/bluetooth/BluetoothGattIncludedService.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2016 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.bluetooth;
-
-parcelable BluetoothGattIncludedService;
diff --git a/binder/android/bluetooth/BluetoothGattService.aidl b/binder/android/bluetooth/BluetoothGattService.aidl
deleted file mode 100644
index 8e72ba9..0000000
--- a/binder/android/bluetooth/BluetoothGattService.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2016 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.bluetooth;
-
-parcelable BluetoothGattService;
diff --git a/binder/android/bluetooth/BluetoothHeadsetClientCall.aidl b/binder/android/bluetooth/BluetoothHeadsetClientCall.aidl
deleted file mode 100644
index 5403d51..0000000
--- a/binder/android/bluetooth/BluetoothHeadsetClientCall.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2014 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.bluetooth;
-
-parcelable BluetoothHeadsetClientCall;
diff --git a/binder/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl b/binder/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl
deleted file mode 100644
index 14f9114..0000000
--- a/binder/android/bluetooth/BluetoothHidDeviceAppQosSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-** Copyright 2016, 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.bluetooth;
-
-parcelable BluetoothHidDeviceAppQosSettings;
diff --git a/binder/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl b/binder/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl
deleted file mode 100644
index 87dd10e..0000000
--- a/binder/android/bluetooth/BluetoothHidDeviceAppSdpSettings.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-** Copyright 2016, 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.bluetooth;
-
-parcelable BluetoothHidDeviceAppSdpSettings;
diff --git a/binder/android/bluetooth/BufferConstraints.aidl b/binder/android/bluetooth/BufferConstraints.aidl
deleted file mode 100644
index 751f5ac..0000000
--- a/binder/android/bluetooth/BufferConstraints.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.bluetooth;
-
-parcelable BufferConstraints;
diff --git a/binder/android/bluetooth/IBluetooth.aidl b/binder/android/bluetooth/IBluetooth.aidl
deleted file mode 100644
index 3e78f5b..0000000
--- a/binder/android/bluetooth/IBluetooth.aidl
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright 2008, 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.bluetooth;
-
-import android.bluetooth.IBluetoothCallback;
-import android.bluetooth.IBluetoothConnectionCallback;
-import android.bluetooth.IBluetoothMetadataListener;
-import android.bluetooth.IBluetoothOobDataCallback;
-import android.bluetooth.IBluetoothSocketManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-import android.bluetooth.BluetoothActivityEnergyInfo;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.OobData;
-import android.content.AttributionSource;
-import android.os.ParcelUuid;
-import android.os.ParcelFileDescriptor;
-import android.os.ResultReceiver;
-
-/**
- * System private API for talking with the Bluetooth service.
- *
- * {@hide}
- */
-interface IBluetooth
-{
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getState();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean enable(boolean quietMode, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean disable(in AttributionSource attributionSource);
-
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.LOCAL_MAC_ADDRESS})")
- String getAddress();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.LOCAL_MAC_ADDRESS})")
- String getAddressWithAttribution(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- ParcelUuid[] getUuids(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setName(in String name, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getName(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)")
- int getNameLengthForAdvertise(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothClass getBluetoothClass(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setBluetoothClass(in BluetoothClass bluetoothClass, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getIoCapability(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setIoCapability(int capability, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getLeIoCapability(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setLeIoCapability(int capability, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- int getScanMode(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean setScanMode(int mode, int duration, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- int getDiscoverableTimeout(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean setDiscoverableTimeout(int timeout, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean startDiscovery(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean cancelDiscovery(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
- boolean isDiscovering(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- long getDiscoveryEndMillis(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getAdapterConnectionState();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getProfileConnectionState(int profile);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- BluetoothDevice[] getBondedDevices(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean createBond(in BluetoothDevice device, in int transport, in OobData p192Data, in OobData p256Data, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean cancelBondProcess(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean removeBond(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getBondState(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean isBondingInitiatedLocally(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- long getSupportedProfiles();
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionState(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getConnectionStateWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getRemoteName(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getRemoteType(in BluetoothDevice device, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getRemoteAlias(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- String getRemoteAliasWithAttribution(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int setRemoteAlias(in BluetoothDevice device, in String name, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getRemoteClass(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- ParcelUuid[] getRemoteUuids(in BluetoothDevice device, in AttributionSource attributionSource);
- @UnsupportedAppUsage
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean fetchRemoteUuids(in BluetoothDevice device);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean fetchRemoteUuidsWithAttribution(in BluetoothDevice device, in int transport, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean sdpSearch(in BluetoothDevice device, in ParcelUuid uuid, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getBatteryLevel(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getMaxConnectedAudioDevices(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[] passkey, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setPairingConfirmation(in BluetoothDevice device, boolean accept, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getPhonebookAccessPermission(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setSilenceMode(in BluetoothDevice device, boolean silence, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean getSilenceMode(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setPhonebookAccessPermission(in BluetoothDevice device, int value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getMessageAccessPermission(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setMessageAccessPermission(in BluetoothDevice device, int value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- int getSimAccessPermission(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setSimAccessPermission(in BluetoothDevice device, int value, in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void registerCallback(in IBluetoothCallback callback, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- void unregisterCallback(in IBluetoothCallback callback, in AttributionSource attributionSource);
-
- // For Socket
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- IBluetoothSocketManager getSocketManager();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean factoryReset(in AttributionSource attributionSource);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isMultiAdvertisementSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isOffloadedFilteringSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isOffloadedScanBatchingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isActivityAndEnergyReportingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLe2MPhySupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLeCodedPhySupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLeExtendedAdvertisingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- boolean isLePeriodicAdvertisingSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int isCisCentralSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int isLePeriodicAdvertisingSyncTransferSenderSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
- int getLeMaximumAdvertisingDataLength();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- BluetoothActivityEnergyInfo reportActivityInfo(in AttributionSource attributionSource);
-
- // For Metadata
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean registerMetadataListener(in IBluetoothMetadataListener listener, in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean unregisterMetadataListener(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- boolean setMetadata(in BluetoothDevice device, in int key, in byte[] value, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- byte[] getMetadata(in BluetoothDevice device, in int key, in AttributionSource attributionSource);
-
- /**
- * Requests the controller activity info asynchronously.
- * The implementor is expected to reply with the
- * {@link android.bluetooth.BluetoothActivityEnergyInfo} object placed into the Bundle with the
- * key {@link android.os.BatteryStats#RESULT_RECEIVER_CONTROLLER_KEY}.
- * The result code is ignored.
- */
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- oneway void requestActivityInfo(in ResultReceiver result, in AttributionSource attributionSou