Merge "Show "Stream paused" when hysteresis mode in UMO." into main

This commit is contained in:
Chelsea Hao
2025-02-05 18:50:40 -08:00
committed by Android (Google) Code Review
3 changed files with 117 additions and 3 deletions

View File

@@ -16,6 +16,9 @@
package com.android.settings.connecteddevice.audiosharing.audiostreams;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -23,6 +26,7 @@ import android.app.Service;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothVolumeControl;
import android.content.Intent;
@@ -64,7 +68,8 @@ public class AudioStreamMediaService extends Service {
static final String DEVICES = "audio_stream_media_service_devices";
private static final String TAG = "AudioStreamMediaService";
private static final int NOTIFICATION_ID = 1;
private static final int BROADCAST_CONTENT_TEXT = R.string.audio_streams_listening_now;
private static final int BROADCAST_LISTENING_NOW_TEXT = R.string.audio_streams_listening_now;
private static final int BROADCAST_STREAM_PAUSED_TEXT = R.string.audio_streams_present_now;
@VisibleForTesting static final String LEAVE_BROADCAST_ACTION = "leave_broadcast_action";
private static final String LEAVE_BROADCAST_TEXT = "Leave Broadcast";
private static final String CHANNEL_ID = "bluetooth_notification_channel";
@@ -94,11 +99,22 @@ public class AudioStreamMediaService extends Service {
LEAVE_BROADCAST_ACTION,
LEAVE_BROADCAST_TEXT,
com.android.settings.R.drawable.ic_clear);
private final PlaybackState.Builder mPlayStateHysteresisBuilder =
new PlaybackState.Builder()
.setState(
PlaybackState.STATE_STOPPED,
STATIC_PLAYBACK_POSITION,
ZERO_PLAYBACK_SPEED)
.addCustomAction(
LEAVE_BROADCAST_ACTION,
LEAVE_BROADCAST_TEXT,
com.android.settings.R.drawable.ic_clear);
private final MetricsFeatureProvider mMetricsFeatureProvider =
FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private final AtomicBoolean mIsMuted = new AtomicBoolean(false);
private final AtomicBoolean mIsHysteresis = new AtomicBoolean(false);
// Set 25 as default as the volume range from `VolumeControlProfile` is from 0 to 255.
// If the initial volume from `onDeviceVolumeChanged` is larger than zero (not muted), we will
// override this value. Otherwise, we raise the volume to 25 when the play button is clicked.
@@ -255,6 +271,9 @@ public class AudioStreamMediaService extends Service {
}
private PlaybackState getPlaybackState() {
if (mIsHysteresis.get()) {
return mPlayStateHysteresisBuilder.build();
}
return mIsMuted.get() ? mPlayStatePausingBuilder.build() : mPlayStatePlayingBuilder.build();
}
@@ -283,7 +302,9 @@ public class AudioStreamMediaService extends Service {
new Notification.Builder(this, CHANNEL_ID)
.setSmallIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
.setStyle(mediaStyle)
.setContentText(getString(BROADCAST_CONTENT_TEXT))
.setContentText(getString(
mIsHysteresis.get() ? BROADCAST_STREAM_PAUSED_TEXT :
BROADCAST_LISTENING_NOW_TEXT))
.setSilent(true);
return notificationBuilder.build();
}
@@ -307,6 +328,38 @@ public class AudioStreamMediaService extends Service {
handleRemoveSource();
}
@Override
public void onReceiveStateChanged(
BluetoothDevice sink, int sourceId, BluetoothLeBroadcastReceiveState state) {
super.onReceiveStateChanged(sink, sourceId, state);
if (!mHysteresisModeFixAvailable || mDevices == null || !mDevices.contains(sink)) {
return;
}
var sourceState = LocalBluetoothLeBroadcastAssistant.getLocalSourceState(state);
boolean streaming = sourceState == STREAMING;
boolean paused = sourceState == PAUSED;
// Exit early if the state is neither streaming nor paused
if (!streaming && !paused) {
return;
}
// Atomically update mIsHysteresis if its current value is not the current paused state
if (mIsHysteresis.compareAndSet(!paused, paused)) {
synchronized (mLocalSessionLock) {
if (mLocalSession == null) {
return;
}
mLocalSession.setPlaybackState(getPlaybackState());
if (mNotificationManager != null) {
mNotificationManager.notify(
NOTIFICATION_ID,
buildNotification(mLocalSession.getSessionToken())
);
}
Log.d(TAG, "updating hysteresis mode to : " + paused);
}
}
}
private void handleRemoveSource() {
if (mAudioStreamsHelper != null
&& !mAudioStreamsHelper.getConnectedBroadcastIdAndState(