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

Commit 8f09b042 authored by Vidhi Shah's avatar Vidhi Shah Committed by Android (Google) Code Review
Browse files

Merge "Stop route scanning after succesfully connecting to route." into main

parents 265c2486 0a36da2f
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
import static android.media.session.MediaController.PlaybackInfo;

import static com.android.media.flags.Flags.avoidBinderCallsDuringRender;
import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_CONNECTED;
import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_CONNECTING;
import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED;
import static com.android.settingslib.media.LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED;
@@ -140,7 +141,7 @@ public abstract class InfoMediaManager {
    }

    /**
     * Wrapper class around SuggestedDeviceInfo and the corresponsing connection state of the
     * Wrapper class around SuggestedDeviceInfo and the corresponding connection state of the
     * suggestion.
     */
    public static class SuggestedDeviceState {
@@ -833,19 +834,16 @@ public abstract class InfoMediaManager {
        }
    }

    final void onConnectionAttemptCompletedForSuggestion(@NonNull SuggestedDeviceState suggestion) {
    final void onConnectionAttemptCompletedForSuggestion(
            @NonNull SuggestedDeviceState suggestion, boolean success) {
        if (!Objects.equals(suggestion, mSuggestedDeviceState)) {
            return;
        }
        if (mSuggestedDeviceState.getConnectionState() == STATE_CONNECTING
                || mSuggestedDeviceState.getConnectionState() == STATE_GROUPING) {
        int state = success ? STATE_CONNECTED : STATE_CONNECTING_FAILED;
        mSuggestedDeviceState =
                    new SuggestedDeviceState(
                            mSuggestedDeviceState.getSuggestedDeviceInfo(),
                            STATE_CONNECTING_FAILED);
                new SuggestedDeviceState(mSuggestedDeviceState.getSuggestedDeviceInfo(), state);
        dispatchOnSuggestedDeviceUpdated();
    }
    }

    private void dispatchOnSuggestedDeviceUpdated() {
        for (MediaDeviceCallback callback : getCallbacks()) {
+54 −36
Original line number Diff line number Diff line
@@ -240,9 +240,7 @@ public class LocalMediaManager implements BluetoothCallback {
                    return;
                }
            }
            mConnectingSuggestedDeviceState =
                    new ConnectingSuggestedDeviceState(
                            currentSuggestion, mConnectSuggestedDeviceHandler);
            mConnectingSuggestedDeviceState = new ConnectingSuggestedDeviceState(currentSuggestion);
            mConnectingSuggestedDeviceState.tryConnect();
        }
    }
@@ -269,20 +267,6 @@ public class LocalMediaManager implements BluetoothCallback {
        return mInfoMediaManager.getSuggestedDevice();
    }

    private boolean connectToDeviceIfConnectionPending(MediaDevice device) {
        synchronized (mMediaDevicesLock) {
            if (mConnectingSuggestedDeviceState != null
                    && mConnectingSuggestedDeviceState
                            .mSuggestedDeviceState
                            .getSuggestedDeviceInfo()
                            .getRouteId()
                            .equals(device.getId())) {
                return connectDevice(device);
            }
            return false;
        }
    }

    void dispatchSelectedDeviceStateChanged(MediaDevice device, @MediaDeviceState int state) {
        for (DeviceCallback callback : getCallbacks()) {
            callback.onSelectedDeviceStateChanged(device, state);
@@ -905,43 +889,77 @@ public class LocalMediaManager implements BluetoothCallback {
        private static final int SCAN_DURATION_MS = 10000;

        @NonNull final SuggestedDeviceState mSuggestedDeviceState;
        @NonNull final Handler mConnectSuggestedDeviceHandler;
        @NonNull final DeviceCallback mDeviceCallback;
        @NonNull final Runnable mConnectionAttemptFinishedRunnable;

        ConnectingSuggestedDeviceState(SuggestedDeviceState suggestedDeviceState, Handler handler) {
        boolean mIsConnectionAttemptActive = false;
        boolean mDidAttemptCompleteSuccessfully = false;

        ConnectingSuggestedDeviceState(SuggestedDeviceState suggestedDeviceState) {
            mSuggestedDeviceState = suggestedDeviceState;
            mConnectSuggestedDeviceHandler = handler;
            mDeviceCallback =
                    new DeviceCallback() {
                        @Override
                        public void onDeviceListUpdate(List<MediaDevice> mediaDevices) {
                            synchronized (mMediaDevicesLock) {
                                for (MediaDevice mediaDevice : mediaDevices) {
                                if (connectToDeviceIfConnectionPending(mediaDevice)) {
                                    if (isSuggestedDevice(mediaDevice)) {
                                        connectDevice(mediaDevice);
                                        mIsConnectionAttemptActive = true;
                                        break;
                                    }
                                }
                            }
                        }

                        @Override
                        public void onSelectedDeviceStateChanged(
                                @NonNull MediaDevice device, @MediaDeviceState int state) {
                            if (isSuggestedDevice(device)
                                    && state == MediaDeviceState.STATE_CONNECTED) {
                                if (!mConnectSuggestedDeviceHandler.hasCallbacks(
                                        mConnectionAttemptFinishedRunnable)) {
                                    return;
                                }
                                mDidAttemptCompleteSuccessfully = true;
                                // Remove the postDelayed runnable previously set and post a new one
                                // to be executed right away.
                                mConnectSuggestedDeviceHandler.removeCallbacks(
                                        mConnectionAttemptFinishedRunnable);
                                    mConnectionAttemptFinishedRunnable.run();
                                    break;
                                mConnectSuggestedDeviceHandler.post(
                                        mConnectionAttemptFinishedRunnable);
                            }
                        }

                        private boolean isSuggestedDevice(MediaDevice device) {
                            return mConnectingSuggestedDeviceState != null
                                    && mConnectingSuggestedDeviceState
                                            .mSuggestedDeviceState
                                            .getSuggestedDeviceInfo()
                                            .getRouteId()
                                            .equals(device.getId());
                        }
                    };
            mConnectionAttemptFinishedRunnable =
                    new Runnable() {
                        @Override
                        public void run() {
                    () -> {
                        synchronized (mMediaDevicesLock) {
                            mConnectingSuggestedDeviceState = null;
                            mIsConnectionAttemptActive = false;
                        }
                        unregisterCallback(mDeviceCallback);
                        stopScan();
                        mInfoMediaManager.onConnectionAttemptCompletedForSuggestion(
                                    mSuggestedDeviceState);
                        }
                                mSuggestedDeviceState, mDidAttemptCompleteSuccessfully);
                    };
        }

        void tryConnect() {
            // Attempt connection only if there isn't one already in progress.
            if (mIsConnectionAttemptActive) {
                return;
            }
            // Reset mDidAttemptCompleteSuccessfully at the start of each connection attempt.
            mDidAttemptCompleteSuccessfully = false;
            registerCallback(mDeviceCallback);
            startScan();
            mConnectSuggestedDeviceHandler.postDelayed(
+35 −5
Original line number Diff line number Diff line
@@ -1305,7 +1305,7 @@ public class InfoMediaManagerTest {
                new SuggestedDeviceState(suggestedDeviceInfo1));
        clearInvocations(mCallback);
        mediaManager.onConnectionAttemptCompletedForSuggestion(
                new SuggestedDeviceState(suggestedDeviceInfo2));
                new SuggestedDeviceState(suggestedDeviceInfo2), true);

        verify(mCallback, never()).onSuggestedDeviceUpdated(any());
    }
@@ -1329,17 +1329,18 @@ public class InfoMediaManagerTest {
                new SuggestedDeviceState(suggestedDeviceInfo));
        mediaManager.onConnectionAttemptCompletedForSuggestion(
                new SuggestedDeviceState(
                        suggestedDeviceInfo, LocalMediaManager.MediaDeviceState.STATE_CONNECTING));
                        suggestedDeviceInfo, LocalMediaManager.MediaDeviceState.STATE_CONNECTING),
                false);
        clearInvocations(mCallback);
        mediaManager.onConnectionAttemptCompletedForSuggestion(
                new SuggestedDeviceState(suggestedDeviceInfo));
                new SuggestedDeviceState(suggestedDeviceInfo), false);

        verify(mCallback, never()).onSuggestedDeviceUpdated(any());
    }

    @EnableFlags(Flags.FLAG_ENABLE_SUGGESTED_DEVICE_API)
    @Test
    public void onConnectionAttemptCompletedForSuggestion_connecting_callbackNotified() {
    public void onConnectionAttemptCompletedForSuggestion_unsuccessful_callbackNotified() {
        SuggestedDeviceInfo suggestedDeviceInfo =
                new SuggestedDeviceInfo.Builder("device_name", TEST_ID_3, 0).build();
        RouterInfoMediaManager mediaManager = createRouterInfoMediaManager();
@@ -1357,13 +1358,42 @@ public class InfoMediaManagerTest {
        clearInvocations(mCallback);
        mediaManager.onConnectionAttemptCompletedForSuggestion(
                new SuggestedDeviceState(
                        suggestedDeviceInfo, LocalMediaManager.MediaDeviceState.STATE_CONNECTING));
                        suggestedDeviceInfo, LocalMediaManager.MediaDeviceState.STATE_CONNECTING),
                false);

        verify(mCallback).onSuggestedDeviceUpdated(mSuggestedDeviceStateCaptor.capture());
        assertThat(mSuggestedDeviceStateCaptor.getValue().getConnectionState())
                .isEqualTo(LocalMediaManager.MediaDeviceState.STATE_CONNECTING_FAILED);
    }

    @EnableFlags(Flags.FLAG_ENABLE_SUGGESTED_DEVICE_API)
    @Test
    public void onConnectionAttemptCompletedForSuggestion_successful_callbackNotified() {
        SuggestedDeviceInfo suggestedDeviceInfo =
                new SuggestedDeviceInfo.Builder("device_name", TEST_ID_3, 0).build();
        RouterInfoMediaManager mediaManager = createRouterInfoMediaManager();
        setAvailableRoutesList(TEST_PACKAGE_NAME);
        mediaManager.registerCallback(mCallback);
        verify(mRouter2)
                .registerDeviceSuggestionsUpdatesCallback(
                        any(), mDeviceSuggestionsUpdatesCallback.capture());
        mDeviceSuggestionsUpdatesCallback
                .getValue()
                .onSuggestionsUpdated("random_package_name", List.of(suggestedDeviceInfo));

        mediaManager.onConnectionAttemptedForSuggestion(
                new SuggestedDeviceState(suggestedDeviceInfo));
        clearInvocations(mCallback);
        mediaManager.onConnectionAttemptCompletedForSuggestion(
                new SuggestedDeviceState(
                        suggestedDeviceInfo, LocalMediaManager.MediaDeviceState.STATE_CONNECTING),
                true);

        verify(mCallback).onSuggestedDeviceUpdated(mSuggestedDeviceStateCaptor.capture());
        assertThat(mSuggestedDeviceStateCaptor.getValue().getConnectionState())
                .isEqualTo(LocalMediaManager.MediaDeviceState.STATE_CONNECTED);
    }

    @EnableFlags(Flags.FLAG_ENABLE_OUTPUT_SWITCHER_DEVICE_GROUPING)
    @Test
    public void composePreferenceRouteListing_useSystemOrderingIsFalse() {
+37 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadow.api.Shadow;

import java.util.ArrayList;
@@ -662,6 +663,42 @@ public class LocalMediaManagerTest {
        verify(mInfoMediaManager).startScan();
    }

    @Test
    public void connectSuggestedDevice_handlerTimesOut_completesConnectionAttempt() {
        when(mInfoMediaManager.getSuggestedDevice()).thenReturn(mSuggestedDeviceState);
        when(mSuggestedDeviceInfo.getRouteId()).thenReturn(TEST_DEVICE_ID_1);
        mLocalMediaManager.mMediaDevices.add(mInfoMediaDevice2);

        mLocalMediaManager.connectSuggestedDevice(mSuggestedDeviceState);
        mLocalMediaManager.mMediaDevices.add(mInfoMediaDevice1);
        mLocalMediaManager.dispatchDeviceListUpdate();

        verify(mInfoMediaManager).connectToDevice(mInfoMediaDevice1);

        ShadowLooper.runUiThreadTasksIncludingDelayedTasks();

        verify(mInfoMediaManager)
                .onConnectionAttemptCompletedForSuggestion(mSuggestedDeviceState, false);
    }

    @Test
    public void connectSuggestedDevice_connectionSuccess_completesConnectionAttempt() {
        when(mInfoMediaManager.getSuggestedDevice()).thenReturn(mSuggestedDeviceState);
        when(mSuggestedDeviceInfo.getRouteId()).thenReturn(TEST_DEVICE_ID_1);
        mLocalMediaManager.mMediaDevices.add(mInfoMediaDevice2);

        mLocalMediaManager.connectSuggestedDevice(mSuggestedDeviceState);
        mLocalMediaManager.mMediaDevices.add(mInfoMediaDevice1);
        mLocalMediaManager.dispatchDeviceListUpdate();

        verify(mInfoMediaManager).connectToDevice(mInfoMediaDevice1);

        mLocalMediaManager.dispatchSelectedDeviceStateChanged(mInfoMediaDevice1,
            LocalMediaManager.MediaDeviceState.STATE_CONNECTED);
        verify(mInfoMediaManager)
                .onConnectionAttemptCompletedForSuggestion(mSuggestedDeviceState, true);
    }

    @Test
    public void getSessionReleaseType_returnCorrectType() {
        when(mInfoMediaManager.getSessionReleaseType())