summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-12-14 02:09:30 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2021-12-14 02:09:30 +0000
commit729a7a44a8acf58a7073d6520ece9e69df2fa6eb (patch)
tree8ed05777c92c99d1bdfcbeab1fb384368b292be0
parentf60b9a30eb1fec740269b20e3772a7bdad4011a0 (diff)
parentbbc23f9c61c5be50e5b25b3d684bb3e6d9a26ec5 (diff)
Snap for 7995208 from bbc23f9c61c5be50e5b25b3d684bb3e6d9a26ec5 to tm-release
Change-Id: I279d238c408ce2fed930df8a9fd59068c344bdb5
-rw-r--r--android/app/src/com/android/bluetooth/BluetoothObexTransport.java10
-rw-r--r--android/app/src/com/android/bluetooth/audio_util/helpers/Image.java24
-rw-r--r--android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java15
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterState.java2
-rw-r--r--android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java12
-rw-r--r--android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java17
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java100
-rw-r--r--system/audio_hal_interface/a2dp_encoding.cc2
-rw-r--r--system/audio_hal_interface/client_interface.cc13
-rw-r--r--system/audio_hal_interface/client_interface.h1
-rw-r--r--system/audio_hal_interface/client_interface_unittest.cc4
-rw-r--r--system/audio_hal_interface/hearing_aid_software_encoding.cc2
-rw-r--r--system/audio_hal_interface/le_audio_software.cc20
-rw-r--r--system/audio_hal_interface/le_audio_software.h1
-rw-r--r--system/bta/le_audio/client_audio.cc8
-rw-r--r--system/bta/pan/bta_pan_ci.cc4
16 files changed, 222 insertions, 13 deletions
diff --git a/android/app/src/com/android/bluetooth/BluetoothObexTransport.java b/android/app/src/com/android/bluetooth/BluetoothObexTransport.java
index b1b5709a76..9fb8253a91 100644
--- a/android/app/src/com/android/bluetooth/BluetoothObexTransport.java
+++ b/android/app/src/com/android/bluetooth/BluetoothObexTransport.java
@@ -40,6 +40,8 @@ public class BluetoothObexTransport implements ObexTransport {
private int mMaxTransmitPacketSize = PACKET_SIZE_UNSPECIFIED;
private int mMaxReceivePacketSize = PACKET_SIZE_UNSPECIFIED;
+ private boolean mIsCoverArt = false;
+
public BluetoothObexTransport(BluetoothSocket socket) {
this.mSocket = socket;
}
@@ -97,7 +99,9 @@ public class BluetoothObexTransport implements ObexTransport {
@Override
public int getMaxTransmitPacketSize() {
- if (mSocket.getConnectionType() != BluetoothSocket.TYPE_L2CAP) {
+ if (mSocket.getConnectionType() != BluetoothSocket.TYPE_L2CAP
+ || (mIsCoverArt
+ && mMaxTransmitPacketSize != PACKET_SIZE_UNSPECIFIED)) {
return mMaxTransmitPacketSize;
}
return mSocket.getMaxTransmitPacketSize();
@@ -125,4 +129,8 @@ public class BluetoothObexTransport implements ObexTransport {
}
return false;
}
+
+ public void setConnectionForCoverArt(boolean isCoverArt) {
+ mIsCoverArt = isCoverArt;
+ }
}
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java b/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java
index c0623c6f46..231df9e276 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java
@@ -56,13 +56,19 @@ public class Image {
public Image(Context context, MediaMetadata metadata) {
mContext = context;
- String uri_art = metadata.getString(MediaMetadata.METADATA_KEY_ART_URI);
- String uri_album_art = metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI);
- String uri_icon = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI);
+ String uri_art = null;
+ String uri_album_art = null;
+ String uri_icon = null;
Bitmap bmp_art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
Bitmap bmp_album_art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
Bitmap bmp_icon = metadata.getBitmap(MediaMetadata.METADATA_KEY_DISPLAY_ICON);
+ if (mContext != null && Util.areUriImagesSupported(mContext)) {
+ uri_art = metadata.getString(MediaMetadata.METADATA_KEY_ART_URI);
+ uri_album_art = metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI);
+ uri_icon = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI);
+ }
+
if (bmp_art != null) {
setImage(bmp_art);
} else if (bmp_album_art != null) {
@@ -84,13 +90,19 @@ public class Image {
public Image(Context context, Bundle bundle) {
mContext = context;
- String uri_art = bundle.getString(MediaMetadata.METADATA_KEY_ART_URI);
- String uri_album_art = bundle.getString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI);
- String uri_icon = bundle.getString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI);
+ String uri_art = null;
+ String uri_album_art = null;
+ String uri_icon = null;
Bitmap bmp_art = bundle.getParcelable(MediaMetadata.METADATA_KEY_ART);
Bitmap bmp_album_art = bundle.getParcelable(MediaMetadata.METADATA_KEY_ALBUM_ART);
Bitmap bmp_icon = bundle.getParcelable(MediaMetadata.METADATA_KEY_DISPLAY_ICON);
+ if (mContext != null && Util.areUriImagesSupported(mContext)) {
+ uri_art = bundle.getString(MediaMetadata.METADATA_KEY_ART_URI);
+ uri_album_art = bundle.getString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI);
+ uri_icon = bundle.getString(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI);
+ }
+
if (bmp_art != null) {
setImage(bmp_art);
} else if (bmp_album_art != null) {
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
index 4397bbc876..8fde670b83 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
@@ -35,8 +35,8 @@ import javax.obex.ServerSession;
/**
* The AVRCP Cover Art Service
*
- * This service handles allocation of image handles and storage of images. It also owns the BIP OBEX
- * server that handles requests to get AVRCP cover artwork.
+ * This service handles allocation of image handles and storage of images. It also owns the
+ * BIP OBEX server that handles requests to get AVRCP cover artwork.
*/
public class AvrcpCoverArtService {
private static final String TAG = "AvrcpCoverArtService";
@@ -44,6 +44,12 @@ public class AvrcpCoverArtService {
private static final int COVER_ART_STORAGE_MAX_ITEMS = 32;
+ /**
+ * Limiting transmit packet size because some carkits are disconnected if
+ * AVRCP Cover Art OBEX packet size exceed 1024 bytes.
+ */
+ private static final int MAX_TRANSMIT_PACKET_SIZE = 1024;
+
private final Context mContext;
// Cover Art and Image Handle objects
@@ -207,7 +213,10 @@ public class AvrcpCoverArtService {
disconnect(device);
}
});
- BluetoothObexTransport transport = new BluetoothObexTransport(socket);
+ BluetoothObexTransport transport = new BluetoothObexTransport(socket,
+ MAX_TRANSMIT_PACKET_SIZE,
+ BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED);
+ transport.setConnectionForCoverArt(true);
try {
ServerSession session = new ServerSession(transport, s, null);
mClients.put(device, session);
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterState.java b/android/app/src/com/android/bluetooth/btservice/AdapterState.java
index 7216d787c2..f25b3a2459 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterState.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterState.java
@@ -78,7 +78,7 @@ final class AdapterState extends StateMachine {
"ro.bluetooth.ble_stop_timeout_delay";
static final int BLE_START_TIMEOUT_DELAY = 4000;
- static final int BLE_STOP_TIMEOUT_DELAY = 1000;
+ static final int BLE_STOP_TIMEOUT_DELAY = 4000;
static final int BREDR_START_TIMEOUT_DELAY = 4000;
static final int BREDR_STOP_TIMEOUT_DELAY = 4000;
diff --git a/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java b/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java
index 824955d5a4..429ee7d0b8 100644
--- a/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java
+++ b/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java
@@ -16,8 +16,12 @@
package com.android.bluetooth.hfp;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
import java.util.List;
@@ -36,6 +40,14 @@ public class BluetoothHeadsetProxy {
mBluetoothHeadset = headset;
}
+ public void closeBluetoothHeadsetProxy(Context context) {
+ final BluetoothManager btManager =
+ context.getSystemService(BluetoothManager.class);
+ if (btManager != null) {
+ btManager.getAdapter().closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
+ }
+ }
+
public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
String number, int type) {
diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java
index dacfa069a5..5ca6397798 100644
--- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java
+++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java
@@ -170,6 +170,8 @@ public class BluetoothInCallService extends InCallService {
Log.d(TAG, "Bluetooth Adapter state: " + state);
if (state == BluetoothAdapter.STATE_ON) {
queryPhoneState();
+ } else if (state == BluetoothAdapter.STATE_TURNING_OFF) {
+ clear();
}
}
}
@@ -620,6 +622,12 @@ public class BluetoothInCallService extends InCallService {
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
+ clear();
+ super.onDestroy();
+ }
+
+ private void clear() {
+ Log.d(TAG, "clear");
if (mBluetoothOnModeChangedListener != null) {
mAudioManager.removeOnModeChangedListener(mBluetoothOnModeChangedListener);
mBluetoothOnModeChangedListener = null;
@@ -628,8 +636,15 @@ public class BluetoothInCallService extends InCallService {
unregisterReceiver(mBluetoothAdapterReceiver);
mBluetoothAdapterReceiver = null;
}
+ if (mBluetoothHeadset != null) {
+ mBluetoothHeadset.closeBluetoothHeadsetProxy(this);
+ mBluetoothHeadset = null;
+ }
+ mProfileListener = null;
sInstance = null;
- super.onDestroy();
+ mCallbacks.clear();
+ mBluetoothCallHashMap.clear();
+ mClccIndexMap.clear();
}
private void sendListOfCalls(boolean shouldLog) {
diff --git a/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java b/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java
index 89bbf5cbae..352fb7e359 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/audio_util/ImageTest.java
@@ -38,6 +38,8 @@ import android.test.mock.MockContentResolver;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.bluetooth.R;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -52,6 +54,7 @@ public class ImageTest {
private Context mTargetContext;
private @Mock Context mMockContext;
+ private @Mock Resources mMockResources;
private Resources mTestResources;
private MockContentResolver mTestContentResolver;
@@ -104,6 +107,8 @@ public class ImageTest {
});
when(mMockContext.getContentResolver()).thenReturn(mTestContentResolver);
+ when(mMockContext.getResources()).thenReturn(mMockResources);
+ when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images)).thenReturn(true);
}
@After
@@ -270,6 +275,55 @@ public class ImageTest {
}
/**
+ * Make sure no image is set when you create an Image from a MediaMetadata object that contains
+ * cover artwork as an Art Uri and Bluetooth is not configured to support URI images.
+ */
+ @Test
+ public void testCreateImageFromMediaMetadataWithArtUriDisabled() {
+ when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images))
+ .thenReturn(false);
+ MediaMetadata metadata =
+ getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_STRING_1);
+ Image artwork = new Image(mMockContext, metadata);
+ assertThat(artwork.getImage()).isNull();
+ assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_NONE);
+ assertThat(artwork.getImageHandle()).isNull();
+ }
+
+ /**
+ * Make sure no image is set when you create an Image from a MediaMetadata object that contains
+ * cover artwork as an Album Art Uri and Bluetooth is not configured to support URI images.
+ */
+ @Test
+ public void testCreateImageFromMediaMetadataWithAlbumArtUriDisabled() {
+ when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images))
+ .thenReturn(false);
+ MediaMetadata metadata =
+ getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, IMAGE_STRING_1);
+ Image artwork = new Image(mMockContext, metadata);
+ assertThat(artwork.getImage()).isNull();
+ assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_NONE);
+ assertThat(artwork.getImageHandle()).isNull();
+ }
+
+ /**
+ * Make sure no image is set when you create an Image from a MediaMetadata object that contains
+ * cover artwork as a Display Icon Uri and Bluetooth is not configured to support URI images.
+ */
+ @Test
+ public void testCreateImageFromMediaMetadataWithDisplayIconUriDisabled() {
+ when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images))
+ .thenReturn(false);
+ MediaMetadata metadata =
+ getMediaMetadataWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI,
+ IMAGE_STRING_1);
+ Image artwork = new Image(mMockContext, metadata);
+ assertThat(artwork.getImage()).isNull();
+ assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_NONE);
+ assertThat(artwork.getImageHandle()).isNull();
+ }
+
+ /**
* Make sure you can create an Image from a MediaMetadata object that contains no cover artwork
*/
@Test
@@ -398,6 +452,52 @@ public class ImageTest {
}
/**
+ * Make sure no image is set when you create an Image from a Bundle that contains cover artwork
+ * as an Art Uri and Bluetooth is not configured to support URI images.
+ */
+ @Test
+ public void testCreateImageFromBundleWithArtUriDisabled() {
+ when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images))
+ .thenReturn(false);
+ Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_ART_URI, IMAGE_STRING_1);
+ Image artwork = new Image(mMockContext, bundle);
+ assertThat(artwork.getImage()).isNull();
+ assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_NONE);
+ assertThat(artwork.getImageHandle()).isNull();
+ }
+
+ /**
+ * Make sure no image is set when you create an Image from a Bundle that contains cover artwork
+ * as an Album Art Uri and Bluetooth is not configured to support URI images.
+ */
+ @Test
+ public void testCreateImageFromBundleWithAlbumArtUriDisabled() {
+ when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images))
+ .thenReturn(false);
+ Bundle bundle = getBundleWithUri(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, IMAGE_STRING_1);
+ Image artwork = new Image(mMockContext, bundle);
+ assertThat(artwork.getImage()).isNull();
+ assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_NONE);
+ assertThat(artwork.getImageHandle()).isNull();
+ }
+
+ /**
+ * Make sure no image is set when you create an Image from a Bundle that contains cover artwork
+ * as a Display Icon Uri and Bluetooth is not configured to support URI images.
+ */
+ @Test
+ public void testCreateImageFromBundleWithDisplayIconUriDisabled() {
+ when(mMockResources.getBoolean(R.bool.avrcp_target_cover_art_uri_images))
+ .thenReturn(false);
+ Bundle bundle =
+ getBundleWithUri(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI, IMAGE_STRING_1);
+ Image artwork = new Image(mMockContext, bundle);
+ assertThat(artwork.getImage()).isNull();
+ assertThat(artwork.getSource()).isEqualTo(Image.SOURCE_NONE);
+ assertThat(artwork.getImageHandle()).isNull();
+ }
+
+ /**
* Make sure you can create an Image from a Bundle that contains no cover artwork
*/
@Test
diff --git a/system/audio_hal_interface/a2dp_encoding.cc b/system/audio_hal_interface/a2dp_encoding.cc
index 8217ff1e22..9ec6c49481 100644
--- a/system/audio_hal_interface/a2dp_encoding.cc
+++ b/system/audio_hal_interface/a2dp_encoding.cc
@@ -163,6 +163,8 @@ class A2dpTransport
}
}
+ void SinkMetadataChanged(const sink_metadata_t&) override {}
+
tA2DP_CTRL_CMD GetPendingCmd() const { return a2dp_pending_cmd_; }
void ResetPendingCmd() { a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE; }
diff --git a/system/audio_hal_interface/client_interface.cc b/system/audio_hal_interface/client_interface.cc
index fb2c532903..0b51d85a34 100644
--- a/system/audio_hal_interface/client_interface.cc
+++ b/system/audio_hal_interface/client_interface.cc
@@ -161,7 +161,18 @@ class BluetoothAudioPortImpl : public IBluetoothAudioPort {
Return<void> updateSinkMetadata(const SinkMetadata& sinkMetadata) override {
StopWatchLegacy stop_watch(__func__);
LOG(INFO) << __func__ << ": " << sinkMetadata.tracks.size() << " track(s)";
- // TODO: pass the metadata up to transport_instance and LE Audio
+ // refer to StreamIn.impl.h within Audio HAL (AUDIO_HAL_VERSION_5_0)
+ std::vector<record_track_metadata> metadata_vec;
+ metadata_vec.reserve(sinkMetadata.tracks.size());
+ for (const auto& metadata : sinkMetadata.tracks) {
+ metadata_vec.push_back({
+ .source = static_cast<audio_source_t>(metadata.source),
+ .gain = metadata.gain,
+ });
+ }
+ const sink_metadata_t sink_metadata = {.track_count = metadata_vec.size(),
+ .tracks = metadata_vec.data()};
+ transport_instance_->SinkMetadataChanged(sink_metadata);
return Void();
}
diff --git a/system/audio_hal_interface/client_interface.h b/system/audio_hal_interface/client_interface.h
index 795100b2d1..12e9878d8a 100644
--- a/system/audio_hal_interface/client_interface.h
+++ b/system/audio_hal_interface/client_interface.h
@@ -155,6 +155,7 @@ class IBluetoothTransportInstance {
timespec* data_position) = 0;
virtual void MetadataChanged(const source_metadata_t& source_metadata) = 0;
+ virtual void SinkMetadataChanged(const sink_metadata_t& sink_metadata) = 0;
// Invoked when the transport is requested to reset presentation position
virtual void ResetPresentationPosition() = 0;
diff --git a/system/audio_hal_interface/client_interface_unittest.cc b/system/audio_hal_interface/client_interface_unittest.cc
index bf3d6a6a47..423203fe7d 100644
--- a/system/audio_hal_interface/client_interface_unittest.cc
+++ b/system/audio_hal_interface/client_interface_unittest.cc
@@ -162,6 +162,8 @@ class TestSinkTransport
}
void MetadataChanged(
const source_metadata_t& source_metadata __unused) override {}
+ void SinkMetadataChanged(
+ const sink_metadata_t& sink_metadata __unused) override {}
void ResetPresentationPosition() override{};
void LogBytesRead(size_t bytes_readed __unused) override{};
};
@@ -200,6 +202,8 @@ class TestSourceTransport
}
void MetadataChanged(
const source_metadata_t& source_metadata __unused) override {}
+ void SinkMetadataChanged(
+ const sink_metadata_t& sink_metadata __unused) override {}
void ResetPresentationPosition() override{};
void LogBytesWritten(size_t bytes_written __unused) override{};
};
diff --git a/system/audio_hal_interface/hearing_aid_software_encoding.cc b/system/audio_hal_interface/hearing_aid_software_encoding.cc
index d2d4496ac6..aa405f6e20 100644
--- a/system/audio_hal_interface/hearing_aid_software_encoding.cc
+++ b/system/audio_hal_interface/hearing_aid_software_encoding.cc
@@ -106,6 +106,8 @@ class HearingAidTransport
}
}
+ void SinkMetadataChanged(const sink_metadata_t&) override {}
+
void ResetPresentationPosition() override {
VLOG(2) << __func__ << ": called.";
remote_delay_report_ms_ = 0;
diff --git a/system/audio_hal_interface/le_audio_software.cc b/system/audio_hal_interface/le_audio_software.cc
index 384518254b..795a0df410 100644
--- a/system/audio_hal_interface/le_audio_software.cc
+++ b/system/audio_hal_interface/le_audio_software.cc
@@ -119,6 +119,18 @@ class LeAudioTransport {
stream_cb_.on_metadata_update_(source_metadata);
}
+ void SinkMetadataChanged(const sink_metadata_t& sink_metadata) {
+ auto track_count = sink_metadata.track_count;
+
+ if (track_count == 0) {
+ LOG(WARNING) << ", invalid number of metadata changed tracks";
+ return;
+ }
+
+ if (stream_cb_.on_sink_metadata_update_)
+ stream_cb_.on_sink_metadata_update_(sink_metadata);
+ }
+
void ResetPresentationPosition() {
VLOG(2) << __func__ << ": called.";
remote_delay_report_ms_ = 0;
@@ -206,6 +218,10 @@ class LeAudioSinkTransport
transport_->MetadataChanged(source_metadata);
}
+ void SinkMetadataChanged(const sink_metadata_t& sink_metadata) override {
+ transport_->SinkMetadataChanged(sink_metadata);
+ }
+
void ResetPresentationPosition() override {
transport_->ResetPresentationPosition();
}
@@ -279,6 +295,10 @@ class LeAudioSourceTransport
transport_->MetadataChanged(source_metadata);
}
+ void SinkMetadataChanged(const sink_metadata_t& sink_metadata) override {
+ transport_->SinkMetadataChanged(sink_metadata);
+ }
+
void ResetPresentationPosition() override {
transport_->ResetPresentationPosition();
}
diff --git a/system/audio_hal_interface/le_audio_software.h b/system/audio_hal_interface/le_audio_software.h
index d595e6d673..e881a4c96d 100644
--- a/system/audio_hal_interface/le_audio_software.h
+++ b/system/audio_hal_interface/le_audio_software.h
@@ -44,6 +44,7 @@ struct StreamCallbacks {
std::function<bool(bool start_media_task)> on_resume_;
std::function<bool(void)> on_suspend_;
std::function<bool(const source_metadata_t&)> on_metadata_update_;
+ std::function<bool(const sink_metadata_t&)> on_sink_metadata_update_;
};
class LeAudioClientInterface {
diff --git a/system/bta/le_audio/client_audio.cc b/system/bta/le_audio/client_audio.cc
index baa4f6cf12..98cb14214f 100644
--- a/system/bta/le_audio/client_audio.cc
+++ b/system/bta/le_audio/client_audio.cc
@@ -245,6 +245,12 @@ bool le_audio_sink_on_metadata_update_req(
return false;
}
+bool le_audio_source_on_metadata_update_req(
+ const sink_metadata_t& sink_metadata) {
+ // TODO: update microphone configuration based on sink metadata
+ return true;
+}
+
} // namespace
bool LeAudioClientAudioSource::Start(
@@ -331,6 +337,7 @@ const void* LeAudioClientAudioSource::Acquire() {
.on_resume_ = le_audio_sink_on_resume_req,
.on_suspend_ = le_audio_sink_on_suspend_req,
.on_metadata_update_ = le_audio_sink_on_metadata_update_req,
+ .on_sink_metadata_update_ = le_audio_source_on_metadata_update_req,
};
sinkClientInterface =
@@ -492,6 +499,7 @@ const void* LeAudioClientAudioSink::Acquire() {
auto source_stream_cb = bluetooth::audio::le_audio::StreamCallbacks{
.on_resume_ = le_audio_source_on_resume_req,
.on_suspend_ = le_audio_source_on_suspend_req,
+ .on_sink_metadata_update_ = le_audio_source_on_metadata_update_req,
};
sourceClientInterface =
diff --git a/system/bta/pan/bta_pan_ci.cc b/system/bta/pan/bta_pan_ci.cc
index 00b218782d..9afe539fa9 100644
--- a/system/bta/pan/bta_pan_ci.cc
+++ b/system/bta/pan/bta_pan_ci.cc
@@ -26,8 +26,12 @@
#include "bta/pan/bta_pan_int.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
+#include "stack/include/btu.h"
#include "types/raw_address.h"
+void bta_pan_sm_execute(tBTA_PAN_SCB* p_scb, uint16_t event,
+ tBTA_PAN_DATA* p_data);
+
/*******************************************************************************
*
* Function bta_pan_ci_tx_ready