Merge changes from topic "ps 2.0 cp"
* changes:
Add power.stats to compatibility matrix
power/stats: Rename readEnergyMeters to readEnergyMeter
power/stats: Add VTS tests for power stats hal
Specify version for aidl_interface explicitly
power/stats: Adding subsystem field to Channel
power/stats: Add EnergyConsumer types
power/stats: Add EnergyConsumerAttribution interface
power/stats: Add duration field to EnergyMeasurement
power/stats: Rename PowerStats HAL
power/stats: Move PowerStats HAL 2.0 to power/stats
diff --git a/audio/5.0/config/api/current.txt b/audio/5.0/config/api/current.txt
index 8458a56..dbb5d3b 100644
--- a/audio/5.0/config/api/current.txt
+++ b/audio/5.0/config/api/current.txt
@@ -199,7 +199,7 @@
public static class DevicePorts.DevicePort {
ctor public DevicePorts.DevicePort();
method public String getAddress();
- method public java.util.List<audio.policy.configuration.V5_0.AudioFormat> getEncodedFormats();
+ method public java.util.List<java.lang.String> getEncodedFormats();
method public audio.policy.configuration.V5_0.Gains getGains();
method public java.util.List<audio.policy.configuration.V5_0.Profile> getProfile();
method public audio.policy.configuration.V5_0.Role getRole();
@@ -207,7 +207,7 @@
method public String getType();
method public boolean get_default();
method public void setAddress(String);
- method public void setEncodedFormats(java.util.List<audio.policy.configuration.V5_0.AudioFormat>);
+ method public void setEncodedFormats(java.util.List<java.lang.String>);
method public void setGains(audio.policy.configuration.V5_0.Gains);
method public void setRole(audio.policy.configuration.V5_0.Role);
method public void setTagName(String);
@@ -380,10 +380,10 @@
public static class SurroundFormats.Format {
ctor public SurroundFormats.Format();
- method public audio.policy.configuration.V5_0.AudioFormat getName();
- method public java.util.List<audio.policy.configuration.V5_0.AudioFormat> getSubformats();
- method public void setName(audio.policy.configuration.V5_0.AudioFormat);
- method public void setSubformats(java.util.List<audio.policy.configuration.V5_0.AudioFormat>);
+ method public String getName();
+ method public java.util.List<java.lang.String> getSubformats();
+ method public void setName(String);
+ method public void setSubformats(java.util.List<java.lang.String>);
}
public class SurroundSound {
diff --git a/audio/5.0/config/audio_policy_configuration.xsd b/audio/5.0/config/audio_policy_configuration.xsd
index b0d1e20..f92136c 100644
--- a/audio/5.0/config/audio_policy_configuration.xsd
+++ b/audio/5.0/config/audio_policy_configuration.xsd
@@ -611,13 +611,13 @@
</xs:sequence>
</xs:complexType>
<xs:simpleType name="audioFormatsList">
- <xs:list itemType="audioFormat" />
+ <xs:list itemType="extendableAudioFormat" />
</xs:simpleType>
<xs:complexType name="surroundFormats">
<xs:sequence>
<xs:element name="format" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
- <xs:attribute name="name" type="audioFormat" use="required"/>
+ <xs:attribute name="name" type="extendableAudioFormat" use="required"/>
<xs:attribute name="subformats" type="audioFormatsList" />
</xs:complexType>
</xs:element>
diff --git a/audio/6.0/config/api/current.txt b/audio/6.0/config/api/current.txt
index f5d4798..01db90e 100644
--- a/audio/6.0/config/api/current.txt
+++ b/audio/6.0/config/api/current.txt
@@ -199,7 +199,7 @@
public static class DevicePorts.DevicePort {
ctor public DevicePorts.DevicePort();
method public String getAddress();
- method public java.util.List<audio.policy.configuration.V6_0.AudioFormat> getEncodedFormats();
+ method public java.util.List<java.lang.String> getEncodedFormats();
method public audio.policy.configuration.V6_0.Gains getGains();
method public java.util.List<audio.policy.configuration.V6_0.Profile> getProfile();
method public audio.policy.configuration.V6_0.Role getRole();
@@ -207,7 +207,7 @@
method public String getType();
method public boolean get_default();
method public void setAddress(String);
- method public void setEncodedFormats(java.util.List<audio.policy.configuration.V6_0.AudioFormat>);
+ method public void setEncodedFormats(java.util.List<java.lang.String>);
method public void setGains(audio.policy.configuration.V6_0.Gains);
method public void setRole(audio.policy.configuration.V6_0.Role);
method public void setTagName(String);
@@ -391,10 +391,10 @@
public static class SurroundFormats.Format {
ctor public SurroundFormats.Format();
- method public audio.policy.configuration.V6_0.AudioFormat getName();
- method public java.util.List<audio.policy.configuration.V6_0.AudioFormat> getSubformats();
- method public void setName(audio.policy.configuration.V6_0.AudioFormat);
- method public void setSubformats(java.util.List<audio.policy.configuration.V6_0.AudioFormat>);
+ method public String getName();
+ method public java.util.List<java.lang.String> getSubformats();
+ method public void setName(String);
+ method public void setSubformats(java.util.List<java.lang.String>);
}
public class SurroundSound {
diff --git a/audio/6.0/config/audio_policy_configuration.xsd b/audio/6.0/config/audio_policy_configuration.xsd
index ead1cc2..c2b8c5d 100644
--- a/audio/6.0/config/audio_policy_configuration.xsd
+++ b/audio/6.0/config/audio_policy_configuration.xsd
@@ -614,13 +614,13 @@
</xs:sequence>
</xs:complexType>
<xs:simpleType name="audioFormatsList">
- <xs:list itemType="audioFormat" />
+ <xs:list itemType="extendableAudioFormat" />
</xs:simpleType>
<xs:complexType name="surroundFormats">
<xs:sequence>
<xs:element name="format" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
- <xs:attribute name="name" type="audioFormat" use="required"/>
+ <xs:attribute name="name" type="extendableAudioFormat" use="required"/>
<xs:attribute name="subformats" type="audioFormatsList" />
</xs:complexType>
</xs:element>
diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt
index c1940e5..48093c5 100644
--- a/audio/7.0/config/api/current.txt
+++ b/audio/7.0/config/api/current.txt
@@ -212,6 +212,7 @@
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_FLAC;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
+ enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC60958;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_IEC61937;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LC3;
enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_LDAC;
@@ -544,7 +545,7 @@
public enum Version {
method @NonNull public String getRawName();
- enum_constant public static final android.audio.policy.configuration.V7_0.Version _1_0;
+ enum_constant public static final android.audio.policy.configuration.V7_0.Version _7_0;
}
public class Volume {
diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd
index 4d224c8..531572b 100644
--- a/audio/7.0/config/audio_policy_configuration.xsd
+++ b/audio/7.0/config/audio_policy_configuration.xsd
@@ -20,7 +20,7 @@
<!-- List the config versions supported by audio policy. -->
<xs:simpleType name="version">
<xs:restriction base="xs:decimal">
- <xs:enumeration value="1.0"/>
+ <xs:enumeration value="7.0"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="halVersion">
@@ -406,6 +406,7 @@
<xs:enumeration value="AUDIO_FORMAT_MPEGH_BL_L4"/>
<xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L3"/>
<xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L4"/>
+ <xs:enumeration value="AUDIO_FORMAT_IEC60958"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extendableAudioFormat">
diff --git a/audio/7.0/config/update_audio_policy_config.sh b/audio/7.0/config/update_audio_policy_config.sh
index 051a0df..159fa35 100755
--- a/audio/7.0/config/update_audio_policy_config.sh
+++ b/audio/7.0/config/update_audio_policy_config.sh
@@ -113,6 +113,9 @@
echo "Press Ctrl-C to cancel, Enter to continue"
read
+# Update 'audioPolicyConfiguration version="1.0"' -> 7.0 in the main file
+sed -i -r -e 's/(audioPolicyConfiguration version=")1.0/\17.0/' ${SOURCE_CONFIG}
+
updateFile() {
FILE=$1
ATTR=$2
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index 710ddce..bbc14ad 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -63,17 +63,17 @@
const std::vector<InterfacesList> mandatoryInterfaces = {
{
"Audio Core API",
+ "android.hardware.audio@7.0::IDevicesFactory",
"android.hardware.audio@6.0::IDevicesFactory",
"android.hardware.audio@5.0::IDevicesFactory",
"android.hardware.audio@4.0::IDevicesFactory",
- "android.hardware.audio@2.0::IDevicesFactory"
},
{
"Audio Effect API",
+ "android.hardware.audio.effect@7.0::IEffectsFactory",
"android.hardware.audio.effect@6.0::IEffectsFactory",
"android.hardware.audio.effect@5.0::IEffectsFactory",
"android.hardware.audio.effect@4.0::IEffectsFactory",
- "android.hardware.audio.effect@2.0::IEffectsFactory",
}
};
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index bb7c6d3..f87e5ed 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -322,9 +322,9 @@
const SourceMetadata metadata = {
{{toString(usage),
toString(content),
- {} /* tags */,
+ volume,
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
- volume}}};
+ {} /* tags */}}};
ASSERT_RESULT(okOrNotSupported, stream->updateSourceMetadata(metadata))
<< "usage=" << toString(usage) << ", content=" << toString(content)
<< ", volume=" << volume;
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 2b9e336..61e99e8 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -928,9 +928,9 @@
const SourceMetadata initMetadata = {
{ { toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_MUSIC),
- {},
+ 1 /* gain */,
toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO),
- 1 /* gain */ } }};
+ {} } }};
#endif
};
TEST_P(OutputStreamTest, OpenOutputStreamTest) {
diff --git a/bluetooth/audio/2.0/default/Android.bp b/bluetooth/audio/2.0/default/Android.bp
index 0db0028..8ed631e 100644
--- a/bluetooth/audio/2.0/default/Android.bp
+++ b/bluetooth/audio/2.0/default/Android.bp
@@ -23,24 +23,3 @@
"libutils",
],
}
-
-cc_library_shared {
- name: "libbluetooth_audio_session",
- defaults: ["hidl_defaults"],
- vendor: true,
- srcs: [
- "session/BluetoothAudioSession.cpp",
- "session/BluetoothAudioSupportedCodecsDB.cpp",
- ],
- export_include_dirs: ["session/"],
- header_libs: ["libhardware_headers"],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "libbase",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
-}
diff --git a/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.cpp
index b4a61b6..3fe1a4d 100644
--- a/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.1/default/A2dpOffloadAudioProvider.cpp
@@ -22,8 +22,8 @@
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
-#include "BluetoothAudioSessionReport.h"
-#include "BluetoothAudioSupportedCodecsDB.h"
+#include "BluetoothAudioSessionReport_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
namespace android {
namespace hardware {
@@ -32,7 +32,7 @@
namespace V2_1 {
namespace implementation {
-using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1;
using ::android::hardware::kSynchronizedReadWrite;
using ::android::hardware::MessageQueue;
using ::android::hardware::Void;
@@ -81,8 +81,8 @@
Return<void> A2dpOffloadAudioProvider::onSessionReady(
startSession_cb _hidl_cb) {
- BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
- nullptr, audio_config_);
+ BluetoothAudioSessionReport_2_1::OnSessionStarted(session_type_, stack_iface_,
+ nullptr, audio_config_);
_hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor());
return Void();
}
diff --git a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
index a67c341..a37176b 100644
--- a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
@@ -20,8 +20,8 @@
#include <android-base/logging.h>
-#include "BluetoothAudioSessionReport.h"
-#include "BluetoothAudioSupportedCodecsDB.h"
+#include "BluetoothAudioSessionReport_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
namespace android {
namespace hardware {
@@ -30,7 +30,7 @@
namespace V2_1 {
namespace implementation {
-using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1;
using ::android::hardware::Void;
using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
@@ -96,7 +96,7 @@
Return<void> A2dpSoftwareAudioProvider::onSessionReady(
startSession_cb _hidl_cb) {
if (mDataMQ && mDataMQ->isValid()) {
- BluetoothAudioSessionReport::OnSessionStarted(
+ BluetoothAudioSessionReport_2_1::OnSessionStarted(
session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
_hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
} else {
diff --git a/bluetooth/audio/2.1/default/Android.bp b/bluetooth/audio/2.1/default/Android.bp
index 5381fec..c05aa3f 100644
--- a/bluetooth/audio/2.1/default/Android.bp
+++ b/bluetooth/audio/2.1/default/Android.bp
@@ -16,29 +16,7 @@
"android.hardware.bluetooth.audio@2.0",
"android.hardware.bluetooth.audio@2.1",
"libbase",
- "libbluetooth_audio_session_2_1",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
-}
-
-cc_library_shared {
- name: "libbluetooth_audio_session_2_1",
- defaults: ["hidl_defaults"],
- vendor: true,
- srcs: [
- "session/BluetoothAudioSession.cpp",
- "session/BluetoothAudioSupportedCodecsDB.cpp",
- ],
- export_include_dirs: ["session/"],
- header_libs: ["libhardware_headers"],
- shared_libs: [
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth.audio@2.1",
- "libbase",
+ "libbluetooth_audio_session",
"libcutils",
"libfmq",
"libhidlbase",
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvider.cpp
index 73fe06c..38889ae 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvider.cpp
@@ -20,8 +20,8 @@
#include <android-base/logging.h>
-#include "BluetoothAudioSessionReport.h"
-#include "BluetoothAudioSupportedCodecsDB.h"
+#include "BluetoothAudioSessionReport_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
namespace android {
namespace hardware {
@@ -30,7 +30,7 @@
namespace V2_1 {
namespace implementation {
-using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1;
using ::android::hardware::kSynchronizedReadWrite;
using ::android::hardware::MessageQueue;
using ::android::hardware::Void;
@@ -105,8 +105,8 @@
* HAL server should start the streaming on data path.
*/
if (stack_iface_) {
- BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
- status);
+ BluetoothAudioSessionReport_2_1::ReportControlStatus(session_type_, true,
+ status);
} else {
LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
<< ", status=" << toString(status) << " has NO session";
@@ -125,8 +125,8 @@
* HAL server should suspend the streaming on data path.
*/
if (stack_iface_) {
- BluetoothAudioSessionReport::ReportControlStatus(session_type_, false,
- status);
+ BluetoothAudioSessionReport_2_1::ReportControlStatus(session_type_, false,
+ status);
} else {
LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
<< ", status=" << toString(status) << " has NO session";
@@ -139,7 +139,7 @@
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
if (stack_iface_) {
- BluetoothAudioSessionReport::OnSessionEnded(session_type_);
+ BluetoothAudioSessionReport_2_1::OnSessionEnded(session_type_);
stack_iface_->unlinkToDeath(death_recipient_);
} else {
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
index adf2717..e1b1ac6 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
@@ -20,7 +20,7 @@
#include <android-base/logging.h>
-#include "BluetoothAudioSupportedCodecsDB.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
namespace android {
namespace hardware {
diff --git a/bluetooth/audio/2.1/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.1/default/HearingAidAudioProvider.cpp
index aded7e1..712bd4f 100644
--- a/bluetooth/audio/2.1/default/HearingAidAudioProvider.cpp
+++ b/bluetooth/audio/2.1/default/HearingAidAudioProvider.cpp
@@ -20,8 +20,8 @@
#include <android-base/logging.h>
-#include "BluetoothAudioSessionReport.h"
-#include "BluetoothAudioSupportedCodecsDB.h"
+#include "BluetoothAudioSessionReport_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
namespace android {
namespace hardware {
@@ -30,7 +30,7 @@
namespace V2_1 {
namespace implementation {
-using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1;
using ::android::hardware::Void;
using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
@@ -95,7 +95,7 @@
Return<void> HearingAidAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
if (mDataMQ && mDataMQ->isValid()) {
- BluetoothAudioSessionReport::OnSessionStarted(
+ BluetoothAudioSessionReport_2_1::OnSessionStarted(
session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
_hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
} else {
diff --git a/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
index 9c2b4fe..2ebf6c5 100644
--- a/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
+++ b/bluetooth/audio/2.1/default/LeAudioAudioProvider.cpp
@@ -21,8 +21,8 @@
#include <android-base/logging.h>
-#include "BluetoothAudioSessionReport.h"
-#include "BluetoothAudioSupportedCodecsDB.h"
+#include "BluetoothAudioSessionReport_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
namespace android {
namespace hardware {
@@ -31,7 +31,7 @@
namespace V2_1 {
namespace implementation {
-using ::android::bluetooth::audio::BluetoothAudioSessionReport;
+using ::android::bluetooth::audio::BluetoothAudioSessionReport_2_1;
using ::android::hardware::Void;
using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
@@ -179,7 +179,7 @@
Return<void> LeAudioAudioProvider::onSessionReady(startSession_cb _hidl_cb) {
if (mDataMQ && mDataMQ->isValid()) {
- BluetoothAudioSessionReport::OnSessionStarted(
+ BluetoothAudioSessionReport_2_1::OnSessionStarted(
session_type_, stack_iface_, mDataMQ->getDesc(), audio_config_);
_hidl_cb(BluetoothAudioStatus::SUCCESS, *mDataMQ->getDesc());
} else {
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSession.cpp b/bluetooth/audio/2.1/default/session/BluetoothAudioSession.cpp
deleted file mode 100644
index ea2c54a..0000000
--- a/bluetooth/audio/2.1/default/session/BluetoothAudioSession.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderSession"
-
-#include "BluetoothAudioSession.h"
-
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::audio::common::V5_0::AudioContentType;
-using ::android::hardware::audio::common::V5_0::AudioUsage;
-using ::android::hardware::audio::common::V5_0::PlaybackTrackMetadata;
-using ::android::hardware::audio::common::V5_0::SourceMetadata;
-using ::android::hardware::bluetooth::audio::V2_0::CodecType;
-using ::android::hardware::bluetooth::audio::V2_0::TimeSpec;
-
-const CodecConfiguration BluetoothAudioSession::kInvalidCodecConfiguration = {
- .codecType = CodecType::UNKNOWN,
- .encodedAudioBitrate = 0x00000000,
- .peerMtu = 0xffff,
- .isScmstEnabled = false,
- .config = {}};
-AudioConfiguration BluetoothAudioSession::invalidSoftwareAudioConfiguration =
- {};
-AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {};
-
-static constexpr int kFmqSendTimeoutMs = 1000; // 1000 ms timeout for sending
-static constexpr int kFmqReceiveTimeoutMs =
- 1000; // 1000 ms timeout for receiving
-static constexpr int kWritePollMs = 1; // polled non-blocking interval
-static constexpr int kReadPollMs = 1; // polled non-blocking interval
-
-static inline timespec timespec_convert_from_hal(const TimeSpec& TS) {
- return {.tv_sec = static_cast<long>(TS.tvSec),
- .tv_nsec = static_cast<long>(TS.tvNSec)};
-}
-
-BluetoothAudioSession::BluetoothAudioSession(const SessionType& session_type)
- : session_type_(session_type), stack_iface_(nullptr), mDataMQ(nullptr) {
- invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters);
- invalidOffloadAudioConfiguration.codecConfig(kInvalidCodecConfiguration);
-}
-
-// The report function is used to report that the Bluetooth stack has started
-// this session without any failure, and will invoke session_changed_cb_ to
-// notify those registered bluetooth_audio outputs
-void BluetoothAudioSession::OnSessionStarted(
- const sp<IBluetoothAudioPort> stack_iface, const DataMQ::Descriptor* dataMQ,
- const AudioConfiguration& audio_config) {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (stack_iface == nullptr) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
- << ", IBluetoothAudioPort Invalid";
- } else if (!UpdateAudioConfig(audio_config)) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
- << ", AudioConfiguration=" << toString(audio_config)
- << " Invalid";
- } else if (!UpdateDataPath(dataMQ)) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
- << " DataMQ Invalid";
- audio_config_ =
- (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH
- ? kInvalidOffloadAudioConfiguration
- : kInvalidSoftwareAudioConfiguration);
- } else {
- stack_iface_ = stack_iface;
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << ", AudioConfiguration=" << toString(audio_config);
- ReportSessionStatus();
- }
-}
-
-// The report function is used to report that the Bluetooth stack has ended the
-// session, and will invoke session_changed_cb_ to notify registered
-// bluetooth_audio outputs
-void BluetoothAudioSession::OnSessionEnded() {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- bool toggled = IsSessionReady();
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
- audio_config_ = (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH
- ? kInvalidOffloadAudioConfiguration
- : kInvalidSoftwareAudioConfiguration);
- stack_iface_ = nullptr;
- UpdateDataPath(nullptr);
- if (toggled) {
- ReportSessionStatus();
- }
-}
-
-// invoking the registered session_changed_cb_
-void BluetoothAudioSession::ReportSessionStatus() {
- // This is locked already by OnSessionStarted / OnSessionEnded
- if (observers_.empty()) {
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO port state observer";
- return;
- }
- for (auto& observer : observers_) {
- uint16_t cookie = observer.first;
- std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
- << " notify to bluetooth_audio=0x"
- << android::base::StringPrintf("%04x", cookie);
- cb->session_changed_cb_(cookie);
- }
-}
-
-// The report function is used to report that the Bluetooth stack has notified
-// the result of startStream or suspendStream, and will invoke
-// control_result_cb_ to notify registered bluetooth_audio outputs
-void BluetoothAudioSession::ReportControlStatus(
- bool start_resp, const BluetoothAudioStatus& status) {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (observers_.empty()) {
- LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO port state observer";
- return;
- }
- for (auto& observer : observers_) {
- uint16_t cookie = observer.first;
- std::shared_ptr<struct PortStatusCallbacks> cb = observer.second;
- LOG(INFO) << __func__ << " - status=" << toString(status)
- << " for SessionType=" << toString(session_type_)
- << ", bluetooth_audio=0x"
- << android::base::StringPrintf("%04x", cookie)
- << (start_resp ? " started" : " suspended");
- cb->control_result_cb_(cookie, start_resp, status);
- }
-}
-
-// The function helps to check if this session is ready or not
-// @return: true if the Bluetooth stack has started the specified session
-bool BluetoothAudioSession::IsSessionReady() {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- bool dataMQ_valid =
- (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH ||
- (mDataMQ != nullptr && mDataMQ->isValid()));
- return stack_iface_ != nullptr && dataMQ_valid;
-}
-
-bool BluetoothAudioSession::UpdateDataPath(const DataMQ::Descriptor* dataMQ) {
- if (dataMQ == nullptr) {
- // usecase of reset by nullptr
- mDataMQ = nullptr;
- return true;
- }
- std::unique_ptr<DataMQ> tempDataMQ;
- tempDataMQ.reset(new DataMQ(*dataMQ));
- if (!tempDataMQ || !tempDataMQ->isValid()) {
- mDataMQ = nullptr;
- return false;
- }
- mDataMQ = std::move(tempDataMQ);
- return true;
-}
-
-bool BluetoothAudioSession::UpdateAudioConfig(
- const AudioConfiguration& audio_config) {
- bool is_software_session =
- (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
- session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
- session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
- bool is_offload_session =
- (session_type_ == 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;
- }
- audio_config_ = audio_config;
- return true;
-}
-
-// The control function helps the bluetooth_audio module to register
-// PortStatusCallbacks
-// @return: cookie - the assigned number to this bluetooth_audio output
-uint16_t BluetoothAudioSession::RegisterStatusCback(
- const PortStatusCallbacks& cbacks) {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- uint16_t cookie = ObserversCookieGetInitValue(session_type_);
- uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_);
-
- while (cookie < cookie_upper_bound) {
- if (observers_.find(cookie) == observers_.end()) {
- break;
- }
- ++cookie;
- }
- if (cookie >= cookie_upper_bound) {
- LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_)
- << " has " << observers_.size()
- << " observers already (No Resource)";
- return kObserversCookieUndefined;
- }
- std::shared_ptr<struct PortStatusCallbacks> cb =
- std::make_shared<struct PortStatusCallbacks>();
- *cb = cbacks;
- observers_[cookie] = cb;
- return cookie;
-}
-
-// The control function helps the bluetooth_audio module to unregister
-// PortStatusCallbacks
-// @param: cookie - indicates which bluetooth_audio output is
-void BluetoothAudioSession::UnregisterStatusCback(uint16_t cookie) {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (observers_.erase(cookie) != 1) {
- LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
- << " no such provider=0x"
- << android::base::StringPrintf("%04x", cookie);
- }
-}
-
-// The control function is for the bluetooth_audio module to get the current
-// AudioConfiguration
-const AudioConfiguration& BluetoothAudioSession::GetAudioConfig() {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (IsSessionReady()) {
- return audio_config_;
- } else if (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return kInvalidOffloadAudioConfiguration;
- } else {
- return kInvalidSoftwareAudioConfiguration;
- }
-}
-
-// Those control functions are for the bluetooth_audio module to start, suspend,
-// stop stream, to check position, and to update metadata.
-bool BluetoothAudioSession::StartStream() {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- return false;
- }
- auto hal_retval = stack_iface_->startStream();
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_) << " failed";
- return false;
- }
- return true;
-}
-
-bool BluetoothAudioSession::SuspendStream() {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- return false;
- }
- auto hal_retval = stack_iface_->suspendStream();
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_) << " failed";
- return false;
- }
- return true;
-}
-
-void BluetoothAudioSession::StopStream() {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (!IsSessionReady()) {
- return;
- }
- auto hal_retval = stack_iface_->stopStream();
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_) << " failed";
- }
-}
-
-bool BluetoothAudioSession::GetPresentationPosition(
- uint64_t* remote_delay_report_ns, uint64_t* total_bytes_readed,
- timespec* data_position) {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- return false;
- }
- bool retval = false;
- auto hal_retval = stack_iface_->getPresentationPosition(
- [&retval, &remote_delay_report_ns, &total_bytes_readed, &data_position](
- BluetoothAudioStatus status,
- const uint64_t& remoteDeviceAudioDelayNanos,
- uint64_t transmittedOctets,
- const TimeSpec& transmittedOctetsTimeStamp) {
- if (status == BluetoothAudioStatus::SUCCESS) {
- if (remote_delay_report_ns)
- *remote_delay_report_ns = remoteDeviceAudioDelayNanos;
- if (total_bytes_readed) *total_bytes_readed = transmittedOctets;
- if (data_position)
- *data_position =
- timespec_convert_from_hal(transmittedOctetsTimeStamp);
- retval = true;
- }
- });
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_) << " failed";
- return false;
- }
- return retval;
-}
-
-void BluetoothAudioSession::UpdateTracksMetadata(
- const struct source_metadata* source_metadata) {
- std::lock_guard<std::recursive_mutex> guard(mutex_);
- if (!IsSessionReady()) {
- LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_)
- << " has NO session";
- return;
- }
-
- ssize_t track_count = source_metadata->track_count;
- LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ", "
- << track_count << " track(s)";
- if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
- session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return;
- }
-
- struct playback_track_metadata* track = source_metadata->tracks;
- SourceMetadata sourceMetadata;
- PlaybackTrackMetadata* halMetadata;
-
- sourceMetadata.tracks.resize(track_count);
- halMetadata = sourceMetadata.tracks.data();
- while (track_count && track) {
- halMetadata->usage = static_cast<AudioUsage>(track->usage);
- halMetadata->contentType =
- static_cast<AudioContentType>(track->content_type);
- halMetadata->gain = track->gain;
- LOG(VERBOSE) << __func__ << " - SessionType=" << toString(session_type_)
- << ", usage=" << toString(halMetadata->usage)
- << ", content=" << toString(halMetadata->contentType)
- << ", gain=" << halMetadata->gain;
- --track_count;
- ++track;
- ++halMetadata;
- }
- auto hal_retval = stack_iface_->updateMetadata(sourceMetadata);
- if (!hal_retval.isOk()) {
- LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
- << toString(session_type_) << " failed";
- }
-}
-
-// The control function writes stream to FMQ
-size_t BluetoothAudioSession::OutWritePcmData(const void* buffer,
- size_t bytes) {
- if (buffer == nullptr || !bytes) return 0;
- size_t totalWritten = 0;
- int ms_timeout = kFmqSendTimeoutMs;
- do {
- std::unique_lock<std::recursive_mutex> lock(mutex_);
- if (!IsSessionReady()) break;
- size_t availableToWrite = mDataMQ->availableToWrite();
- if (availableToWrite) {
- if (availableToWrite > (bytes - totalWritten)) {
- availableToWrite = bytes - totalWritten;
- }
-
- if (!mDataMQ->write(static_cast<const uint8_t*>(buffer) + totalWritten,
- availableToWrite)) {
- ALOGE("FMQ datapath writing %zu/%zu failed", totalWritten, bytes);
- return totalWritten;
- }
- totalWritten += availableToWrite;
- } else if (ms_timeout >= kWritePollMs) {
- lock.unlock();
- usleep(kWritePollMs * 1000);
- ms_timeout -= kWritePollMs;
- } else {
- ALOGD("out data %zu/%zu overflow %d ms", totalWritten, bytes,
- (kFmqSendTimeoutMs - ms_timeout));
- return totalWritten;
- }
- } while (totalWritten < bytes);
- return totalWritten;
-}
-
-// The control function reads stream from FMQ
-size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
- if (buffer == nullptr || !bytes) return 0;
- size_t totalRead = 0;
- int ms_timeout = kFmqReceiveTimeoutMs;
- do {
- std::unique_lock<std::recursive_mutex> lock(mutex_);
- if (!IsSessionReady()) break;
- size_t availableToRead = mDataMQ->availableToRead();
- if (availableToRead) {
- if (availableToRead > (bytes - totalRead)) {
- availableToRead = bytes - totalRead;
- }
- if (!mDataMQ->read(static_cast<uint8_t*>(buffer) + totalRead,
- availableToRead)) {
- ALOGE("FMQ datapath reading %zu/%zu failed", totalRead, bytes);
- return totalRead;
- }
- totalRead += availableToRead;
- } else if (ms_timeout >= kReadPollMs) {
- lock.unlock();
- usleep(kReadPollMs * 1000);
- ms_timeout -= kReadPollMs;
- continue;
- } else {
- ALOGD("in data %zu/%zu overflow %d ms", totalRead, bytes,
- (kFmqReceiveTimeoutMs - ms_timeout));
- return totalRead;
- }
- } while (totalRead < bytes);
- return totalRead;
-}
-
-std::unique_ptr<BluetoothAudioSessionInstance>
- BluetoothAudioSessionInstance::instance_ptr =
- std::unique_ptr<BluetoothAudioSessionInstance>(
- new BluetoothAudioSessionInstance());
-
-// API to fetch the session
-std::shared_ptr<BluetoothAudioSession>
-BluetoothAudioSessionInstance::GetSessionInstance(
- const SessionType& session_type) {
- std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
- if (!instance_ptr->sessions_map_.empty()) {
- auto entry = instance_ptr->sessions_map_.find(session_type);
- if (entry != instance_ptr->sessions_map_.end()) {
- return entry->second;
- }
- }
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- std::make_shared<BluetoothAudioSession>(session_type);
- instance_ptr->sessions_map_[session_type] = session_ptr;
- return session_ptr;
-}
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSession.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSession.h
deleted file mode 100644
index 7bc12e6..0000000
--- a/bluetooth/audio/2.1/default/session/BluetoothAudioSession.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <mutex>
-#include <unordered_map>
-
-#include <android/hardware/bluetooth/audio/2.0/IBluetoothAudioPort.h>
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-#include <fmq/MessageQueue.h>
-#include <hardware/audio.h>
-#include <hidl/MQDescriptor.h>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using ::android::sp;
-using ::android::hardware::kSynchronizedReadWrite;
-using ::android::hardware::MessageQueue;
-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::IBluetoothAudioPort;
-using ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
-using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-using ::android::hardware::bluetooth::audio::V2_1::SessionType;
-
-using BluetoothAudioStatus =
- ::android::hardware::bluetooth::audio::V2_0::Status;
-
-using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-
-static constexpr uint16_t kObserversCookieSize = 0x0010; // 0x0000 ~ 0x000f
-constexpr uint16_t kObserversCookieUndefined =
- (static_cast<uint16_t>(SessionType::UNKNOWN) << 8 & 0xff00);
-inline SessionType ObserversCookieGetSessionType(uint16_t cookie) {
- return static_cast<SessionType>(cookie >> 8 & 0x00ff);
-}
-inline uint16_t ObserversCookieGetInitValue(SessionType session_type) {
- return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
-}
-inline uint16_t ObserversCookieGetUpperBound(SessionType session_type) {
- return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
- kObserversCookieSize;
-}
-
-// This presents the callbacks of started / suspended and session changed,
-// and the bluetooth_audio module uses to receive the status notification
-struct PortStatusCallbacks {
- // control_result_cb_ - when the Bluetooth stack reports results of
- // streamStarted or streamSuspended, the BluetoothAudioProvider will invoke
- // this callback to report to the bluetooth_audio module.
- // @param: cookie - indicates which bluetooth_audio output should handle
- // @param: start_resp - this report is for startStream or not
- // @param: status - the result of startStream
- std::function<void(uint16_t cookie, bool start_resp,
- const BluetoothAudioStatus& status)>
- control_result_cb_;
- // session_changed_cb_ - when the Bluetooth stack start / end session, the
- // BluetoothAudioProvider will invoke this callback to notify to the
- // bluetooth_audio module.
- // @param: cookie - indicates which bluetooth_audio output should handle
- std::function<void(uint16_t cookie)> session_changed_cb_;
-};
-
-class BluetoothAudioSession {
- private:
- // using recursive_mutex to allow hwbinder to re-enter again.
- std::recursive_mutex mutex_;
- SessionType session_type_;
-
- // audio control path to use for both software and offloading
- sp<IBluetoothAudioPort> stack_iface_;
- // Audio path (FMQ) for software encoding/decoded data
- std::unique_ptr<DataMQ> mDataMQ;
- // audio data configuration for both software and offloading
- AudioConfiguration audio_config_;
-
- static AudioConfiguration invalidSoftwareAudioConfiguration;
- static AudioConfiguration invalidOffloadAudioConfiguration;
-
- // saving those registered bluetooth_audio's callbacks
- std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks>>
- observers_;
-
- bool UpdateDataPath(const DataMQ::Descriptor* dataMQ);
- bool UpdateAudioConfig(const AudioConfiguration& audio_config);
- // invoking the registered session_changed_cb_
- void ReportSessionStatus();
-
- public:
- BluetoothAudioSession(const SessionType& session_type);
-
- // The function helps to check if this session is ready or not
- // @return: true if the Bluetooth stack has started the specified session
- bool IsSessionReady();
-
- // The report function is used to report that the Bluetooth stack has started
- // this session without any failure, and will invoke session_changed_cb_ to
- // notify those registered bluetooth_audio outputs
- void OnSessionStarted(const sp<IBluetoothAudioPort> stack_iface,
- const DataMQ::Descriptor* dataMQ,
- const AudioConfiguration& audio_config);
-
- // The report function is used to report that the Bluetooth stack has ended
- // the session, and will invoke session_changed_cb_ to notify registered
- // bluetooth_audio outputs
- void OnSessionEnded();
-
- // The report function is used to report that the Bluetooth stack has notified
- // the result of startStream or suspendStream, and will invoke
- // control_result_cb_ to notify registered bluetooth_audio outputs
- void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status);
-
- // The control function helps the bluetooth_audio module to register
- // PortStatusCallbacks
- // @return: cookie - the assigned number to this bluetooth_audio output
- uint16_t RegisterStatusCback(const PortStatusCallbacks& cbacks);
-
- // The control function helps the bluetooth_audio module to unregister
- // PortStatusCallbacks
- // @param: cookie - indicates which bluetooth_audio output is
- void UnregisterStatusCback(uint16_t cookie);
-
- // The control function is for the bluetooth_audio module to get the current
- // AudioConfiguration
- const AudioConfiguration& GetAudioConfig();
-
- // Those control functions are for the bluetooth_audio module to start,
- // suspend, stop stream, to check position, and to update metadata.
- bool StartStream();
- bool SuspendStream();
- void StopStream();
- bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position);
- void UpdateTracksMetadata(const struct source_metadata* source_metadata);
-
- // The control function writes stream to FMQ
- size_t OutWritePcmData(const void* buffer, size_t bytes);
- // The control function read stream from FMQ
- size_t InReadPcmData(void* buffer, size_t bytes);
-
- static constexpr PcmParameters kInvalidPcmParameters = {
- .sampleRate = SampleRate::RATE_UNKNOWN,
- .channelMode = ChannelMode::UNKNOWN,
- .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
- .dataIntervalUs = 0,
- };
- // can't be constexpr because of non-literal type
- static const CodecConfiguration kInvalidCodecConfiguration;
-
- static constexpr AudioConfiguration& kInvalidSoftwareAudioConfiguration =
- invalidSoftwareAudioConfiguration;
- static constexpr AudioConfiguration& kInvalidOffloadAudioConfiguration =
- invalidOffloadAudioConfiguration;
-};
-
-class BluetoothAudioSessionInstance {
- public:
- // The API is to fetch the specified session
- static std::shared_ptr<BluetoothAudioSession> GetSessionInstance(
- const SessionType& session_type);
-
- private:
- static std::unique_ptr<BluetoothAudioSessionInstance> instance_ptr;
- std::mutex mutex_;
- std::unordered_map<SessionType, std::shared_ptr<BluetoothAudioSession>>
- sessions_map_;
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSessionControl.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSessionControl.h
deleted file mode 100644
index 017a611..0000000
--- a/bluetooth/audio/2.1/default/session/BluetoothAudioSessionControl.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BluetoothAudioSession.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-class BluetoothAudioSessionControl {
- public:
- // The control API helps to check if session is ready or not
- // @return: true if the Bluetooth stack has started th specified session
- static bool IsSessionReady(const SessionType& session_type) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->IsSessionReady();
- }
- return false;
- }
-
- // The control API helps the bluetooth_audio module to register
- // PortStatusCallbacks
- // @return: cookie - the assigned number to this bluetooth_audio output
- static uint16_t RegisterControlResultCback(
- const SessionType& session_type, const PortStatusCallbacks& cbacks) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->RegisterStatusCback(cbacks);
- }
- return kObserversCookieUndefined;
- }
-
- // The control API helps the bluetooth_audio module to unregister
- // PortStatusCallbacks
- // @param: cookie - indicates which bluetooth_audio output is
- static void UnregisterControlResultCback(const SessionType& session_type,
- uint16_t cookie) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->UnregisterStatusCback(cookie);
- }
- }
-
- // The control API for the bluetooth_audio module to get current
- // AudioConfiguration
- static const AudioConfiguration& GetAudioConfig(
- const SessionType& session_type) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->GetAudioConfig();
- } else if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return BluetoothAudioSession::kInvalidOffloadAudioConfiguration;
- } else {
- return BluetoothAudioSession::kInvalidSoftwareAudioConfiguration;
- }
- }
-
- // Those control APIs for the bluetooth_audio module to start / suspend / stop
- // stream, to check position, and to update metadata.
- static bool StartStream(const SessionType& session_type) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->StartStream();
- }
- return false;
- }
-
- static bool SuspendStream(const SessionType& session_type) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->SuspendStream();
- }
- return false;
- }
-
- static void StopStream(const SessionType& session_type) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->StopStream();
- }
- }
-
- static bool GetPresentationPosition(const SessionType& session_type,
- uint64_t* remote_delay_report_ns,
- uint64_t* total_bytes_readed,
- timespec* data_position) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->GetPresentationPosition(
- remote_delay_report_ns, total_bytes_readed, data_position);
- }
- return false;
- }
-
- static void UpdateTracksMetadata(
- const SessionType& session_type,
- const struct source_metadata* source_metadata) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->UpdateTracksMetadata(source_metadata);
- }
- }
-
- // The control API writes stream to FMQ
- static size_t OutWritePcmData(const SessionType& session_type,
- const void* buffer, size_t bytes) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->OutWritePcmData(buffer, bytes);
- }
- return 0;
- }
-
- // The control API reads stream from FMQ
- static size_t InReadPcmData(const SessionType& session_type, void* buffer,
- size_t bytes) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- return session_ptr->InReadPcmData(buffer, bytes);
- }
- return 0;
- }
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSessionReport.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSessionReport.h
deleted file mode 100644
index 267bf8f..0000000
--- a/bluetooth/audio/2.1/default/session/BluetoothAudioSessionReport.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "BluetoothAudioSession.h"
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-class BluetoothAudioSessionReport {
- public:
- // The API reports the Bluetooth stack has started the session, and will
- // inform registered bluetooth_audio session
- static void OnSessionStarted(const SessionType& session_type,
- const sp<IBluetoothAudioPort> host_iface,
- const DataMQ::Descriptor* dataMQ,
- const AudioConfiguration& audio_config) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->OnSessionStarted(host_iface, dataMQ, audio_config);
- }
- }
- // The API reports the Bluetooth stack has ended the session, and will
- // inform registered bluetooth_audio outputs
- static void OnSessionEnded(const SessionType& session_type) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->OnSessionEnded();
- }
- }
- // The API reports the Bluetooth stack has replied the result of startStream
- // or suspendStream, and will inform registered bluetooth_audio outputs
- static void ReportControlStatus(const SessionType& session_type,
- const bool& start_resp,
- const BluetoothAudioStatus& status) {
- std::shared_ptr<BluetoothAudioSession> session_ptr =
- BluetoothAudioSessionInstance::GetSessionInstance(session_type);
- if (session_ptr != nullptr) {
- session_ptr->ReportControlStatus(start_resp, status);
- }
- }
-};
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp
deleted file mode 100644
index 0937f44..0000000
--- a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BTAudioProviderSessionCodecsDB"
-
-#include "BluetoothAudioSupportedCodecsDB.h"
-
-#include <android-base/logging.h>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-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::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::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 ::android::hardware::bluetooth::audio::V2_1::SampleRate;
-
-// Default Supported PCM Parameters
-static const ::android::hardware::bluetooth::audio::V2_0::PcmParameters
- kDefaultSoftwarePcmCapabilities = {
- .sampleRate = static_cast<
- android::hardware::bluetooth::audio::V2_0::SampleRate>(
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_16000),
- .channelMode =
- static_cast<ChannelMode>(ChannelMode::MONO | ChannelMode::STEREO),
- .bitsPerSample = static_cast<BitsPerSample>(BitsPerSample::BITS_16 |
- BitsPerSample::BITS_24 |
- BitsPerSample::BITS_32)};
-
-static const PcmParameters kDefaultSoftwarePcmCapabilities_2_1 = {
- .sampleRate = static_cast<SampleRate>(
- SampleRate::RATE_48000 | SampleRate::RATE_44100 |
- SampleRate::RATE_32000 | SampleRate::RATE_24000 |
- SampleRate::RATE_16000 | SampleRate::RATE_8000),
- .channelMode =
- static_cast<ChannelMode>(ChannelMode::MONO | ChannelMode::STEREO),
- .bitsPerSample = static_cast<BitsPerSample>(BitsPerSample::BITS_16)};
-
-// Default Supported Codecs
-// SBC: mSampleRate:(44100), mBitsPerSample:(16), mChannelMode:(MONO|STEREO)
-// all blocks | subbands 8 | Loudness
-static const SbcParameters kDefaultOffloadSbcCapability = {
- .sampleRate =
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100,
- .channelMode = static_cast<SbcChannelMode>(SbcChannelMode::MONO |
- SbcChannelMode::JOINT_STEREO),
- .blockLength = static_cast<SbcBlockLength>(
- SbcBlockLength::BLOCKS_4 | SbcBlockLength::BLOCKS_8 |
- SbcBlockLength::BLOCKS_12 | SbcBlockLength::BLOCKS_16),
- .numSubbands = SbcNumSubbands::SUBBAND_8,
- .allocMethod = SbcAllocMethod::ALLOC_MD_L,
- .bitsPerSample = BitsPerSample::BITS_16,
- .minBitpool = 2,
- .maxBitpool = 53};
-
-// AAC: mSampleRate:(44100), mBitsPerSample:(16), mChannelMode:(STEREO)
-static const AacParameters kDefaultOffloadAacCapability = {
- .objectType = AacObjectType::MPEG2_LC,
- .sampleRate =
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100,
- .channelMode = ChannelMode::STEREO,
- .variableBitRateEnabled = AacVariableBitRate::ENABLED,
- .bitsPerSample = BitsPerSample::BITS_16};
-
-// LDAC: mSampleRate:(44100|48000|88200|96000), mBitsPerSample:(16|24|32),
-// mChannelMode:(DUAL|STEREO)
-static const LdacParameters kDefaultOffloadLdacCapability = {
- .sampleRate =
- static_cast<android::hardware::bluetooth::audio::V2_0::SampleRate>(
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000),
- .channelMode = static_cast<LdacChannelMode>(LdacChannelMode::DUAL |
- LdacChannelMode::STEREO),
- .qualityIndex = LdacQualityIndex::QUALITY_HIGH,
- .bitsPerSample = static_cast<BitsPerSample>(BitsPerSample::BITS_16 |
- BitsPerSample::BITS_24 |
- BitsPerSample::BITS_32)};
-
-// aptX: mSampleRate:(44100|48000), mBitsPerSample:(16), mChannelMode:(STEREO)
-static const AptxParameters kDefaultOffloadAptxCapability = {
- .sampleRate =
- static_cast<android::hardware::bluetooth::audio::V2_0::SampleRate>(
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000),
- .channelMode = ChannelMode::STEREO,
- .bitsPerSample = BitsPerSample::BITS_16,
-};
-
-// aptX HD: mSampleRate:(44100|48000), mBitsPerSample:(24),
-// mChannelMode:(STEREO)
-static const AptxParameters kDefaultOffloadAptxHdCapability = {
- .sampleRate =
- static_cast<android::hardware::bluetooth::audio::V2_0::SampleRate>(
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 |
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000),
- .channelMode = ChannelMode::STEREO,
- .bitsPerSample = BitsPerSample::BITS_24,
-};
-
-const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
- {.codecType = CodecType::SBC, .capabilities = {}},
- {.codecType = CodecType::AAC, .capabilities = {}},
- {.codecType = CodecType::LDAC, .capabilities = {}},
- {.codecType = CodecType::APTX, .capabilities = {}},
- {.codecType = CodecType::APTX_HD, .capabilities = {}}};
-
-static bool IsSingleBit(uint32_t bitmasks, uint32_t bitfield) {
- bool single = false;
- uint32_t test_bit = 0x00000001;
- while (test_bit <= bitmasks && test_bit <= bitfield) {
- if (bitfield & test_bit && bitmasks & test_bit) {
- if (single) return false;
- single = true;
- }
- if (test_bit == 0x80000000) break;
- test_bit <<= 1;
- }
- return single;
-}
-
-static bool IsOffloadSbcConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific);
-static bool IsOffloadAacConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific);
-static bool IsOffloadLdacConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific);
-static bool IsOffloadAptxConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific);
-static bool IsOffloadAptxHdConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific);
-
-static bool IsOffloadSbcConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific) {
- if (codec_specific.getDiscriminator() !=
- CodecConfiguration::CodecSpecific::hidl_discriminator::sbcConfig) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- }
- const SbcParameters sbc_data = codec_specific.sbcConfig();
- if (!IsSingleBit(static_cast<uint32_t>(sbc_data.sampleRate), 0xff) ||
- !IsSingleBit(static_cast<uint32_t>(sbc_data.channelMode), 0x0f) ||
- !IsSingleBit(static_cast<uint32_t>(sbc_data.blockLength), 0xf0) ||
- !IsSingleBit(static_cast<uint32_t>(sbc_data.numSubbands), 0x0c) ||
- !IsSingleBit(static_cast<uint32_t>(sbc_data.allocMethod), 0x03) ||
- !IsSingleBit(static_cast<uint32_t>(sbc_data.bitsPerSample), 0x07) ||
- sbc_data.minBitpool > sbc_data.maxBitpool) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- } else if ((sbc_data.sampleRate & kDefaultOffloadSbcCapability.sampleRate) &&
- (sbc_data.channelMode &
- kDefaultOffloadSbcCapability.channelMode) &&
- (sbc_data.blockLength &
- kDefaultOffloadSbcCapability.blockLength) &&
- (sbc_data.numSubbands &
- kDefaultOffloadSbcCapability.numSubbands) &&
- (sbc_data.allocMethod &
- kDefaultOffloadSbcCapability.allocMethod) &&
- (sbc_data.bitsPerSample &
- kDefaultOffloadSbcCapability.bitsPerSample) &&
- (kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
- sbc_data.maxBitpool <= kDefaultOffloadSbcCapability.maxBitpool)) {
- return true;
- }
- LOG(WARNING) << __func__
- << ": Unsupported CodecSpecific=" << toString(codec_specific);
- return false;
-}
-
-static bool IsOffloadAacConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific) {
- if (codec_specific.getDiscriminator() !=
- CodecConfiguration::CodecSpecific::hidl_discriminator::aacConfig) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- }
- const AacParameters aac_data = codec_specific.aacConfig();
- if (!IsSingleBit(static_cast<uint32_t>(aac_data.objectType), 0xf0) ||
- !IsSingleBit(static_cast<uint32_t>(aac_data.sampleRate), 0xff) ||
- !IsSingleBit(static_cast<uint32_t>(aac_data.channelMode), 0x03) ||
- !IsSingleBit(static_cast<uint32_t>(aac_data.bitsPerSample), 0x07)) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- } else if ((aac_data.objectType & kDefaultOffloadAacCapability.objectType) &&
- (aac_data.sampleRate & kDefaultOffloadAacCapability.sampleRate) &&
- (aac_data.channelMode &
- kDefaultOffloadAacCapability.channelMode) &&
- (aac_data.variableBitRateEnabled == AacVariableBitRate::DISABLED ||
- kDefaultOffloadAacCapability.variableBitRateEnabled ==
- AacVariableBitRate::ENABLED) &&
- (aac_data.bitsPerSample &
- kDefaultOffloadAacCapability.bitsPerSample)) {
- return true;
- }
- LOG(WARNING) << __func__
- << ": Unsupported CodecSpecific=" << toString(codec_specific);
- return false;
-}
-
-static bool IsOffloadLdacConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific) {
- if (codec_specific.getDiscriminator() !=
- CodecConfiguration::CodecSpecific::hidl_discriminator::ldacConfig) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- }
- const LdacParameters ldac_data = codec_specific.ldacConfig();
- if (!IsSingleBit(static_cast<uint32_t>(ldac_data.sampleRate), 0xff) ||
- !IsSingleBit(static_cast<uint32_t>(ldac_data.channelMode), 0x07) ||
- (ldac_data.qualityIndex > LdacQualityIndex::QUALITY_LOW &&
- ldac_data.qualityIndex != LdacQualityIndex::QUALITY_ABR) ||
- !IsSingleBit(static_cast<uint32_t>(ldac_data.bitsPerSample), 0x07)) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- } else if ((ldac_data.sampleRate &
- kDefaultOffloadLdacCapability.sampleRate) &&
- (ldac_data.channelMode &
- kDefaultOffloadLdacCapability.channelMode) &&
- (ldac_data.bitsPerSample &
- kDefaultOffloadLdacCapability.bitsPerSample)) {
- return true;
- }
- LOG(WARNING) << __func__
- << ": Unsupported CodecSpecific=" << toString(codec_specific);
- return false;
-}
-
-static bool IsOffloadAptxConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific) {
- if (codec_specific.getDiscriminator() !=
- CodecConfiguration::CodecSpecific::hidl_discriminator::aptxConfig) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- }
- const AptxParameters aptx_data = codec_specific.aptxConfig();
- if (!IsSingleBit(static_cast<uint32_t>(aptx_data.sampleRate), 0xff) ||
- !IsSingleBit(static_cast<uint32_t>(aptx_data.channelMode), 0x03) ||
- !IsSingleBit(static_cast<uint32_t>(aptx_data.bitsPerSample), 0x07)) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- } else if ((aptx_data.sampleRate &
- kDefaultOffloadAptxCapability.sampleRate) &&
- (aptx_data.channelMode &
- kDefaultOffloadAptxCapability.channelMode) &&
- (aptx_data.bitsPerSample &
- kDefaultOffloadAptxCapability.bitsPerSample)) {
- return true;
- }
- LOG(WARNING) << __func__
- << ": Unsupported CodecSpecific=" << toString(codec_specific);
- return false;
-}
-
-static bool IsOffloadAptxHdConfigurationValid(
- const CodecConfiguration::CodecSpecific& codec_specific) {
- if (codec_specific.getDiscriminator() !=
- CodecConfiguration::CodecSpecific::hidl_discriminator::aptxConfig) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- }
- const AptxParameters aptx_data = codec_specific.aptxConfig();
- if (!IsSingleBit(static_cast<uint32_t>(aptx_data.sampleRate), 0xff) ||
- !IsSingleBit(static_cast<uint32_t>(aptx_data.channelMode), 0x03) ||
- !IsSingleBit(static_cast<uint32_t>(aptx_data.bitsPerSample), 0x07)) {
- LOG(WARNING) << __func__
- << ": Invalid CodecSpecific=" << toString(codec_specific);
- return false;
- } else if ((aptx_data.sampleRate &
- kDefaultOffloadAptxHdCapability.sampleRate) &&
- (aptx_data.channelMode &
- kDefaultOffloadAptxHdCapability.channelMode) &&
- (aptx_data.bitsPerSample &
- kDefaultOffloadAptxHdCapability.bitsPerSample)) {
- return true;
- }
- LOG(WARNING) << __func__
- << ": Unsupported CodecSpecific=" << toString(codec_specific);
- return false;
-}
-
-std::vector<::android::hardware::bluetooth::audio::V2_0::PcmParameters>
-GetSoftwarePcmCapabilities() {
- return std::vector<
- ::android::hardware::bluetooth::audio::V2_0::PcmParameters>(
- 1, kDefaultSoftwarePcmCapabilities);
-}
-
-std::vector<PcmParameters> GetSoftwarePcmCapabilities_2_1() {
- return std::vector<PcmParameters>(1, kDefaultSoftwarePcmCapabilities_2_1);
-}
-
-std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
- const ::android::hardware::bluetooth::audio::V2_0::SessionType&
- session_type) {
- return GetOffloadCodecCapabilities(static_cast<SessionType>(session_type));
-}
-
-std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
- const SessionType& session_type) {
- if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return std::vector<CodecCapabilities>(0);
- }
- std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
- kDefaultOffloadA2dpCodecCapabilities;
- for (auto& codec_capability : offload_a2dp_codec_capabilities) {
- switch (codec_capability.codecType) {
- case CodecType::SBC:
- codec_capability.capabilities.sbcCapabilities(
- kDefaultOffloadSbcCapability);
- break;
- case CodecType::AAC:
- codec_capability.capabilities.aacCapabilities(
- kDefaultOffloadAacCapability);
- break;
- case CodecType::LDAC:
- codec_capability.capabilities.ldacCapabilities(
- kDefaultOffloadLdacCapability);
- break;
- case CodecType::APTX:
- codec_capability.capabilities.aptxCapabilities(
- kDefaultOffloadAptxCapability);
- break;
- case CodecType::APTX_HD:
- codec_capability.capabilities.aptxCapabilities(
- kDefaultOffloadAptxHdCapability);
- break;
- case CodecType::UNKNOWN:
- codec_capability = {};
- break;
- }
- }
- return offload_a2dp_codec_capabilities;
-}
-
-bool IsSoftwarePcmConfigurationValid(
- const ::android::hardware::bluetooth::audio::V2_0::PcmParameters&
- pcm_config) {
- if ((pcm_config.sampleRate !=
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_44100 &&
- pcm_config.sampleRate !=
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_48000 &&
- pcm_config.sampleRate !=
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_88200 &&
- pcm_config.sampleRate !=
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_96000 &&
- pcm_config.sampleRate !=
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_16000 &&
- pcm_config.sampleRate !=
- android::hardware::bluetooth::audio::V2_0::SampleRate::RATE_24000) ||
- (pcm_config.bitsPerSample != BitsPerSample::BITS_16 &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_24 &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_32) ||
- (pcm_config.channelMode != ChannelMode::MONO &&
- pcm_config.channelMode != ChannelMode::STEREO)) {
- LOG(WARNING) << __func__
- << ": Invalid PCM Configuration=" << toString(pcm_config);
- return false;
- } else if (pcm_config.sampleRate &
- kDefaultSoftwarePcmCapabilities.sampleRate &&
- pcm_config.bitsPerSample &
- kDefaultSoftwarePcmCapabilities.bitsPerSample &&
- pcm_config.channelMode &
- kDefaultSoftwarePcmCapabilities.channelMode) {
- return true;
- }
- LOG(WARNING) << __func__
- << ": Unsupported PCM Configuration=" << toString(pcm_config);
- return false;
-}
-
-bool IsSoftwarePcmConfigurationValid_2_1(const PcmParameters& pcm_config) {
- if ((pcm_config.sampleRate != SampleRate::RATE_96000 &&
- pcm_config.sampleRate != SampleRate::RATE_88200 &&
- pcm_config.sampleRate != SampleRate::RATE_48000 &&
- pcm_config.sampleRate != SampleRate::RATE_44100 &&
- pcm_config.sampleRate != SampleRate::RATE_32000 &&
- pcm_config.sampleRate != SampleRate::RATE_24000 &&
- pcm_config.sampleRate != SampleRate::RATE_16000 &&
- pcm_config.sampleRate != SampleRate::RATE_8000) ||
- (pcm_config.bitsPerSample != BitsPerSample::BITS_16 &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_24 &&
- pcm_config.bitsPerSample != BitsPerSample::BITS_32) ||
- (pcm_config.channelMode != ChannelMode::MONO &&
- pcm_config.channelMode != ChannelMode::STEREO)) {
- LOG(WARNING) << __func__
- << ": Invalid PCM Configuration=" << toString(pcm_config);
- return false;
- } else if (pcm_config.sampleRate &
- kDefaultSoftwarePcmCapabilities_2_1.sampleRate &&
- pcm_config.bitsPerSample &
- kDefaultSoftwarePcmCapabilities_2_1.bitsPerSample &&
- pcm_config.channelMode &
- kDefaultSoftwarePcmCapabilities_2_1.channelMode &&
- pcm_config.dataIntervalUs != 0) {
- return true;
- }
- LOG(WARNING) << __func__
- << ": Unsupported PCM Configuration=" << toString(pcm_config);
- return false;
-}
-
-bool IsOffloadCodecConfigurationValid(const SessionType& session_type,
- const CodecConfiguration& codec_config) {
- if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- LOG(ERROR) << __func__
- << ": Invalid SessionType=" << toString(session_type);
- return false;
- } else if (codec_config.encodedAudioBitrate < 0x00000001 ||
- 0x00ffffff < codec_config.encodedAudioBitrate) {
- LOG(ERROR) << __func__ << ": Unsupported Codec Configuration="
- << toString(codec_config);
- return false;
- }
- const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
- switch (codec_config.codecType) {
- case CodecType::SBC:
- if (IsOffloadSbcConfigurationValid(codec_specific)) {
- return true;
- }
- return false;
- case CodecType::AAC:
- if (IsOffloadAacConfigurationValid(codec_specific)) {
- return true;
- }
- return false;
- case CodecType::LDAC:
- if (IsOffloadLdacConfigurationValid(codec_specific)) {
- return true;
- }
- return false;
- case CodecType::APTX:
- if (IsOffloadAptxConfigurationValid(codec_specific)) {
- return true;
- }
- return false;
- case CodecType::APTX_HD:
- if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
- return true;
- }
- return false;
- case CodecType::UNKNOWN:
- return false;
- }
- return false;
-}
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.h b/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.h
deleted file mode 100644
index 9b2f680..0000000
--- a/bluetooth/audio/2.1/default/session/BluetoothAudioSupportedCodecsDB.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/bluetooth/audio/2.0/types.h>
-#include <android/hardware/bluetooth/audio/2.1/types.h>
-
-namespace android {
-namespace bluetooth {
-namespace audio {
-
-using ::android::hardware::bluetooth::audio::V2_0::CodecCapabilities;
-using ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration;
-using ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
-using ::android::hardware::bluetooth::audio::V2_1::SessionType;
-
-std::vector<::android::hardware::bluetooth::audio::V2_0::PcmParameters>
-GetSoftwarePcmCapabilities();
-std::vector<PcmParameters> GetSoftwarePcmCapabilities_2_1();
-std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
- const SessionType& session_type);
-std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
- const ::android::hardware::bluetooth::audio::V2_0::SessionType&
- session_type);
-
-bool IsSoftwarePcmConfigurationValid_2_1(const PcmParameters& pcm_config);
-bool IsSoftwarePcmConfigurationValid(
- const ::android::hardware::bluetooth::audio::V2_0::PcmParameters&
- pcm_config);
-bool IsOffloadCodecConfigurationValid(const SessionType& session_type,
- const CodecConfiguration& codec_config);
-
-} // namespace audio
-} // namespace bluetooth
-} // namespace android
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
new file mode 100644
index 0000000..35476d2
--- /dev/null
+++ b/bluetooth/audio/utils/Android.bp
@@ -0,0 +1,23 @@
+cc_library_shared {
+ name: "libbluetooth_audio_session",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ srcs: [
+ "session/BluetoothAudioSession.cpp",
+ "session/BluetoothAudioSession_2_1.cpp",
+ "session/BluetoothAudioSupportedCodecsDB.cpp",
+ "session/BluetoothAudioSupportedCodecsDB_2_1.cpp",
+ ],
+ export_include_dirs: ["session/"],
+ header_libs: ["libhardware_headers"],
+ shared_libs: [
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hardware.bluetooth.audio@2.1",
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+}
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
similarity index 100%
rename from bluetooth/audio/2.0/default/session/BluetoothAudioSession.cpp
rename to bluetooth/audio/utils/session/BluetoothAudioSession.cpp
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSession.h b/bluetooth/audio/utils/session/BluetoothAudioSession.h
similarity index 100%
rename from bluetooth/audio/2.0/default/session/BluetoothAudioSession.h
rename to bluetooth/audio/utils/session/BluetoothAudioSession.h
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl.h
similarity index 100%
rename from bluetooth/audio/2.0/default/session/BluetoothAudioSessionControl.h
rename to bluetooth/audio/utils/session/BluetoothAudioSessionControl.h
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
new file mode 100644
index 0000000..86af468
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioSession_2_1.h"
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionControl_2_1 {
+ using SessionType_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::SessionType;
+
+ public:
+ // The control API helps to check if session is ready or not
+ // @return: true if the Bluetooth stack has started th specified session
+ static bool IsSessionReady(const SessionType_2_1& session_type) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioSession()->IsSessionReady();
+ }
+ return false;
+ }
+
+ // The control API helps the bluetooth_audio module to register
+ // PortStatusCallbacks
+ // @return: cookie - the assigned number to this bluetooth_audio output
+ static uint16_t RegisterControlResultCback(
+ const SessionType_2_1& session_type, const PortStatusCallbacks& cbacks) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
+ }
+ return kObserversCookieUndefined;
+ }
+
+ // The control API helps the bluetooth_audio module to unregister
+ // PortStatusCallbacks
+ // @param: cookie - indicates which bluetooth_audio output is
+ static void UnregisterControlResultCback(const SessionType_2_1& session_type,
+ uint16_t cookie) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
+ }
+ }
+
+ // The control API for the bluetooth_audio module to get current
+ // AudioConfiguration
+ static const AudioConfiguration& GetAudioConfig(
+ const SessionType_2_1& session_type) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ // TODO: map 2.1 to 2.0 audio config inside GetAudioConfig?
+ return session_ptr->GetAudioSession()->GetAudioConfig();
+ } else if (session_type ==
+ SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ return BluetoothAudioSession::kInvalidOffloadAudioConfiguration;
+ } else {
+ return BluetoothAudioSession::kInvalidSoftwareAudioConfiguration;
+ }
+ }
+
+ // Those control APIs for the bluetooth_audio module to start / suspend / stop
+ // stream, to check position, and to update metadata.
+ static bool StartStream(const SessionType_2_1& session_type) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioSession()->StartStream();
+ }
+ return false;
+ }
+
+ static bool SuspendStream(const SessionType_2_1& session_type) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioSession()->SuspendStream();
+ }
+ return false;
+ }
+
+ static void StopStream(const SessionType_2_1& session_type) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->GetAudioSession()->StopStream();
+ }
+ }
+
+ static bool GetPresentationPosition(const SessionType_2_1& session_type,
+ uint64_t* remote_delay_report_ns,
+ uint64_t* total_bytes_readed,
+ timespec* data_position) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioSession()->GetPresentationPosition(
+ remote_delay_report_ns, total_bytes_readed, data_position);
+ }
+ return false;
+ }
+
+ static void UpdateTracksMetadata(
+ const SessionType_2_1& session_type,
+ const struct source_metadata* source_metadata) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->GetAudioSession()->UpdateTracksMetadata(source_metadata);
+ }
+ }
+
+ // The control API writes stream to FMQ
+ static size_t OutWritePcmData(const SessionType_2_1& session_type,
+ const void* buffer, size_t bytes) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->GetAudioSession()->OutWritePcmData(buffer, bytes);
+ }
+ return 0;
+ }
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSessionReport.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport.h
similarity index 100%
rename from bluetooth/audio/2.0/default/session/BluetoothAudioSessionReport.h
rename to bluetooth/audio/utils/session/BluetoothAudioSessionReport.h
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_1.h
new file mode 100644
index 0000000..ab30536
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_1.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioSession_2_1.h"
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSessionReport_2_1 {
+ public:
+ // The API reports the Bluetooth stack has started the session, and will
+ // inform registered bluetooth_audio outputs
+ static void OnSessionStarted(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type,
+ const sp<IBluetoothAudioPort> host_iface,
+ const DataMQ::Descriptor* dataMQ,
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ audio_config) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->OnSessionStarted(host_iface, dataMQ, audio_config);
+ }
+ }
+ // The API reports the Bluetooth stack has ended the session, and will
+ // inform registered bluetooth_audio outputs
+ static void OnSessionEnded(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->GetAudioSession()->OnSessionEnded();
+ }
+ }
+ // The API reports the Bluetooth stack has replied the result of startStream
+ // or suspendStream, and will inform registered bluetooth_audio outputs
+ static void ReportControlStatus(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type,
+ const bool& start_resp, const BluetoothAudioStatus& status) {
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->GetAudioSession()->ReportControlStatus(start_resp, status);
+ }
+ }
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
new file mode 100644
index 0000000..9e1baf4
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderSession_2_1"
+
+#include "BluetoothAudioSession_2_1.h"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+using SessionType_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::SessionType;
+using SessionType_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::SessionType;
+
+namespace {
+bool is_2_0_session_type(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ if (session_type == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH ||
+ session_type == SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH) {
+ return true;
+ } else {
+ return false;
+ }
+}
+} // namespace
+
+BluetoothAudioSession_2_1::BluetoothAudioSession_2_1(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type)
+ : audio_session(BluetoothAudioSessionInstance::GetSessionInstance(
+ static_cast<SessionType_2_0>(session_type))) {
+ if (is_2_0_session_type(session_type)) {
+ session_type_2_1_ = (SessionType_2_1::UNKNOWN);
+ } else {
+ session_type_2_1_ = (session_type);
+ }
+}
+
+std::shared_ptr<BluetoothAudioSession>
+BluetoothAudioSession_2_1::GetAudioSession() {
+ return audio_session;
+}
+
+// The report function is used to report that the Bluetooth stack has started
+// this session without any failure, and will invoke session_changed_cb_ to
+// notify those registered bluetooth_audio outputs
+void BluetoothAudioSession_2_1::OnSessionStarted(
+ const sp<IBluetoothAudioPort> stack_iface, const DataMQ::Descriptor* dataMQ,
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ audio_config) {
+ if (session_type_2_1_ == SessionType_2_1::UNKNOWN) {
+ ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration config;
+ if (audio_config.getDiscriminator() ==
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
+ hidl_discriminator::codecConfig) {
+ config.codecConfig(audio_config.codecConfig());
+ } else {
+ auto& tmpPcm = audio_config.pcmConfig();
+ config.pcmConfig(
+ ::android::hardware::bluetooth::audio::V2_0::PcmParameters{
+ .sampleRate = static_cast<SampleRate>(tmpPcm.sampleRate),
+ .channelMode = tmpPcm.channelMode,
+ .bitsPerSample = tmpPcm.bitsPerSample
+ /*dataIntervalUs is not passed to 2.0 */
+ });
+ }
+
+ audio_session->OnSessionStarted(stack_iface, dataMQ, config);
+ } else {
+ LOG(FATAL) << " Not implemented yet!!";
+ }
+}
+
+std::unique_ptr<BluetoothAudioSessionInstance_2_1>
+ BluetoothAudioSessionInstance_2_1::instance_ptr =
+ std::unique_ptr<BluetoothAudioSessionInstance_2_1>(
+ new BluetoothAudioSessionInstance_2_1());
+
+// API to fetch the session of A2DP / Hearing Aid
+std::shared_ptr<BluetoothAudioSession_2_1>
+BluetoothAudioSessionInstance_2_1::GetSessionInstance(
+ const SessionType_2_1& session_type) {
+ std::lock_guard<std::mutex> guard(instance_ptr->mutex_);
+ if (!instance_ptr->sessions_map_.empty()) {
+ auto entry = instance_ptr->sessions_map_.find(session_type);
+ if (entry != instance_ptr->sessions_map_.end()) {
+ return entry->second;
+ }
+ }
+ std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+ std::make_shared<BluetoothAudioSession_2_1>(session_type);
+ instance_ptr->sessions_map_[session_type] = session_ptr;
+ return session_ptr;
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
new file mode 100644
index 0000000..0e9c12b
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.1/types.h>
+#include "BluetoothAudioSession.h"
+
+#include <mutex>
+#include <unordered_map>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+class BluetoothAudioSession_2_1 {
+ private:
+ std::shared_ptr<BluetoothAudioSession> audio_session;
+
+ ::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_;
+
+ // audio data configuration for both software and offloading
+ ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+ audio_config_2_1_;
+
+ bool UpdateAudioConfig(
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ audio_config);
+
+ public:
+ BluetoothAudioSession_2_1(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type);
+
+ std::shared_ptr<BluetoothAudioSession> GetAudioSession();
+
+ // The report function is used to report that the Bluetooth stack has started
+ // this session without any failure, and will invoke session_changed_cb_ to
+ // notify those registered bluetooth_audio outputs
+ void OnSessionStarted(
+ const sp<IBluetoothAudioPort> stack_iface,
+ const DataMQ::Descriptor* dataMQ,
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ audio_config);
+
+ // The control function is for the bluetooth_audio module to get the current
+ // AudioConfiguration
+ const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+ GetAudioConfig();
+};
+
+class BluetoothAudioSessionInstance_2_1 {
+ public:
+ // The API is to fetch the specified session of A2DP / Hearing Aid
+ static std::shared_ptr<BluetoothAudioSession_2_1> GetSessionInstance(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type);
+
+ private:
+ static std::unique_ptr<BluetoothAudioSessionInstance_2_1> instance_ptr;
+ std::mutex mutex_;
+ std::unordered_map<::android::hardware::bluetooth::audio::V2_1::SessionType,
+ std::shared_ptr<BluetoothAudioSession_2_1>>
+ sessions_map_;
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.cpp
similarity index 100%
rename from bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.cpp
rename to bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.cpp
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.h
similarity index 100%
rename from bluetooth/audio/2.0/default/session/BluetoothAudioSupportedCodecsDB.h
rename to bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB.h
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp
new file mode 100644
index 0000000..8b0b0f7
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderSessionCodecsDB_2_1"
+
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+
+using SampleRate_2_0 = ::android::hardware::bluetooth::audio::V2_0::SampleRate;
+using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+
+using SessionType_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::SessionType;
+using SessionType_2_0 =
+ ::android::hardware::bluetooth::audio::V2_0::SessionType;
+
+namespace {
+bool is_2_0_session_type(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ if (session_type == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH ||
+ session_type == SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH) {
+ return true;
+ } else {
+ return false;
+ }
+}
+} // namespace
+
+static const ::android::hardware::bluetooth::audio::V2_1::PcmParameters
+ kDefaultSoftwarePcmCapabilities_2_1 = {
+ .sampleRate = static_cast<SampleRate_2_1>(
+ SampleRate_2_1::RATE_44100 | SampleRate_2_1::RATE_48000 |
+ SampleRate_2_1::RATE_88200 | SampleRate_2_1::RATE_96000 |
+ SampleRate_2_1::RATE_16000 | SampleRate_2_1::RATE_24000),
+ .channelMode =
+ static_cast<ChannelMode>(ChannelMode::MONO | ChannelMode::STEREO),
+ .bitsPerSample = static_cast<BitsPerSample>(BitsPerSample::BITS_16 |
+ BitsPerSample::BITS_24 |
+ BitsPerSample::BITS_32)};
+
+std::vector<::android::hardware::bluetooth::audio::V2_1::PcmParameters>
+GetSoftwarePcmCapabilities_2_1() {
+ return std::vector<
+ ::android::hardware::bluetooth::audio::V2_1::PcmParameters>(
+ 1, kDefaultSoftwarePcmCapabilities_2_1);
+}
+
+std::vector<CodecCapabilities> GetOffloadCodecCapabilities(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ if (is_2_0_session_type(session_type)) {
+ return GetOffloadCodecCapabilities(
+ static_cast<SessionType_2_0>(session_type));
+ }
+ return std::vector<CodecCapabilities>(0);
+}
+
+bool IsSoftwarePcmConfigurationValid_2_1(
+ const ::android::hardware::bluetooth::audio::V2_1::PcmParameters&
+ pcm_config) {
+ if ((pcm_config.sampleRate != SampleRate_2_1::RATE_44100 &&
+ pcm_config.sampleRate != SampleRate_2_1::RATE_48000 &&
+ pcm_config.sampleRate != SampleRate_2_1::RATE_88200 &&
+ pcm_config.sampleRate != SampleRate_2_1::RATE_96000 &&
+ pcm_config.sampleRate != SampleRate_2_1::RATE_16000 &&
+ pcm_config.sampleRate != SampleRate_2_1::RATE_24000) ||
+ (pcm_config.bitsPerSample != BitsPerSample::BITS_16 &&
+ pcm_config.bitsPerSample != BitsPerSample::BITS_24 &&
+ pcm_config.bitsPerSample != BitsPerSample::BITS_32) ||
+ (pcm_config.channelMode != ChannelMode::MONO &&
+ pcm_config.channelMode != ChannelMode::STEREO)) {
+ LOG(WARNING) << __func__
+ << ": Invalid PCM Configuration=" << toString(pcm_config);
+ return false;
+ } else if (pcm_config.sampleRate &
+ kDefaultSoftwarePcmCapabilities_2_1.sampleRate &&
+ pcm_config.bitsPerSample &
+ kDefaultSoftwarePcmCapabilities_2_1.bitsPerSample &&
+ pcm_config.channelMode &
+ kDefaultSoftwarePcmCapabilities_2_1.channelMode &&
+ pcm_config.dataIntervalUs != 0) {
+ return true;
+ }
+ LOG(WARNING) << __func__
+ << ": Unsupported PCM Configuration=" << toString(pcm_config);
+ return false;
+}
+
+bool IsOffloadCodecConfigurationValid(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type,
+ const ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration&
+ codec_config) {
+ if (is_2_0_session_type(session_type)) {
+ return IsOffloadCodecConfigurationValid(
+ static_cast<SessionType_2_0>(session_type), codec_config);
+ }
+
+ return false;
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h
new file mode 100644
index 0000000..746d9c0
--- /dev/null
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_1.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioSupportedCodecsDB.h"
+
+#include <android/hardware/bluetooth/audio/2.1/types.h>
+
+namespace android {
+namespace bluetooth {
+namespace audio {
+
+std::vector<::android::hardware::bluetooth::audio::V2_1::PcmParameters>
+GetSoftwarePcmCapabilities_2_1();
+std::vector<::android::hardware::bluetooth::audio::V2_0::CodecCapabilities>
+GetOffloadCodecCapabilities(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type);
+
+bool IsSoftwarePcmConfigurationValid_2_1(
+ const ::android::hardware::bluetooth::audio::V2_1::PcmParameters&
+ pcm_config);
+
+bool IsOffloadCodecConfigurationValid(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type,
+ const ::android::hardware::bluetooth::audio::V2_0::CodecConfiguration&
+ codec_config);
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace android
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 2099dc0..7e6b5ad 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -888,6 +888,8 @@
static Status getSystemCameraKind(const camera_metadata_t* staticMeta,
SystemCameraKind* systemCameraKind);
+ static V3_2::DataspaceFlags getDataspace(PixelFormat format);
+
void processCaptureRequestInternal(uint64_t bufferusage, RequestTemplate reqTemplate,
bool useSecureOnlyCameras);
@@ -3178,7 +3180,6 @@
}
}
-
// Verify that all supported stream formats and sizes can be configured
// successfully.
TEST_P(CameraHidlTest, configureStreamsAvailableOutputs) {
@@ -3221,17 +3222,7 @@
uint32_t streamConfigCounter = 0;
for (auto& it : outputStreams) {
V3_2::Stream stream3_2;
- V3_2::DataspaceFlags dataspaceFlag = 0;
- switch (static_cast<PixelFormat>(it.format)) {
- case PixelFormat::BLOB:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
- break;
- case PixelFormat::Y16:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
- break;
- default:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
- }
+ V3_2::DataspaceFlags dataspaceFlag = getDataspace(static_cast<PixelFormat>(it.format));
stream3_2 = {streamId,
StreamType::OUTPUT,
static_cast<uint32_t>(it.width),
@@ -3351,17 +3342,8 @@
size_t j = 0;
for (const auto& it : outputStreams) {
V3_2::Stream stream3_2;
- V3_2::DataspaceFlags dataspaceFlag = 0;
- switch (static_cast<PixelFormat>(it.format)) {
- case PixelFormat::BLOB:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
- break;
- case PixelFormat::Y16:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
- break;
- default:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
- }
+ V3_2::DataspaceFlags dataspaceFlag = getDataspace(
+ static_cast<PixelFormat>(it.format));
stream3_2 = {streamId++,
StreamType::OUTPUT,
static_cast<uint32_t>(it.width),
@@ -5901,6 +5883,23 @@
return ret;
}
+// Select an appropriate dataspace given a specific pixel format.
+V3_2::DataspaceFlags CameraHidlTest::getDataspace(PixelFormat format) {
+ switch (format) {
+ case PixelFormat::BLOB:
+ return static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
+ case PixelFormat::Y16:
+ return static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
+ case PixelFormat::RAW16:
+ case PixelFormat::RAW_OPAQUE:
+ case PixelFormat::RAW10:
+ case PixelFormat::RAW12:
+ return static_cast<V3_2::DataspaceFlags>(Dataspace::ARBITRARY);
+ default:
+ return static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
+ }
+}
+
// Check whether this is a monochrome camera using the static camera characteristics.
Status CameraHidlTest::isMonochromeCamera(const camera_metadata_t *staticMeta) {
Status ret = Status::METHOD_NOT_SUPPORTED;
@@ -6275,17 +6274,8 @@
ASSERT_EQ(Status::OK, rc);
ASSERT_FALSE(outputStreams.empty());
- V3_2::DataspaceFlags dataspaceFlag = 0;
- switch (static_cast<PixelFormat>(outputStreams[idx].format)) {
- case PixelFormat::BLOB:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF);
- break;
- case PixelFormat::Y16:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::DEPTH);
- break;
- default:
- dataspaceFlag = static_cast<V3_2::DataspaceFlags>(Dataspace::UNKNOWN);
- }
+ V3_2::DataspaceFlags dataspaceFlag = getDataspace(
+ static_cast<PixelFormat>(outputStreams[idx].format));
::android::hardware::hidl_vec<V3_4::Stream> streams3_4(/*size*/1);
V3_4::Stream stream3_4 = {{ 0 /*streamId*/, StreamType::OUTPUT,
diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml
index 5888ab9..608890b 100644
--- a/compatibility_matrices/compatibility_matrix.3.xml
+++ b/compatibility_matrices/compatibility_matrix.3.xml
@@ -310,6 +310,10 @@
<instance>slot2</instance>
<instance>slot3</instance>
</interface>
+ </hal>
+ <hal format="hidl" optional="true">
+ <name>android.hardware.radio</name>
+ <version>1.0-2</version>
<interface>
<name>ISap</name>
<instance>slot1</instance>
diff --git a/graphics/allocator/2.0/default/OWNERS b/graphics/allocator/2.0/default/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/allocator/2.0/default/OWNERS
+++ b/graphics/allocator/2.0/default/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/allocator/2.0/utils/OWNERS b/graphics/allocator/2.0/utils/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/allocator/2.0/utils/OWNERS
+++ b/graphics/allocator/2.0/utils/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/composer/2.1/default/OWNERS b/graphics/composer/2.1/default/OWNERS
index db8fb80..709c4d1 100644
--- a/graphics/composer/2.1/default/OWNERS
+++ b/graphics/composer/2.1/default/OWNERS
@@ -1,6 +1,3 @@
# Graphics team
-courtneygo@google.com
-jessehall@google.com
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.1/utils/OWNERS b/graphics/composer/2.1/utils/OWNERS
index 5acc631..7af69b4 100644
--- a/graphics/composer/2.1/utils/OWNERS
+++ b/graphics/composer/2.1/utils/OWNERS
@@ -1,5 +1,2 @@
-courtneygo@google.com
-jessehall@google.com
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.2/default/OWNERS b/graphics/composer/2.2/default/OWNERS
index db8fb80..709c4d1 100644
--- a/graphics/composer/2.2/default/OWNERS
+++ b/graphics/composer/2.2/default/OWNERS
@@ -1,6 +1,3 @@
# Graphics team
-courtneygo@google.com
-jessehall@google.com
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.2/utils/OWNERS b/graphics/composer/2.2/utils/OWNERS
index 3f1e82c..709c4d1 100644
--- a/graphics/composer/2.2/utils/OWNERS
+++ b/graphics/composer/2.2/utils/OWNERS
@@ -1,5 +1,3 @@
# Graphics team
-courtneygo@google.com
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.2/vts/functional/OWNERS b/graphics/composer/2.2/vts/functional/OWNERS
index a17a50c..ea06752 100644
--- a/graphics/composer/2.2/vts/functional/OWNERS
+++ b/graphics/composer/2.2/vts/functional/OWNERS
@@ -1,8 +1,6 @@
# Graphics team
-courtneygo@google.com
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
# VTS team
yim@google.com
diff --git a/graphics/composer/2.3/default/OWNERS b/graphics/composer/2.3/default/OWNERS
index 820ebe6..709c4d1 100644
--- a/graphics/composer/2.3/default/OWNERS
+++ b/graphics/composer/2.3/default/OWNERS
@@ -1,5 +1,3 @@
# Graphics team
-jessehall@google.com
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.3/utils/OWNERS b/graphics/composer/2.3/utils/OWNERS
index cc6d937..709c4d1 100644
--- a/graphics/composer/2.3/utils/OWNERS
+++ b/graphics/composer/2.3/utils/OWNERS
@@ -1,4 +1,3 @@
# Graphics team
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.3/vts/functional/OWNERS b/graphics/composer/2.3/vts/functional/OWNERS
index b3ea6be..ea06752 100644
--- a/graphics/composer/2.3/vts/functional/OWNERS
+++ b/graphics/composer/2.3/vts/functional/OWNERS
@@ -1,7 +1,6 @@
# Graphics team
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
# VTS team
yim@google.com
diff --git a/graphics/composer/2.4/default/OWNERS b/graphics/composer/2.4/default/OWNERS
index cc6d937..709c4d1 100644
--- a/graphics/composer/2.4/default/OWNERS
+++ b/graphics/composer/2.4/default/OWNERS
@@ -1,4 +1,3 @@
# Graphics team
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.4/utils/OWNERS b/graphics/composer/2.4/utils/OWNERS
index cc6d937..709c4d1 100644
--- a/graphics/composer/2.4/utils/OWNERS
+++ b/graphics/composer/2.4/utils/OWNERS
@@ -1,4 +1,3 @@
# Graphics team
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
diff --git a/graphics/composer/2.4/vts/functional/OWNERS b/graphics/composer/2.4/vts/functional/OWNERS
index b3ea6be..ea06752 100644
--- a/graphics/composer/2.4/vts/functional/OWNERS
+++ b/graphics/composer/2.4/vts/functional/OWNERS
@@ -1,7 +1,6 @@
# Graphics team
+adyabr@google.com
lpy@google.com
-stoza@google.com
-vhau@google.com
# VTS team
yim@google.com
diff --git a/graphics/mapper/2.0/default/OWNERS b/graphics/mapper/2.0/default/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/2.0/default/OWNERS
+++ b/graphics/mapper/2.0/default/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/mapper/2.0/utils/OWNERS b/graphics/mapper/2.0/utils/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/2.0/utils/OWNERS
+++ b/graphics/mapper/2.0/utils/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/mapper/2.0/vts/OWNERS b/graphics/mapper/2.0/vts/OWNERS
index 11b7d21..4177296 100644
--- a/graphics/mapper/2.0/vts/OWNERS
+++ b/graphics/mapper/2.0/vts/OWNERS
@@ -1,7 +1,7 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
# VTS team
yim@google.com
diff --git a/graphics/mapper/2.1/default/OWNERS b/graphics/mapper/2.1/default/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/2.1/default/OWNERS
+++ b/graphics/mapper/2.1/default/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/mapper/2.1/utils/OWNERS b/graphics/mapper/2.1/utils/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/2.1/utils/OWNERS
+++ b/graphics/mapper/2.1/utils/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/mapper/2.1/vts/OWNERS b/graphics/mapper/2.1/vts/OWNERS
index 11b7d21..4177296 100644
--- a/graphics/mapper/2.1/vts/OWNERS
+++ b/graphics/mapper/2.1/vts/OWNERS
@@ -1,7 +1,7 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
# VTS team
yim@google.com
diff --git a/graphics/mapper/3.0/utils/OWNERS b/graphics/mapper/3.0/utils/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/3.0/utils/OWNERS
+++ b/graphics/mapper/3.0/utils/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/mapper/3.0/vts/OWNERS b/graphics/mapper/3.0/vts/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/3.0/vts/OWNERS
+++ b/graphics/mapper/3.0/vts/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/mapper/4.0/utils/OWNERS b/graphics/mapper/4.0/utils/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/4.0/utils/OWNERS
+++ b/graphics/mapper/4.0/utils/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/graphics/mapper/4.0/vts/OWNERS b/graphics/mapper/4.0/vts/OWNERS
index 2a56b38..c9f24d0 100644
--- a/graphics/mapper/4.0/vts/OWNERS
+++ b/graphics/mapper/4.0/vts/OWNERS
@@ -1,4 +1,4 @@
# Graphics team
chrisforbes@google.com
-stoza@google.com
-vhau@google.com
+jreck@google.com
+lpy@google.com
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index a398e7d..4e9dcdb 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -18,9 +18,12 @@
import @1.0::CdmaSmsMessage;
+import @1.0::Dial;
import @1.0::GsmSmsMessage;
import @1.1::CardPowerState;
import @1.2::DataRequestReason;
+import @1.4::EmergencyCallRouting;
+import @1.4::EmergencyServiceCategory;
import @1.4::RadioAccessFamily;
import @1.5::IRadio;
import @1.5::AccessNetwork;
@@ -375,6 +378,64 @@
int64_t completionDurationMillis);
/**
+ * Initiate emergency voice call, with zero or more emergency service category(s), zero or
+ * more emergency Uniform Resource Names (URN), and routing information for handling the call.
+ * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial
+ * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android.
+ *
+ * In multi-sim scenario, if the emergency number is from a specific subscription, this radio
+ * request can still be sent out on the other subscription as long as routing is set to
+ * @1.4::EmergencyNumberRouting#EMERGENCY. This radio request will not be sent on an inactive
+ * (PIN/PUK locked) subscription unless both subscriptions are PIN/PUK locked. In this case,
+ * the request will be sent on the primary subscription.
+ *
+ * Some countries or carriers require some emergency numbers that must be handled with normal
+ * call routing if possible or emergency routing. 1) if the 'routing' field is specified as
+ * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to
+ * use normal call routing to handle the call; if service cannot support normal routing, the
+ * implementation must use emergency routing to handle the call. 2) if 'routing' is specified
+ * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to
+ * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN,
+ * Android does not know how to handle the call.
+ *
+ * If the dialed emergency number does not have a specified emergency service category, the
+ * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed
+ * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field
+ * is set to an empty list. If the underlying technology used to request emergency services
+ * does not support the emergency service category or emergency uniform resource names, the
+ * field 'categories' or 'urns' may be ignored.
+ *
+ * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the
+ * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's
+ * intent for this dial request is emergency call, and the modem must treat this as an actual
+ * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know
+ * user's intent for this call.
+ *
+ * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real
+ * emergency service; otherwise it's for a real emergency call request.
+ *
+ * Reference: 3gpp 22.101, Section 10 - Emergency Calls;
+ * 3gpp 23.167, Section 6 - Functional description;
+ * 3gpp 24.503, Section 5.1.6.8.1 - General;
+ * RFC 5031
+ *
+ * @param serial Serial number of request.
+ * @param dialInfo the same @1.0::Dial information used by @1.0::IRadio.dial.
+ * @param categories bitfield<@1.4::EmergencyServiceCategory> the Emergency Service Category(s)
+ * of the call.
+ * @param urns the emergency Uniform Resource Names (URN)
+ * @param routing @1.4::EmergencyCallRouting the emergency call routing information.
+ * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call
+ * is known.
+ * @param isTesting Flag indicating if this request is for testing purpose.
+ *
+ * Response function is IRadioResponse.emergencyDialResponse()
+ */
+ oneway emergencyDial_1_6(int32_t serial, Dial dialInfo,
+ bitfield<EmergencyServiceCategory> categories, vec<string> urns,
+ EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting);
+
+ /**
* Get which bands the modem's background scan is acting on.
*
* @param serial Serial number of request.
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 8e1033b..8560b3d 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -732,6 +732,14 @@
*/
NrVopsInfo nrVopsInfo;
} ngranInfo;
+
+ struct GeranRegistrationInfo {
+ /**
+ * True if the dual transfer mode is supported.
+ * Refer to 3GPP TS 44.108 section 3.4.25.3
+ */
+ bool dtmSupported;
+ } geranInfo;
} accessTechnologySpecificInfo;
};
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 8b87292..44900b8 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -412,6 +412,167 @@
}
/*
+ * Test IRadio.emergencyDial() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6) {
+ if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+ ALOGI("Skipping emergencyDial because voice call is not supported in device");
+ return;
+ } else {
+ ALOGI("Running emergencyDial because voice call is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_0::Dial dialInfo;
+ dialInfo.address = hidl_string("911");
+ int categories = static_cast<int>(
+ ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
+ std::vector<hidl_string> urns = {""};
+ ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+ ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
+
+ Return<void> res =
+ radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
+
+ ALOGI("emergencyDial, rspInfo_v1_0.error = %s\n",
+ toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str());
+
+ ::android::hardware::radio::V1_0::RadioError rspEmergencyDial =
+ radioRsp_v1_6->rspInfo_v1_0.error;
+ // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+ // or Emergency_Only.
+ if (isDsDsEnabled() || isTsTsEnabled()) {
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getVoiceRegistrationState(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) ||
+ isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) {
+ EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
+ }
+ } else {
+ EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
+ }
+
+ // Give some time for modem to establish the emergency call channel.
+ sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+ // Disconnect all the potential established calls to prevent them affecting other tests.
+ clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadio.emergencyDial() with specified service and its response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withServices) {
+ if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+ ALOGI("Skipping emergencyDial because voice call is not supported in device");
+ return;
+ } else {
+ ALOGI("Running emergencyDial because voice call is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_0::Dial dialInfo;
+ dialInfo.address = hidl_string("911");
+ int categories =
+ static_cast<int>(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE);
+ std::vector<hidl_string> urns = {"urn:service:sos.ambulance"};
+ ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+ ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
+
+ Return<void> res =
+ radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
+
+ ALOGI("emergencyDial_withServices, rspInfo_v1_0.error = %s\n",
+ toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str());
+ ::android::hardware::radio::V1_0::RadioError rspEmergencyDial =
+ radioRsp_v1_6->rspInfo_v1_0.error;
+
+ // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+ // or Emergency_Only.
+ if (isDsDsEnabled() || isTsTsEnabled()) {
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getVoiceRegistrationState(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) ||
+ isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) {
+ EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
+ }
+ } else {
+ EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
+ }
+ // Give some time for modem to establish the emergency call channel.
+ sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+ // Disconnect all the potential established calls to prevent them affecting other tests.
+ clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadio.emergencyDial() with known emergency call routing and its response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, emergencyDial_1_6_withEmergencyRouting) {
+ if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+ ALOGI("Skipping emergencyDial because voice call is not supported in device");
+ return;
+ } else {
+ ALOGI("Running emergencyDial because voice call is supported in device");
+ }
+
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_0::Dial dialInfo;
+ dialInfo.address = hidl_string("911");
+ int categories = static_cast<int>(
+ ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
+ std::vector<hidl_string> urns = {""};
+ ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+ ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY;
+
+ Return<void> res =
+ radio_v1_6->emergencyDial_1_6(serial, dialInfo, categories, urns, routing, true, true);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo_v1_0.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
+
+ ALOGI("emergencyDial_withEmergencyRouting, rspInfo_v1_0.error = %s\n",
+ toString(radioRsp_v1_6->rspInfo_v1_0.error).c_str());
+ ::android::hardware::radio::V1_0::RadioError rspEmergencyDial =
+ radioRsp_v1_6->rspInfo_v1_0.error;
+
+ // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+ // or Emergency_Only.
+ if (isDsDsEnabled() || isTsTsEnabled()) {
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getVoiceRegistrationState(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ if (isVoiceEmergencyOnly(radioRsp_v1_6->voiceRegResp.regState) ||
+ isVoiceInService(radioRsp_v1_6->voiceRegResp.regState)) {
+ EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
+ }
+ } else {
+ EXPECT_EQ(::android::hardware::radio::V1_0::RadioError::NONE, rspEmergencyDial);
+ }
+
+ // Give some time for modem to establish the emergency call channel.
+ sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+ // Disconnect all the potential established calls to prevent them affecting other tests.
+ clearPotentialEstablishedCalls();
+}
+
+/*
* Test IRadio.getCurrentCalls_1_6() for the response returned.
*/
TEST_P(RadioHidlTest_v1_6, getCurrentCalls_1_6) {
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index 79c3cde..59f7682 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -74,6 +74,29 @@
return status;
}
+void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() {
+ // Get the current call Id to hangup the established emergency call.
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getCurrentCalls_1_6(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+
+ // Hang up to disconnect the established call channels.
+ for (const ::android::hardware::radio::V1_6::Call& call : radioRsp_v1_6->currentCalls) {
+ serial = GetRandomSerialNumber();
+ radio_v1_6->hangup(serial, call.base.base.index);
+ ALOGI("Hang up to disconnect the established call channel: %d", call.base.base.index);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ // Give some time for modem to disconnect the established call channel.
+ sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME);
+ }
+
+ // Verify there are no more current calls.
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getCurrentCalls_1_6(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(0, radioRsp_v1_6->currentCalls.size());
+}
+
void RadioHidlTest_v1_6::updateSimCardStatus() {
serial = GetRandomSerialNumber();
radio_v1_6->getIccCardStatus(serial);
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 5fcfa3b..db067d7 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -70,7 +70,8 @@
::android::hardware::radio::V1_6::RadioResponseInfo rspInfo;
// Call
- hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+ hidl_vec<::android::hardware::radio::V1_6::Call> currentCalls;
+ ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp;
// Sms
SendSmsResult sendSmsResult;
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index 7c5cf6d..ba84fd4 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -816,8 +816,11 @@
}
Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2(
- const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
- const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
+ const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) {
+ rspInfo_v1_0 = info;
+ voiceRegResp = voiceRegResponse;
+ parent_v1_6.notify(info.serial);
return Void();
}
@@ -1210,8 +1213,9 @@
Return<void> RadioResponse_v1_6::getCurrentCallsResponse_1_6(
const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
- const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& /*calls*/) {
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls) {
rspInfo = info;
+ currentCalls = calls;
parent_v1_6.notify(info.serial);
return Void();
}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
index 594844a..a35b46c 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
@@ -111,6 +111,8 @@
STORAGE_KEY_UNSUPPORTED = -77,
INCOMPATIBLE_MGF_DIGEST = -78,
UNSUPPORTED_MGF_DIGEST = -79,
+ MISSING_NOT_BEFORE = -80,
+ MISSING_NOT_AFTER = -81,
UNIMPLEMENTED = -100,
VERSION_MISMATCH = -101,
UNKNOWN_ERROR = -1000,
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
index b924a13..03982e3 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
@@ -94,4 +94,8 @@
MAC_LENGTH = 805307371,
RESET_SINCE_ID_ROTATION = 1879049196,
CONFIRMATION_TOKEN = -1879047187,
+ CERTIFICATE_SERIAL = -2147482642,
+ CERTIFICATE_SUBJECT = -1879047185,
+ CERTIFICATE_NOT_BEFORE = 1610613744,
+ CERTIFICATE_NOT_AFTER = 1610613745,
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
index b20601d..35e3827 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
@@ -42,7 +42,7 @@
INVALID_AUTHORIZATION_TIMEOUT = -16,
UNSUPPORTED_KEY_FORMAT = -17,
INCOMPATIBLE_KEY_FORMAT = -18,
- UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19, /** For PKCS8 & PKCS12 */
+ UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19, /** For PKCS8 & PKCS12 */
UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, /** For PKCS8 & PKCS12 */
INVALID_INPUT_LENGTH = -21,
KEY_EXPORT_OPTIONS_INVALID = -22,
@@ -101,6 +101,8 @@
STORAGE_KEY_UNSUPPORTED = -77,
INCOMPATIBLE_MGF_DIGEST = -78,
UNSUPPORTED_MGF_DIGEST = -79,
+ MISSING_NOT_BEFORE = -80,
+ MISSING_NOT_AFTER = -81,
UNIMPLEMENTED = -100,
VERSION_MISMATCH = -101,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index f52e32b..4f58cbe 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -933,4 +933,35 @@
* Must never appear in KeyCharacteristics.
*/
CONFIRMATION_TOKEN = (9 << 28) /* TagType:BYTES */ | 1005,
+
+ /**
+ * Tag::CERTIFICATE_SERIAL specifies the serial number to be assigned to the
+ * attestation certificate to be generated for the given key. This parameter should only
+ * be passed to keyMint in the attestation parameters during generateKey() and importKey().
+ */
+ CERTIFICATE_SERIAL = (8 << 28) /* TagType:BIGNUM */ | 1006,
+
+ /**
+ * Tag::CERTIFICATE_SUBJECT the certificate subject. The value is a DER encoded X509 NAME.
+ * This value is used when generating a self signed certificates. This tag may be specified
+ * during generateKey and importKey. If not provided the subject name shall default to
+ * <TODO default subject here>.
+ */
+ CERTIFICATE_SUBJECT = (9 << 28) /* TagType:BYTES */ | 1007,
+
+ /**
+ * Tag::CERTIFICATE_NOT_BEFORE the beginning of the validity of the certificate in UNIX epoch
+ * time in seconds. This value is used when generating attestation or self signed certificates.
+ * ErrorCode::MISSING_NOT_BEFORE must be returned if this tag is not provided if this tag is
+ * not provided to generateKey or importKey.
+ */
+ CERTIFICATE_NOT_BEFORE = (6 << 28) /* TagType:DATE */ | 1008,
+
+ /**
+ * Tag::CERTIFICATE_NOT_AFTER the end of the validity of the certificate in UNIX epoch
+ * time in seconds. This value is used when generating attestation or self signed certificates.
+ * ErrorCode::MISSING_NOT_AFTER must be returned if this tag is not provided to generateKey
+ * or importKey.
+ */
+ CERTIFICATE_NOT_AFTER = (6 << 28) /* TagType:DATE */ | 1009,
}
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 43cfb63..479a11d 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -126,6 +126,10 @@
DECLARE_TYPED_TAG(USER_SECURE_ID);
DECLARE_TYPED_TAG(VENDOR_PATCHLEVEL);
DECLARE_TYPED_TAG(RSA_OAEP_MGF_DIGEST);
+DECLARE_TYPED_TAG(CERTIFICATE_SERIAL);
+DECLARE_TYPED_TAG(CERTIFICATE_SUBJECT);
+DECLARE_TYPED_TAG(CERTIFICATE_NOT_BEFORE);
+DECLARE_TYPED_TAG(CERTIFICATE_NOT_AFTER);
#undef DECLARE_TYPED_TAG