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

Commit 0f3440b7 authored by Alex Shabalin's avatar Alex Shabalin
Browse files

Guard accessing `InfoMediaManager#mMediaDevices` with a lock.

Prevents reading incorrect values during the device list refresh.

Additionally, fix the unit test.

Fix: 417307066
Flag: com.android.media.flags.avoid_binder_calls_during_render
Test: atest com.android.settingslib.media.InfoMediaManagerTest,
Verified on a device.

Change-Id: Ic223ee3ccb9330d8115e23ab4b71c0569aa13a1d
parent a69e7446
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ public abstract class InfoMediaManager {

    private static final String TAG = "InfoMediaManager";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private final Object mLock = new Object();
    protected final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
    @NonNull protected final Context mContext;
    @NonNull protected final String mPackageName;
@@ -358,8 +359,14 @@ public abstract class InfoMediaManager {
    protected abstract List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName);

    protected final void rebuildDeviceList() {
        if (avoidBinderCallsDuringRender()) {
            synchronized (mLock) {
                buildAvailableRoutes();
            }
        } else {
            buildAvailableRoutes();
        }
    }

    protected final void notifyCurrentConnectedDeviceChanged() {
        final String id = mCurrentConnectedDevice != null ? mCurrentConnectedDevice.getId() : null;
@@ -584,8 +591,10 @@ public abstract class InfoMediaManager {
    @NonNull
    List<MediaDevice> getSelectableMediaDevices() {
        if (avoidBinderCallsDuringRender()) {
            synchronized (mLock) {
                return mMediaDevices.stream().filter(MediaDevice::isSelectable).toList();
            }
        }

        final RoutingSessionInfo info = getActiveRoutingSession();

@@ -610,8 +619,10 @@ public abstract class InfoMediaManager {
    @NonNull
    List<MediaDevice> getTransferableMediaDevices() {
        if (avoidBinderCallsDuringRender()) {
            synchronized (mLock) {
                return mMediaDevices.stream().filter(MediaDevice::isTransferable).toList();
            }
        }

        final RoutingSessionInfo info = getActiveRoutingSession();

@@ -636,8 +647,10 @@ public abstract class InfoMediaManager {
    @NonNull
    List<MediaDevice> getDeselectableMediaDevices() {
        if (avoidBinderCallsDuringRender()) {
            synchronized (mLock) {
                return mMediaDevices.stream().filter(MediaDevice::isDeselectable).toList();
            }
        }

        final RoutingSessionInfo info = getActiveRoutingSession();

@@ -663,8 +676,10 @@ public abstract class InfoMediaManager {
    @NonNull
    List<MediaDevice> getSelectedMediaDevices() {
        if (avoidBinderCallsDuringRender()) {
            synchronized (mLock) {
                return mMediaDevices.stream().filter(MediaDevice::isSelected).toList();
            }
        }

        RoutingSessionInfo info = getActiveRoutingSession();

+1 −0
Original line number Diff line number Diff line
@@ -638,6 +638,7 @@ public class InfoMediaManagerTest {
        when(cachedDevice.getName()).thenReturn("BLUETOOTH");
        when(cachedDevice.getAddress()).thenReturn("00:00:00:00:00:00");
        when(bluetoothRoute.isSystemRoute()).thenReturn(true);
        when(bluetoothRoute.getName()).thenReturn("BLUETOOTH");
        when(bluetoothRoute.getId()).thenReturn(TEST_ID_2);
        when(bluetoothRoute.getType()).thenReturn(TYPE_BLE_HEADSET);
        when(bluetoothRoute.getAddress()).thenReturn("00:00:00:00:00:00");