Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +3 −1 Original line number Diff line number Diff line Loading @@ -936,7 +936,9 @@ public class LeAudioService extends ProfileService { } if (groupId == currentlyActiveGroupId) { Log.w(TAG, "group is already active"); if (groupId != LE_AUDIO_GROUP_ID_INVALID) { Log.w(TAG, "group is already active: device=" + device + ", groupId = " + groupId); } return; } Loading android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +28 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ import android.os.Looper; import android.util.Log; import android.util.Pair; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.le_audio.LeAudioService; import com.android.internal.annotations.VisibleForTesting; import java.nio.ByteBuffer; Loading @@ -52,6 +56,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; /** Loading Loading @@ -134,6 +139,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private MediaState mCurrentMediaState = MediaState.INACTIVE; private Map<BluetoothDevice, List<GattOpContext>> mPendingGattOperations = new HashMap<>(); private McpService mMcpService; private LeAudioService mLeAudioService; private AdapterService mAdapterService; private static class GattOpContext { public enum Operation { Loading Loading @@ -295,7 +302,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (VDBG) { Log.d(TAG, "MEDIA_CONTROL_POINT write request"); } int status = handleMediaControlPointRequest(value); int status = handleMediaControlPointRequest(device, value); if (responseNeeded) { mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); } Loading Loading @@ -784,6 +791,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mCcid = ccid; mMcpService = mcpService; mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), "AdapterService shouldn't be null when creating MediaControlCattService"); } protected boolean init(UUID scvUuid) { Loading Loading @@ -836,7 +845,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } @VisibleForTesting int handleMediaControlPointRequest(byte[] value) { int handleMediaControlPointRequest(BluetoothDevice device, byte[] value) { if (DBG) { Log.d(TAG, "handleMediaControlPointRequest"); } Loading Loading @@ -880,6 +889,18 @@ public class MediaControlGattService implements MediaControlGattServiceInterface Log.d(TAG, "handleMediaControlPointRequest: sending request up"); } if (req.getOpcode() == Request.Opcodes.PLAY) { if (mAdapterService.getActiveDevices(BluetoothProfile.A2DP).size() > 0) { A2dpService.getA2dpService().setActiveDevice(null); } if (mAdapterService.getActiveDevices(BluetoothProfile.HEARING_AID).size() > 0) { HearingAidService.getHearingAidService().setActiveDevice(null); } if (mLeAudioService == null) { mLeAudioService = LeAudioService.getLeAudioService(); } mLeAudioService.setActiveDevice(device); } mCallbacks.onMediaControlRequest(req); return BluetoothGatt.GATT_SUCCESS; Loading @@ -899,6 +920,11 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mBluetoothGattServer = proxy; } @VisibleForTesting void setLeAudioServiceForTesting(LeAudioService leAudioService) { mLeAudioService = leAudioService; } private boolean initGattService(UUID serviceUuid) { if (DBG) { Log.d(TAG, "initGattService uuid: " + serviceUuid); Loading android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java +16 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.le_audio.LeAudioService; import org.junit.After; import org.junit.Assert; Loading Loading @@ -71,6 +72,7 @@ public class MediaControlGattServiceTest { @Mock private AdapterService mAdapterService; @Mock private MediaControlGattService.BluetoothGattServerProxy mMockGattServer; @Mock private McpService mMockMcpService; @Mock private LeAudioService mMockLeAudioService; @Mock private MediaControlServiceCallbacks mMockMcsCallbacks; @Captor private ArgumentCaptor<BluetoothGattService> mGattServiceCaptor; Loading @@ -92,6 +94,7 @@ public class MediaControlGattServiceTest { mMcpService = new MediaControlGattService(mMockMcpService, mMockMcsCallbacks, TEST_CCID); mMcpService.setBluetoothGattServerForTesting(mMockGattServer); mMcpService.setServiceManagerForTesting(mMockMcpService); mMcpService.setLeAudioServiceForTesting(mMockLeAudioService); when(mMockMcpService.getDeviceAuthorization(any(BluetoothDevice.class))).thenReturn( BluetoothDevice.ACCESS_ALLOWED); Loading @@ -103,6 +106,7 @@ public class MediaControlGattServiceTest { reset(mMockGattServer); reset(mMockMcpService); reset(mMockMcsCallbacks); reset(mMockLeAudioService); TestUtils.clearAdapterService(mAdapterService); } Loading Loading @@ -823,8 +827,8 @@ public class MediaControlGattServiceTest { bb.putInt(value); } Assert.assertEquals( expectedGattResult, mMcpService.handleMediaControlPointRequest(bb.array())); Assert.assertEquals(expectedGattResult, mMcpService.handleMediaControlPointRequest(mCurrentDevice, bb.array())); if (expectedGattResult == BluetoothGatt.GATT_SUCCESS) { // Verify if callback comes to profile Loading Loading @@ -931,6 +935,16 @@ public class MediaControlGattServiceTest { mMcpService.isOpcodeSupported(Request.Opcodes.PLAY)); } @Test public void testMediaControlPointeRequest_OpcodePlayCallLeAudioServiceSetActiveDevice() { BluetoothGattService service = initAllFeaturesGattService(); prepareConnectedDevice(); mMcpService.updateSupportedOpcodesChar(Request.SupportedOpcodes.PLAY, true); verifyMediaControlPointRequest(service, Request.Opcodes.PLAY, null, BluetoothGatt.GATT_SUCCESS, 1); verify(mMockLeAudioService).setActiveDevice(any(BluetoothDevice.class)); } @Test public void testPlaybackSpeedWrite() { BluetoothGattService service = initAllFeaturesGattService(); Loading Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +3 −1 Original line number Diff line number Diff line Loading @@ -936,7 +936,9 @@ public class LeAudioService extends ProfileService { } if (groupId == currentlyActiveGroupId) { Log.w(TAG, "group is already active"); if (groupId != LE_AUDIO_GROUP_ID_INVALID) { Log.w(TAG, "group is already active: device=" + device + ", groupId = " + groupId); } return; } Loading
android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +28 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,10 @@ import android.os.Looper; import android.util.Log; import android.util.Pair; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.hearingaid.HearingAidService; import com.android.bluetooth.le_audio.LeAudioService; import com.android.internal.annotations.VisibleForTesting; import java.nio.ByteBuffer; Loading @@ -52,6 +56,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; /** Loading Loading @@ -134,6 +139,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private MediaState mCurrentMediaState = MediaState.INACTIVE; private Map<BluetoothDevice, List<GattOpContext>> mPendingGattOperations = new HashMap<>(); private McpService mMcpService; private LeAudioService mLeAudioService; private AdapterService mAdapterService; private static class GattOpContext { public enum Operation { Loading Loading @@ -295,7 +302,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (VDBG) { Log.d(TAG, "MEDIA_CONTROL_POINT write request"); } int status = handleMediaControlPointRequest(value); int status = handleMediaControlPointRequest(device, value); if (responseNeeded) { mBluetoothGattServer.sendResponse(device, requestId, status, offset, value); } Loading Loading @@ -784,6 +791,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mCcid = ccid; mMcpService = mcpService; mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(), "AdapterService shouldn't be null when creating MediaControlCattService"); } protected boolean init(UUID scvUuid) { Loading Loading @@ -836,7 +845,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } @VisibleForTesting int handleMediaControlPointRequest(byte[] value) { int handleMediaControlPointRequest(BluetoothDevice device, byte[] value) { if (DBG) { Log.d(TAG, "handleMediaControlPointRequest"); } Loading Loading @@ -880,6 +889,18 @@ public class MediaControlGattService implements MediaControlGattServiceInterface Log.d(TAG, "handleMediaControlPointRequest: sending request up"); } if (req.getOpcode() == Request.Opcodes.PLAY) { if (mAdapterService.getActiveDevices(BluetoothProfile.A2DP).size() > 0) { A2dpService.getA2dpService().setActiveDevice(null); } if (mAdapterService.getActiveDevices(BluetoothProfile.HEARING_AID).size() > 0) { HearingAidService.getHearingAidService().setActiveDevice(null); } if (mLeAudioService == null) { mLeAudioService = LeAudioService.getLeAudioService(); } mLeAudioService.setActiveDevice(device); } mCallbacks.onMediaControlRequest(req); return BluetoothGatt.GATT_SUCCESS; Loading @@ -899,6 +920,11 @@ public class MediaControlGattService implements MediaControlGattServiceInterface mBluetoothGattServer = proxy; } @VisibleForTesting void setLeAudioServiceForTesting(LeAudioService leAudioService) { mLeAudioService = leAudioService; } private boolean initGattService(UUID serviceUuid) { if (DBG) { Log.d(TAG, "initGattService uuid: " + serviceUuid); Loading
android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java +16 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.le_audio.LeAudioService; import org.junit.After; import org.junit.Assert; Loading Loading @@ -71,6 +72,7 @@ public class MediaControlGattServiceTest { @Mock private AdapterService mAdapterService; @Mock private MediaControlGattService.BluetoothGattServerProxy mMockGattServer; @Mock private McpService mMockMcpService; @Mock private LeAudioService mMockLeAudioService; @Mock private MediaControlServiceCallbacks mMockMcsCallbacks; @Captor private ArgumentCaptor<BluetoothGattService> mGattServiceCaptor; Loading @@ -92,6 +94,7 @@ public class MediaControlGattServiceTest { mMcpService = new MediaControlGattService(mMockMcpService, mMockMcsCallbacks, TEST_CCID); mMcpService.setBluetoothGattServerForTesting(mMockGattServer); mMcpService.setServiceManagerForTesting(mMockMcpService); mMcpService.setLeAudioServiceForTesting(mMockLeAudioService); when(mMockMcpService.getDeviceAuthorization(any(BluetoothDevice.class))).thenReturn( BluetoothDevice.ACCESS_ALLOWED); Loading @@ -103,6 +106,7 @@ public class MediaControlGattServiceTest { reset(mMockGattServer); reset(mMockMcpService); reset(mMockMcsCallbacks); reset(mMockLeAudioService); TestUtils.clearAdapterService(mAdapterService); } Loading Loading @@ -823,8 +827,8 @@ public class MediaControlGattServiceTest { bb.putInt(value); } Assert.assertEquals( expectedGattResult, mMcpService.handleMediaControlPointRequest(bb.array())); Assert.assertEquals(expectedGattResult, mMcpService.handleMediaControlPointRequest(mCurrentDevice, bb.array())); if (expectedGattResult == BluetoothGatt.GATT_SUCCESS) { // Verify if callback comes to profile Loading Loading @@ -931,6 +935,16 @@ public class MediaControlGattServiceTest { mMcpService.isOpcodeSupported(Request.Opcodes.PLAY)); } @Test public void testMediaControlPointeRequest_OpcodePlayCallLeAudioServiceSetActiveDevice() { BluetoothGattService service = initAllFeaturesGattService(); prepareConnectedDevice(); mMcpService.updateSupportedOpcodesChar(Request.SupportedOpcodes.PLAY, true); verifyMediaControlPointRequest(service, Request.Opcodes.PLAY, null, BluetoothGatt.GATT_SUCCESS, 1); verify(mMockLeAudioService).setActiveDevice(any(BluetoothDevice.class)); } @Test public void testPlaybackSpeedWrite() { BluetoothGattService service = initAllFeaturesGattService(); Loading