Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 273825ed authored by Iván Budnik's avatar Iván Budnik Committed by Android (Google) Code Review
Browse files

Merge "Avoid null connected devices when updating routing information" into main

parents 634beed8 a68b5fb8
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -254,8 +254,6 @@ public abstract class InfoMediaManager {
    protected abstract List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName);

    protected final void rebuildDeviceList() {
        mMediaDevices.clear();
        mCurrentConnectedDevice = null;
        buildAvailableRoutes();
    }

@@ -524,6 +522,7 @@ public abstract class InfoMediaManager {
    // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
    @SuppressWarnings("NewApi")
    private synchronized void buildAvailableRoutes() {
        mMediaDevices.clear();
        RoutingSessionInfo activeSession = getActiveRoutingSession();

        for (MediaRoute2Info route : getAvailableRoutes(activeSession)) {
@@ -533,6 +532,12 @@ public abstract class InfoMediaManager {
            }
            addMediaDevice(route, activeSession);
        }

        // In practice, mMediaDevices should always have at least one route.
        if (!mMediaDevices.isEmpty()) {
            // First device on the list is always the first selected route.
            mCurrentConnectedDevice = mMediaDevices.get(0);
        }
    }

    private synchronized List<MediaRoute2Info> getAvailableRoutes(
@@ -643,9 +648,6 @@ public abstract class InfoMediaManager {
        if (mediaDevice != null) {
            if (activeSession.getSelectedRoutes().contains(route.getId())) {
                mediaDevice.setState(STATE_SELECTED);
                if (mCurrentConnectedDevice == null) {
                    mCurrentConnectedDevice = mediaDevice;
                }
            }
            mMediaDevices.add(mediaDevice);
        }
+42 −55
Original line number Diff line number Diff line
@@ -110,6 +110,17 @@ public class InfoMediaManagerTest {
                    .setAddress("00:00:00:00:00:00")
                    .build();

    private static final RoutingSessionInfo TEST_REMOTE_ROUTING_SESSION =
            new RoutingSessionInfo.Builder("FAKE_REMOTE_ROUTING_SESSION_ID", TEST_PACKAGE_NAME)
                    .addSelectedRoute(TEST_ID_1)
                    .build();

    private static final MediaRoute2Info TEST_REMOTE_ROUTE =
            new MediaRoute2Info.Builder(TEST_ID_1, "REMOTE_ROUTE")
                    .setSystemRoute(true)
                    .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
                    .build();

    @Mock
    private MediaRouter2Manager mRouterManager;
    @Mock
@@ -151,7 +162,10 @@ public class InfoMediaManagerTest {
        RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
        mInfoMediaManager.mRouterManager = mRouterManager;
        // Since test is running in Robolectric, return a fake session to avoid NPE.
        when(mRouterManager.getRoutingSessions(anyString())).thenReturn(List.of(sessionInfo));
        when(mRouterManager.getRoutingSessions(anyString()))
                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION));
        when(mRouterManager.getSelectedRoutes(any()))
                .thenReturn(List.of(TEST_SELECTED_SYSTEM_ROUTE));

        mInfoMediaManager.startScan();
        mInfoMediaManager.stopScan();
@@ -191,52 +205,27 @@ public class InfoMediaManagerTest {

    @Test
    public void onSessionReleased_shouldUpdateConnectedDevice() {
        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
        final RoutingSessionInfo sessionInfo1 = mock(RoutingSessionInfo.class);
        routingSessionInfos.add(sessionInfo1);
        final RoutingSessionInfo sessionInfo2 = mock(RoutingSessionInfo.class);
        routingSessionInfos.add(sessionInfo2);

        final List<String> selectedRoutesSession1 = new ArrayList<>();
        selectedRoutesSession1.add(TEST_ID_1);
        when(sessionInfo1.getSelectedRoutes()).thenReturn(selectedRoutesSession1);

        final List<String> selectedRoutesSession2 = new ArrayList<>();
        selectedRoutesSession2.add(TEST_ID_2);
        when(sessionInfo2.getSelectedRoutes()).thenReturn(selectedRoutesSession2);

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);

        final MediaRoute2Info info1 = mock(MediaRoute2Info.class);
        when(info1.getId()).thenReturn(TEST_ID_1);
        when(info1.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        final MediaRoute2Info info2 = mock(MediaRoute2Info.class);
        when(info2.getId()).thenReturn(TEST_ID_2);
        when(info2.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        final List<MediaRoute2Info> routes = new ArrayList<>();
        routes.add(info1);
        routes.add(info2);
        mShadowRouter2Manager.setAllRoutes(routes);
        mShadowRouter2Manager.setTransferableRoutes(routes);
        mInfoMediaManager.mRouterManager = mRouterManager;

        final MediaDevice mediaDevice1 = mInfoMediaManager.findMediaDevice(TEST_ID_1);
        assertThat(mediaDevice1).isNull();
        final MediaDevice mediaDevice2 = mInfoMediaManager.findMediaDevice(TEST_ID_2);
        assertThat(mediaDevice2).isNull();
        // Active routing session is last one in list.
        when(mRouterManager.getRoutingSessions(anyString()))
                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION, TEST_REMOTE_ROUTING_SESSION));
        when(mRouterManager.getSelectedRoutes(TEST_SYSTEM_ROUTING_SESSION))
                .thenReturn(List.of(TEST_SELECTED_SYSTEM_ROUTE));
        when(mRouterManager.getSelectedRoutes(TEST_REMOTE_ROUTING_SESSION))
                .thenReturn(List.of(TEST_REMOTE_ROUTE));

        mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
        final MediaDevice infoDevice1 = mInfoMediaManager.mMediaDevices.get(0);
        assertThat(infoDevice1.getId()).isEqualTo(TEST_ID_1);
        final MediaDevice infoDevice2 = mInfoMediaManager.mMediaDevices.get(1);
        assertThat(infoDevice2.getId()).isEqualTo(TEST_ID_2);
        // The active routing session is the last one in the list, which maps to infoDevice2.
        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice2);
        MediaDevice remoteDevice = mInfoMediaManager.findMediaDevice(TEST_REMOTE_ROUTE.getId());
        assertThat(remoteDevice).isNotNull();
        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(remoteDevice);

        routingSessionInfos.remove(sessionInfo2);
        mInfoMediaManager.mMediaRouterCallback.onSessionReleased(sessionInfo2);
        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice1);
        when(mRouterManager.getRoutingSessions(anyString()))
                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION));
        mInfoMediaManager.mMediaRouterCallback.onSessionReleased(TEST_REMOTE_ROUTING_SESSION);
        MediaDevice systemRoute = mInfoMediaManager.findMediaDevice(TEST_SYSTEM_ROUTE_ID);
        assertThat(systemRoute).isNotNull();
        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(systemRoute);
    }

    @Test
@@ -794,18 +783,16 @@ public class InfoMediaManagerTest {

    @Test
    public void onSessionUpdated_shouldDispatchDeviceListAdded() {
        final MediaRoute2Info info = mock(MediaRoute2Info.class);
        when(info.getId()).thenReturn(TEST_ID);
        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
        when(info.isSystemRoute()).thenReturn(true);

        final List<MediaRoute2Info> routes = new ArrayList<>();
        routes.add(info);
        mShadowRouter2Manager.setAllRoutes(routes);
        mInfoMediaManager.mRouterManager = mRouterManager;
        // Since test is running in Robolectric, return a fake session to avoid NPE.
        when(mRouterManager.getRoutingSessions(anyString()))
                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION));
        when(mRouterManager.getSelectedRoutes(any()))
                .thenReturn(List.of(TEST_SELECTED_SYSTEM_ROUTE));

        mInfoMediaManager.registerCallback(mCallback);

        mInfoMediaManager.mMediaRouterCallback.onSessionUpdated(mock(RoutingSessionInfo.class));
        mInfoMediaManager.mMediaRouterCallback.onSessionUpdated(TEST_SYSTEM_ROUTING_SESSION);

        verify(mCallback).onDeviceListAdded(any());
    }
@@ -871,7 +858,7 @@ public class InfoMediaManagerTest {
    }

    @Test
    public void addMediaDevice_deviceIncludedInSelectedDevices_shouldSetAsCurrentConnected() {
    public void onRoutesUpdated_setsFirstSelectedRouteAsCurrentConnectedDevice() {
        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
                mock(CachedBluetoothDeviceManager.class);

@@ -886,14 +873,14 @@ public class InfoMediaManagerTest {

        when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME))
                .thenReturn(List.of(selectedBtSession));
        when(mRouterManager.getSelectedRoutes(any())).thenReturn(List.of(TEST_BLUETOOTH_ROUTE));
        when(mLocalBluetoothManager.getCachedDeviceManager())
                .thenReturn(cachedBluetoothDeviceManager);
        when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
                .thenReturn(cachedDevice);
        mInfoMediaManager.mRouterManager = mRouterManager;

        mInfoMediaManager.mMediaDevices.clear();
        mInfoMediaManager.addMediaDevice(TEST_BLUETOOTH_ROUTE, selectedBtSession);
        mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();

        MediaDevice device = mInfoMediaManager.mMediaDevices.get(0);

+8 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.media.dialog;
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -47,6 +48,7 @@ import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.media.LocalMediaManager;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogTransitionAnimator;
import com.android.systemui.broadcast.BroadcastSender;
@@ -127,6 +129,12 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
                mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
                mKeyguardManager, mFlags, mUserTracker);

        // Using a fake package will cause routing operations to fail, so we intercept
        // scanning-related operations.
        mMediaOutputController.mLocalMediaManager = mock(LocalMediaManager.class);
        doNothing().when(mMediaOutputController.mLocalMediaManager).startScan();
        doNothing().when(mMediaOutputController.mLocalMediaManager).stopScan();

        mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender,
                mMediaOutputController);
        mMediaOutputBaseDialogImpl.onCreate(new Bundle());