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

Commit a4e74a6f authored by Alexandr Shabalin's avatar Alexandr Shabalin Committed by Android (Google) Code Review
Browse files

Merge "Clean up code for the flag `use_media_router2_for_info_media_manager`." into main

parents fecb36ff 9cb317a1
Loading
Loading
Loading
Loading
+0 −7
Original line number Diff line number Diff line
package: "com.android.settingslib.media.flags"
container: "system"

flag {
    name: "use_media_router2_for_info_media_manager"
    namespace: "media_solutions"
    description: "Gates whether to use a MediaRouter2-based implementation of InfoMediaManager, instead of the legacy MediaRouter2Manager-based implementation."
    bug: "192657812"
}

flag {
    name: "enable_tv_media_output_dialog"
    namespace: "tv_system_ui"
+7 −12
Original line number Diff line number Diff line
@@ -265,7 +265,6 @@ public abstract class InfoMediaManager {
            userHandle = android.os.Process.myUserHandle();
        }

        if (Flags.useMediaRouter2ForInfoMediaManager()) {
        try {
            return new RouterInfoMediaManager(
                    context, packageName, userHandle, localBluetoothManager, mediaController);
@@ -275,10 +274,6 @@ public abstract class InfoMediaManager {
            return new NoOpInfoMediaManager(
                    context, packageName, userHandle, localBluetoothManager, mediaController);
        }
        } else {
            return new ManagerInfoMediaManager(
                    context, packageName, userHandle, localBluetoothManager, mediaController);
        }
    }

    public void startScan() {
+0 −256
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.media;

import android.content.Context;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.RouteListingPreference;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.bluetooth.LocalBluetoothManager;

import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Template implementation of {@link InfoMediaManager} using {@link MediaRouter2Manager}.
 */
public class ManagerInfoMediaManager extends InfoMediaManager {

    private static final String TAG = "ManagerInfoMediaManager";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    @VisibleForTesting
    /* package */ final RouterManagerCallback mMediaRouterCallback = new RouterManagerCallback();
    @VisibleForTesting
    /* package */ MediaRouter2Manager mRouterManager;
    boolean mIsScanning = false;

    private final Executor mExecutor = Executors.newSingleThreadExecutor();

    /* package */ ManagerInfoMediaManager(
            Context context,
            @NonNull String packageName,
            @NonNull UserHandle userHandle,
            LocalBluetoothManager localBluetoothManager,
            @Nullable MediaController mediaController) {
        super(context, packageName, userHandle, localBluetoothManager, mediaController);

        mRouterManager = MediaRouter2Manager.getInstance(context);
    }

    @Override
    protected void startScanOnRouter() {
        if (!mIsScanning) {
            mRouterManager.registerScanRequest();
            mIsScanning = true;
        }
    }

    @Override
    protected void registerRouter() {
        mRouterManager.registerCallback(mExecutor, mMediaRouterCallback);
    }

    @Override
    protected void stopScanOnRouter() {
        if (mIsScanning) {
            mRouterManager.unregisterScanRequest();
            mIsScanning = false;
        }
    }

    @Override
    protected void unregisterRouter() {
        mRouterManager.unregisterCallback(mMediaRouterCallback);
    }

    @Override
    protected void transferToRoute(@NonNull MediaRoute2Info route) {
        mRouterManager.transfer(mPackageName, route, mUserHandle);
    }

    @Override
    protected void selectRoute(@NonNull MediaRoute2Info route, @NonNull RoutingSessionInfo info) {
        mRouterManager.selectRoute(info, route);
    }

    @Override
    protected void deselectRoute(@NonNull MediaRoute2Info route, @NonNull RoutingSessionInfo info) {
        mRouterManager.deselectRoute(info, route);
    }

    @Override
    protected void releaseSession(@NonNull RoutingSessionInfo sessionInfo) {
        mRouterManager.releaseSession(sessionInfo);
    }

    @Override
    @NonNull
    protected List<MediaRoute2Info> getSelectableRoutes(@NonNull RoutingSessionInfo info) {
        return mRouterManager.getSelectableRoutes(info);
    }

    @Override
    @NonNull
    protected List<MediaRoute2Info> getTransferableRoutes(@NonNull RoutingSessionInfo info) {
        return mRouterManager.getTransferableRoutes(info);
    }

    @Override
    @NonNull
    protected List<MediaRoute2Info> getDeselectableRoutes(@NonNull RoutingSessionInfo info) {
        return mRouterManager.getDeselectableRoutes(info);
    }

    @Override
    @NonNull
    protected List<MediaRoute2Info> getSelectedRoutes(@NonNull RoutingSessionInfo info) {
        return mRouterManager.getSelectedRoutes(info);
    }

    @Override
    protected void setSessionVolume(@NonNull RoutingSessionInfo info, int volume) {
        mRouterManager.setSessionVolume(info, volume);
    }

    @Override
    protected void setRouteVolume(@NonNull MediaRoute2Info route, int volume) {
        mRouterManager.setRouteVolume(route, volume);
    }

    @Override
    @Nullable
    protected RouteListingPreference getRouteListingPreference() {
        return mRouterManager.getRouteListingPreference(mPackageName);
    }

    @Override
    @NonNull
    protected List<RoutingSessionInfo> getRoutingSessionsForPackage() {
        return mRouterManager.getRoutingSessions(mPackageName);
    }

    @Override
    @NonNull
    protected List<RoutingSessionInfo> getRemoteSessions() {
        return mRouterManager.getRemoteSessions();
    }

    @Nullable
    @Override
    protected RoutingSessionInfo getRoutingSessionById(@NonNull String sessionId) {
        for (RoutingSessionInfo sessionInfo : getRemoteSessions()) {
            if (TextUtils.equals(sessionInfo.getId(), sessionId)) {
                return sessionInfo;
            }
        }

        RoutingSessionInfo systemSession = mRouterManager.getSystemRoutingSession(null);

        return TextUtils.equals(systemSession.getId(), sessionId) ? systemSession : null;
    }

    @Override
    @NonNull
    protected List<MediaRoute2Info> getAvailableRoutesFromRouter() {
        return mRouterManager.getAvailableRoutes(mPackageName);
    }

    @Override
    @NonNull
    protected List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName) {
        return mRouterManager.getTransferableRoutes(packageName);
    }

    @Override
    public void requestDeviceSuggestion() {
        // no-op, not supported by ManagerInfoMediaManager
    }

    @VisibleForTesting
    /* package */ final class RouterManagerCallback implements MediaRouter2Manager.Callback {

        @Override
        public void onRoutesUpdated() {
            refreshDevices();
        }

        @Override
        public void onPreferredFeaturesChanged(String packageName, List<String> preferredFeatures) {
            if (TextUtils.equals(mPackageName, packageName)) {
                refreshDevices();
            }
        }

        @Override
        public void onTransferred(RoutingSessionInfo oldSession, RoutingSessionInfo newSession) {
            if (DEBUG) {
                Log.d(
                        TAG,
                        "onTransferred() oldSession : "
                                + oldSession.getName()
                                + ", newSession : "
                                + newSession.getName());
            }
            rebuildDeviceList();
            notifyCurrentConnectedDeviceChanged();
        }

        /**
         * Ignore callback here since we'll also receive{@link
         * MediaRouter2Manager.Callback#onRequestFailed onRequestFailed} with reason code.
         */
        @Override
        public void onTransferFailed(RoutingSessionInfo session, MediaRoute2Info route) {}

        @Override
        public void onRequestFailed(int reason) {
            dispatchOnRequestFailed(reason);
        }

        @Override
        public void onSessionUpdated(RoutingSessionInfo sessionInfo) {
            refreshDevices();
        }

        @Override
        public void onSessionReleased(@NonNull RoutingSessionInfo session) {
            refreshDevices();
        }

        @Override
        public void onRouteListingPreferenceUpdated(
                String packageName, RouteListingPreference routeListingPreference) {
            if (!TextUtils.equals(mPackageName, packageName)) {
                return;
            }
            notifyRouteListingPreferenceUpdated(routeListingPreference);
            refreshDevices();
        }
    }
}
+16 −9
Original line number Diff line number Diff line
@@ -56,14 +56,18 @@ public final class RouterInfoMediaManager extends InfoMediaManager {
    private static final String TAG = "RouterInfoMediaManager";

    private final MediaRouter2 mRouter;
    private final MediaRouter2Manager mRouterManager;
    @VisibleForTesting
    MediaRouter2Manager mRouterManager;

    private final Executor mExecutor = Executors.newSingleThreadExecutor();

    private final RouteCallback mRouteCallback = new RouteCallback();
    private final TransferCallback mTransferCallback = new TransferCallback();
    private final ControllerCallback mControllerCallback = new ControllerCallback();
    private final Consumer<RouteListingPreference> mRouteListingPreferenceCallback =
    @VisibleForTesting
    final RouteCallback mRouteCallback = new RouteCallback();
    @VisibleForTesting
    final TransferCallback mTransferCallback = new TransferCallback();
    @VisibleForTesting
    final ControllerCallback mControllerCallback = new ControllerCallback();
    @VisibleForTesting
    final Consumer<RouteListingPreference> mRouteListingPreferenceCallback =
            (preference) -> {
                notifyRouteListingPreferenceUpdated(preference);
                refreshDevices();
@@ -351,7 +355,8 @@ public final class RouterInfoMediaManager extends InfoMediaManager {
        return mRouter.getController(sessionInfo.getId());
    }

    private final class RouteCallback extends MediaRouter2.RouteCallback {
    @VisibleForTesting
    final class RouteCallback extends MediaRouter2.RouteCallback {
        @Override
        public void onRoutesUpdated(@NonNull List<MediaRoute2Info> routes) {
            refreshDevices();
@@ -363,7 +368,8 @@ public final class RouterInfoMediaManager extends InfoMediaManager {
        }
    }

    private final class TransferCallback extends MediaRouter2.TransferCallback {
    @VisibleForTesting
    final class TransferCallback extends MediaRouter2.TransferCallback {
        @Override
        public void onTransfer(
                @NonNull RoutingController oldController,
@@ -388,7 +394,8 @@ public final class RouterInfoMediaManager extends InfoMediaManager {
        }
    }

    private final class ControllerCallback extends MediaRouter2.ControllerCallback {
    @VisibleForTesting
    final class ControllerCallback extends MediaRouter2.ControllerCallback {
        @Override
        public void onControllerUpdated(@NonNull RoutingController controller) {
            refreshDevices();
+3 −25
Original line number Diff line number Diff line
@@ -16,24 +16,17 @@

package com.android.settingslib.media;

import static com.android.settingslib.media.flags.Flags.FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER;

import static com.google.common.truth.Truth.assertThat;

import android.Manifest;
import android.app.UiAutomation;
import android.content.Context;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@@ -45,9 +38,6 @@ public class InfoMediaManagerIntegTest {
    private Context mContext;
    private UiAutomation mUiAutomation;

    @Rule
    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();

    @Before
    public void setUp() {
        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
@@ -61,8 +51,7 @@ public class InfoMediaManagerIntegTest {
    }

    @Test
    @RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
    public void createInstance_withMR2FlagOn_returnsRouterInfoMediaManager() {
    public void createInstance_withValidPackage_returnsRouterInfoMediaManager() {
        InfoMediaManager manager =
                InfoMediaManager.createInstance(
                        mContext, mContext.getPackageName(), mContext.getUser(), null, null);
@@ -70,27 +59,16 @@ public class InfoMediaManagerIntegTest {
    }

    @Test
    @RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
    public void createInstance_withMR2FlagOn_withFakePackage_returnsNoOpInfoMediaManager() {
    public void createInstance_withFakePackage_returnsNoOpInfoMediaManager() {
        InfoMediaManager manager =
                InfoMediaManager.createInstance(mContext, FAKE_PACKAGE, null, null, null);
        assertThat(manager).isInstanceOf(NoOpInfoMediaManager.class);
    }

    @Test
    @RequiresFlagsEnabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
    public void createInstance_withMR2FlagOn_withNullPackage_returnsRouterInfoMediaManager() {
    public void createInstance_withNullPackage_returnsRouterInfoMediaManager() {
        InfoMediaManager manager =
                InfoMediaManager.createInstance(mContext, null, null, null, null);
        assertThat(manager).isInstanceOf(RouterInfoMediaManager.class);
    }

    @Test
    @RequiresFlagsDisabled(FLAG_USE_MEDIA_ROUTER2_FOR_INFO_MEDIA_MANAGER)
    public void createInstance_withMR2FlagOff_returnsManagerInfoMediaManager() {
        InfoMediaManager manager =
                InfoMediaManager.createInstance(
                        mContext, mContext.getPackageName(), mContext.getUser(), null, null);
        assertThat(manager).isInstanceOf(ManagerInfoMediaManager.class);
    }
}
Loading