Loading android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +13 −0 Original line number Diff line number Diff line Loading @@ -34,9 +34,11 @@ import android.os.Looper; import android.os.SystemProperties; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.Utils; import com.android.bluetooth.avrcp.AvrcpPassthrough; import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -310,6 +312,17 @@ public class MediaPlayerList { return mMediaPlayers.get(mActivePlayerId); } /** This is used to send passthrough command to media session */ public void sendMediaKeyEvent(int key, boolean pushed) { if (mMediaSessionManager == null) { Log.d(TAG, "Bluetooth is turning off, ignore it"); return; } int action = pushed ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP; KeyEvent event = new KeyEvent(action, AvrcpPassthrough.toKeyCode(key)); mMediaSessionManager.dispatchMediaKeyEvent(event, false); } /** * This is used by setBrowsedPlayer as the browsed player is always the Bluetooth player. * Loading android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.bluetooth.avrcp; import android.bluetooth.BluetoothAvrcp; import android.view.KeyEvent; class AvrcpPassthrough { public class AvrcpPassthrough { public static int toKeyCode(int operation) { switch (operation) { case BluetoothAvrcp.PASSTHROUGH_ID_UP: Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +4 −5 Original line number Diff line number Diff line Loading @@ -247,6 +247,8 @@ public class LeAudioService extends ProfileService { LeAudioGroupDescriptor(boolean isInbandRingtonEnabled) { mIsConnected = false; mActiveState = ACTIVE_STATE_INACTIVE; mAllowedSinkContexts = BluetoothLeAudio.CONTEXTS_ALL; mAllowedSourceContexts = BluetoothLeAudio.CONTEXTS_ALL; mHasFallbackDeviceWhenGettingInactive = false; mDirection = AUDIO_DIRECTION_NONE; mCodecStatus = null; Loading Loading @@ -338,11 +340,8 @@ public class LeAudioService extends ProfileService { } boolean areAllowedContextsModified() { if ((mAllowedSinkContexts != BluetoothLeAudio.CONTEXTS_ALL) || (mAllowedSourceContexts != BluetoothLeAudio.CONTEXTS_ALL)) { return true; } return false; return (mAllowedSinkContexts != BluetoothLeAudio.CONTEXTS_ALL) || (mAllowedSourceContexts != BluetoothLeAudio.CONTEXTS_ALL); } } Loading android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java +20 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.mcp; import static java.util.Map.entry; import android.annotation.NonNull; import android.bluetooth.BluetoothAvrcp; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothUuid; Loading @@ -36,6 +37,7 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.audio_util.MediaData; import com.android.bluetooth.audio_util.MediaPlayerList; import com.android.bluetooth.audio_util.MediaPlayerWrapper; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.le_audio.ContentControlIdKeeper; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -402,8 +404,24 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { + Request.Opcodes.toString(request.getOpcode())); Request.Results status = Request.Results.COMMAND_CANNOT_BE_COMPLETED; if (mMediaPlayerList.getActivePlayer() == null && mGMcsService != null) { if (Flags.mcpAllowPlayWithoutActivePlayer() && !Utils.isPtsTestMode() && mMediaPlayerList.getActivePlayer() == null && request.getOpcode() == Request.Opcodes.PLAY) { Log.d(TAG, "Player is not active. GMCS send media key for PLAY"); mMediaPlayerList.sendMediaKeyEvent(BluetoothAvrcp.PASSTHROUGH_ID_PLAY, true); mMediaPlayerList.sendMediaKeyEvent(BluetoothAvrcp.PASSTHROUGH_ID_PLAY, false); return; } if (mMediaPlayerList.getActivePlayer() == null || mCurrentData.state == null) { Log.w(TAG, "no active MediaPlayer or mCurrentData is null"); if (mGMcsService != null) { mGMcsService.setMediaControlRequestResult(request, status); } else { Log.e(TAG, "mGMcsService is null"); } return; } long actions = getCurrentPlayerSupportedActions(); Loading flags/mcp.aconfig 0 → 100644 +13 −0 Original line number Diff line number Diff line package: "com.android.bluetooth.flags" container: "com.android.btservices" flag { name: "mcp_allow_play_without_active_player" namespace: "bluetooth" description: "Handle LeAudio play same as in AVRCP in case player is not active" bug: "337169240" metadata { purpose: PURPOSE_BUGFIX } } Loading
android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +13 −0 Original line number Diff line number Diff line Loading @@ -34,9 +34,11 @@ import android.os.Looper; import android.os.SystemProperties; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.Utils; import com.android.bluetooth.avrcp.AvrcpPassthrough; import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -310,6 +312,17 @@ public class MediaPlayerList { return mMediaPlayers.get(mActivePlayerId); } /** This is used to send passthrough command to media session */ public void sendMediaKeyEvent(int key, boolean pushed) { if (mMediaSessionManager == null) { Log.d(TAG, "Bluetooth is turning off, ignore it"); return; } int action = pushed ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP; KeyEvent event = new KeyEvent(action, AvrcpPassthrough.toKeyCode(key)); mMediaSessionManager.dispatchMediaKeyEvent(event, false); } /** * This is used by setBrowsedPlayer as the browsed player is always the Bluetooth player. * Loading
android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.bluetooth.avrcp; import android.bluetooth.BluetoothAvrcp; import android.view.KeyEvent; class AvrcpPassthrough { public class AvrcpPassthrough { public static int toKeyCode(int operation) { switch (operation) { case BluetoothAvrcp.PASSTHROUGH_ID_UP: Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +4 −5 Original line number Diff line number Diff line Loading @@ -247,6 +247,8 @@ public class LeAudioService extends ProfileService { LeAudioGroupDescriptor(boolean isInbandRingtonEnabled) { mIsConnected = false; mActiveState = ACTIVE_STATE_INACTIVE; mAllowedSinkContexts = BluetoothLeAudio.CONTEXTS_ALL; mAllowedSourceContexts = BluetoothLeAudio.CONTEXTS_ALL; mHasFallbackDeviceWhenGettingInactive = false; mDirection = AUDIO_DIRECTION_NONE; mCodecStatus = null; Loading Loading @@ -338,11 +340,8 @@ public class LeAudioService extends ProfileService { } boolean areAllowedContextsModified() { if ((mAllowedSinkContexts != BluetoothLeAudio.CONTEXTS_ALL) || (mAllowedSourceContexts != BluetoothLeAudio.CONTEXTS_ALL)) { return true; } return false; return (mAllowedSinkContexts != BluetoothLeAudio.CONTEXTS_ALL) || (mAllowedSourceContexts != BluetoothLeAudio.CONTEXTS_ALL); } } Loading
android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java +20 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.mcp; import static java.util.Map.entry; import android.annotation.NonNull; import android.bluetooth.BluetoothAvrcp; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothUuid; Loading @@ -36,6 +37,7 @@ import com.android.bluetooth.Utils; import com.android.bluetooth.audio_util.MediaData; import com.android.bluetooth.audio_util.MediaPlayerList; import com.android.bluetooth.audio_util.MediaPlayerWrapper; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.le_audio.ContentControlIdKeeper; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -402,8 +404,24 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { + Request.Opcodes.toString(request.getOpcode())); Request.Results status = Request.Results.COMMAND_CANNOT_BE_COMPLETED; if (mMediaPlayerList.getActivePlayer() == null && mGMcsService != null) { if (Flags.mcpAllowPlayWithoutActivePlayer() && !Utils.isPtsTestMode() && mMediaPlayerList.getActivePlayer() == null && request.getOpcode() == Request.Opcodes.PLAY) { Log.d(TAG, "Player is not active. GMCS send media key for PLAY"); mMediaPlayerList.sendMediaKeyEvent(BluetoothAvrcp.PASSTHROUGH_ID_PLAY, true); mMediaPlayerList.sendMediaKeyEvent(BluetoothAvrcp.PASSTHROUGH_ID_PLAY, false); return; } if (mMediaPlayerList.getActivePlayer() == null || mCurrentData.state == null) { Log.w(TAG, "no active MediaPlayer or mCurrentData is null"); if (mGMcsService != null) { mGMcsService.setMediaControlRequestResult(request, status); } else { Log.e(TAG, "mGMcsService is null"); } return; } long actions = getCurrentPlayerSupportedActions(); Loading
flags/mcp.aconfig 0 → 100644 +13 −0 Original line number Diff line number Diff line package: "com.android.bluetooth.flags" container: "com.android.btservices" flag { name: "mcp_allow_play_without_active_player" namespace: "bluetooth" description: "Handle LeAudio play same as in AVRCP in case player is not active" bug: "337169240" metadata { purpose: PURPOSE_BUGFIX } }