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

Commit 71cb02dc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add new api for output switcher"

parents cbb9454c 6ab62ca6
Loading
Loading
Loading
Loading
+171 −18
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@@ -83,10 +84,179 @@ public class InfoMediaManager extends MediaManager {
     * Get current device that played media.
     * @return MediaDevice
     */
    public MediaDevice getCurrentConnectedDevice() {
    MediaDevice getCurrentConnectedDevice() {
        return mCurrentConnectedDevice;
    }

    /**
     * Transfer MediaDevice for media without package name.
     */
    boolean connectDeviceWithoutPackageName(MediaDevice device) {
        boolean isConnected = false;
        final List<RoutingSessionInfo> infos = mRouterManager.getActiveSessions();
        if (infos.size() > 0) {
            final RoutingSessionInfo info = infos.get(0);
            final MediaRouter2Manager.RoutingController controller =
                    mRouterManager.getControllerForSession(info);

            controller.transferToRoute(device.mRouteInfo);
            isConnected = true;
        }
        return isConnected;
    }

    /**
     * Add a MediaDevice to let it play current media.
     *
     * @param device MediaDevice
     * @return If add device successful return {@code true}, otherwise return {@code false}
     */
    boolean addDeviceToPlayMedia(MediaDevice device) {
        if (TextUtils.isEmpty(mPackageName)) {
            Log.w(TAG, "addDeviceToPlayMedia() package name is null or empty!");
            return false;
        }

        final RoutingSessionInfo info = getRoutingSessionInfo();
        if (info != null && info.getSelectableRoutes().contains(device.mRouteInfo.getId())) {
            mRouterManager.getControllerForSession(info).selectRoute(device.mRouteInfo);
            return true;
        }

        Log.w(TAG, "addDeviceToPlayMedia() Ignoring selecting a non-selectable device : "
                + device.getName());

        return false;
    }

    private RoutingSessionInfo getRoutingSessionInfo() {
        for (RoutingSessionInfo info : mRouterManager.getRoutingSessions(mPackageName)) {
            if (TextUtils.equals(info.getClientPackageName(), mPackageName)) {
                return info;
            }
        }

        Log.w(TAG, "RoutingSessionInfo() cannot found match packagename : " + mPackageName);
        return null;
    }

    /**
     * Remove a {@code device} from current media.
     *
     * @param device MediaDevice
     * @return If device stop successful return {@code true}, otherwise return {@code false}
     */
    boolean removeDeviceFromPlayMedia(MediaDevice device) {
        if (TextUtils.isEmpty(mPackageName)) {
            Log.w(TAG, "removeDeviceFromMedia() package name is null or empty!");
            return false;
        }

        final RoutingSessionInfo info = getRoutingSessionInfo();
        if (info != null && info.getSelectedRoutes().contains(device.mRouteInfo.getId())) {
            mRouterManager.getControllerForSession(info).deselectRoute(device.mRouteInfo);
            return true;
        }

        Log.w(TAG, "removeDeviceFromMedia() Ignoring deselecting a non-deselectable device : "
                + device.getName());

        return false;
    }

    /**
     * Get the MediaDevice list that can be added to current media.
     *
     * @return list of MediaDevice
     */
    List<MediaDevice> getSelectableMediaDevice() {
        final List<MediaDevice> deviceList = new ArrayList<>();
        if (TextUtils.isEmpty(mPackageName)) {
            Log.w(TAG, "getSelectableMediaDevice() package name is null or empty!");
            return deviceList;
        }

        final RoutingSessionInfo info = getRoutingSessionInfo();
        if (info != null) {
            for (MediaRoute2Info route : mRouterManager.getControllerForSession(info)
                    .getSelectableRoutes()) {
                deviceList.add(new InfoMediaDevice(mContext, mRouterManager,
                        route, mPackageName));
            }
            return deviceList;
        }

        Log.w(TAG, "getSelectableMediaDevice() cannot found selectable MediaDevice from : "
                + mPackageName);

        return deviceList;
    }

    /**
     * Adjust the volume of {@link android.media.RoutingSessionInfo}.
     *
     * @param volume the value of volume
     */
    void adjustSessionVolume(int volume) {
        if (TextUtils.isEmpty(mPackageName)) {
            Log.w(TAG, "adjustSessionVolume() package name is null or empty!");
            return;
        }

        final RoutingSessionInfo info = getRoutingSessionInfo();
        if (info != null) {
            Log.d(TAG, "adjustSessionVolume() adjust volume : " + volume + ", with : "
                    + mPackageName);
            mRouterManager.setSessionVolume(info, volume);
            return;
        }

        Log.w(TAG, "adjustSessionVolume() can't found corresponding RoutingSession with : "
                + mPackageName);
    }

    /**
     * Gets the maximum volume of the {@link android.media.RoutingSessionInfo}.
     *
     * @return  maximum volume of the session, and return -1 if not found.
     */
    public int getSessionVolumeMax() {
        if (TextUtils.isEmpty(mPackageName)) {
            Log.w(TAG, "getSessionVolumeMax() package name is null or empty!");
            return -1;
        }

        final RoutingSessionInfo info = getRoutingSessionInfo();
        if (info != null) {
            return info.getVolumeMax();
        }

        Log.w(TAG, "getSessionVolumeMax() can't found corresponding RoutingSession with : "
                + mPackageName);
        return -1;
    }

    /**
     * Gets the current volume of the {@link android.media.RoutingSessionInfo}.
     *
     * @return current volume of the session, and return -1 if not found.
     */
    public int getSessionVolume() {
        if (TextUtils.isEmpty(mPackageName)) {
            Log.w(TAG, "getSessionVolume() package name is null or empty!");
            return -1;
        }

        final RoutingSessionInfo info = getRoutingSessionInfo();
        if (info != null) {
            return info.getVolume();
        }

        Log.w(TAG, "getSessionVolume() can't found corresponding RoutingSession with : "
                + mPackageName);
        return -1;
    }

    private void refreshDevices() {
        mMediaDevices.clear();
        mCurrentConnectedDevice = null;
@@ -150,23 +320,6 @@ public class InfoMediaManager extends MediaManager {
        }
    }

    /**
     * Transfer MediaDevice for media without package name.
     */
    public boolean connectDeviceWithoutPackageName(MediaDevice device) {
        boolean isConnected = false;
        final List<RoutingSessionInfo> infos = mRouterManager.getActiveSessions();
        if (infos.size() > 0) {
            final RoutingSessionInfo info = infos.get(0);
            final MediaRouter2Manager.RoutingController controller =
                    mRouterManager.getControllerForSession(info);

            controller.transferToRoute(device.mRouteInfo);
            isConnected = true;
        }
        return isConnected;
    }

    class RouterManagerCallback extends MediaRouter2Manager.Callback {

        @Override
+56 −0
Original line number Diff line number Diff line
@@ -252,6 +252,62 @@ public class LocalMediaManager implements BluetoothCallback {
        return devices;
    }

    /**
     * Add a MediaDevice to let it play current media.
     *
     * @param device MediaDevice
     * @return If add device successful return {@code true}, otherwise return {@code false}
     */
    public boolean addDeviceToPlayMedia(MediaDevice device) {
        return mInfoMediaManager.addDeviceToPlayMedia(device);
    }

    /**
     * Remove a {@code device} from current media.
     *
     * @param device MediaDevice
     * @return If device stop successful return {@code true}, otherwise return {@code false}
     */
    public boolean removeDeviceFromPlayMedia(MediaDevice device) {
        return mInfoMediaManager.removeDeviceFromPlayMedia(device);
    }

    /**
     * Get the MediaDevice list that can be added to current media.
     *
     * @return list of MediaDevice
     */
    public List<MediaDevice> getSelectableMediaDevice() {
        return mInfoMediaManager.getSelectableMediaDevice();
    }

    /**
     * Adjust the volume of session.
     *
     * @param volume the value of volume
     */
    public void adjustSessionVolume(int volume) {
        mInfoMediaManager.adjustSessionVolume(volume);
    }

    /**
     * Gets the maximum volume of the {@link android.media.RoutingSessionInfo}.
     *
     * @return  maximum volume of the session, and return -1 if not found.
     */
    public int getSessionVolumeMax() {
        return mInfoMediaManager.getSessionVolumeMax();
    }

    /**
     * Gets the current volume of the {@link android.media.RoutingSessionInfo}.
     *
     * @return current volume of the session, and return -1 if not found.
     */
    public int getSessionVolume() {
        return mInfoMediaManager.getSessionVolume();
    }

    private MediaDevice updateCurrentConnectedDevice() {
        MediaDevice phoneMediaDevice = null;
        for (MediaDevice device : mMediaDevices) {
+218 −25
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.media.MediaRouter2Manager;
import android.media.RoutingSessionInfo;

import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.testutils.shadow.ShadowRouter2Manager;

import org.junit.Before;
import org.junit.Test;
@@ -36,15 +37,18 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

import java.util.ArrayList;
import java.util.List;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowRouter2Manager.class})
public class InfoMediaManagerTest {

    private static final String TEST_PACKAGE_NAME = "com.test.packagename";
    private static final String TEST_ID = "test_id";
    private static final String TEST_NAME = "test_name";

    @Mock
    private MediaRouter2Manager mRouterManager;
@@ -53,6 +57,7 @@ public class InfoMediaManagerTest {

    private InfoMediaManager mInfoMediaManager;
    private Context mContext;
    private ShadowRouter2Manager mShadowRouter2Manager;

    @Before
    public void setUp() {
@@ -61,22 +66,8 @@ public class InfoMediaManagerTest {

        mInfoMediaManager =
                new InfoMediaManager(mContext, TEST_PACKAGE_NAME, null, mLocalBluetoothManager);
        mInfoMediaManager.mRouterManager = mRouterManager;
    }

    @Test
    public void stopScan_shouldRemoveCallback() {
        mInfoMediaManager.stopScan();

        verify(mRouterManager).unregisterCallback(mInfoMediaManager.mMediaRouterCallback);
    }

    @Test
    public void startScan_shouldAddCallback() {
        mInfoMediaManager.startScan();

        verify(mRouterManager).registerCallback(mInfoMediaManager.mExecutor,
                mInfoMediaManager.mMediaRouterCallback);
        mShadowRouter2Manager = ShadowRouter2Manager.getShadow();
        mInfoMediaManager.mRouterManager = MediaRouter2Manager.getInstance(mContext);
    }

    @Test
@@ -87,7 +78,7 @@ public class InfoMediaManagerTest {

        final List<MediaRoute2Info> routes = new ArrayList<>();
        routes.add(info);
        when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(routes);
        mShadowRouter2Manager.setAvailableRoutes(routes);

        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
        assertThat(mediaDevice).isNull();
@@ -108,7 +99,7 @@ public class InfoMediaManagerTest {

        final List<MediaRoute2Info> routes = new ArrayList<>();
        routes.add(info);
        when(mRouterManager.getAllRoutes()).thenReturn(routes);
        mShadowRouter2Manager.setAllRoutes(routes);

        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
        assertThat(mediaDevice).isNull();
@@ -129,7 +120,7 @@ public class InfoMediaManagerTest {

        final List<MediaRoute2Info> routes = new ArrayList<>();
        routes.add(info);
        when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(routes);
        mShadowRouter2Manager.setAvailableRoutes(routes);

        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
        assertThat(mediaDevice).isNull();
@@ -157,7 +148,7 @@ public class InfoMediaManagerTest {

        final List<MediaRoute2Info> routes = new ArrayList<>();
        routes.add(info);
        when(mRouterManager.getAvailableRoutes(TEST_PACKAGE_NAME)).thenReturn(routes);
        mShadowRouter2Manager.setAvailableRoutes(routes);

        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
        assertThat(mediaDevice).isNull();
@@ -178,7 +169,7 @@ public class InfoMediaManagerTest {

        final List<MediaRoute2Info> routes = new ArrayList<>();
        routes.add(info);
        when(mRouterManager.getAllRoutes()).thenReturn(routes);
        mShadowRouter2Manager.setAllRoutes(routes);

        final MediaDevice mediaDevice = mInfoMediaManager.findMediaDevice(TEST_ID);
        assertThat(mediaDevice).isNull();
@@ -194,12 +185,12 @@ public class InfoMediaManagerTest {
    @Test
    public void connectDeviceWithoutPackageName_noSession_returnFalse() {
        final MediaRoute2Info info = mock(MediaRoute2Info.class);
        final MediaDevice device = new InfoMediaDevice(mContext, mRouterManager, info,
                TEST_PACKAGE_NAME);
        final MediaDevice device = new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager,
                info, TEST_PACKAGE_NAME);

        final List<RoutingSessionInfo> infos = new ArrayList<>();

        when(mRouterManager.getActiveSessions()).thenReturn(infos);
        mShadowRouter2Manager.setActiveSessions(infos);

        assertThat(mInfoMediaManager.connectDeviceWithoutPackageName(device)).isFalse();
    }
@@ -239,10 +230,212 @@ public class InfoMediaManagerTest {
        assertThat(mediaDevice).isNull();

        mInfoMediaManager.mPackageName = "";
        mInfoMediaManager.mMediaRouterCallback.onRoutesChanged(routes);
        mInfoMediaManager.mMediaRouterCallback.onRoutesRemoved(routes);

        final MediaDevice infoDevice = mInfoMediaManager.mMediaDevices.get(0);
        assertThat(infoDevice.getId()).isEqualTo(TEST_ID);
        assertThat(mInfoMediaManager.mMediaDevices).hasSize(routes.size());
    }

    @Test
    public void addDeviceToPlayMedia_packageNameIsNull_returnFalse() {
        mInfoMediaManager.mPackageName = null;
        final MediaDevice device = mock(MediaDevice.class);

        assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isFalse();
    }

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

        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
        final MediaDevice device =
                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
                        TEST_PACKAGE_NAME);

        final List<String> list = new ArrayList<>();
        list.add(TEST_ID);

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
        when(info.getSelectableRoutes()).thenReturn(list);
        when(route2Info.getId()).thenReturn(TEST_ID);
        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isTrue();
    }

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

        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
        final MediaDevice device =
                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
                        TEST_PACKAGE_NAME);

        final List<String> list = new ArrayList<>();
        list.add("fake_id");

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
        when(info.getSelectableRoutes()).thenReturn(list);
        when(route2Info.getId()).thenReturn(TEST_ID);
        when(route2Info.getName()).thenReturn(TEST_NAME);
        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        assertThat(mInfoMediaManager.addDeviceToPlayMedia(device)).isFalse();
    }

    @Test
    public void removeDeviceFromMedia_packageNameIsNull_returnFalse() {
        mInfoMediaManager.mPackageName = null;
        final MediaDevice device = mock(MediaDevice.class);

        assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isFalse();
    }

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

        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
        final MediaDevice device =
                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
                        TEST_PACKAGE_NAME);

        final List<String> list = new ArrayList<>();
        list.add(TEST_ID);

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
        when(info.getSelectedRoutes()).thenReturn(list);
        when(route2Info.getId()).thenReturn(TEST_ID);
        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isTrue();
    }

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

        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
        final MediaDevice device =
                new InfoMediaDevice(mContext, mInfoMediaManager.mRouterManager, route2Info,
                        TEST_PACKAGE_NAME);

        final List<String> list = new ArrayList<>();
        list.add("fake_id");

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
        when(info.getSelectedRoutes()).thenReturn(list);
        when(route2Info.getId()).thenReturn(TEST_ID);
        when(route2Info.getName()).thenReturn(TEST_NAME);
        when(route2Info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        assertThat(mInfoMediaManager.removeDeviceFromPlayMedia(device)).isFalse();
    }

    @Test
    public void getSelectableMediaDevice_packageNameIsNull_returnFalse() {
        mInfoMediaManager.mPackageName = null;

        assertThat(mInfoMediaManager.getSelectableMediaDevice()).isEmpty();
    }

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

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn("com.fake.packagename");

        assertThat(mInfoMediaManager.getSelectableMediaDevice()).isEmpty();
    }

    @Test
    public void adjustSessionVolume_packageNameIsNull_noCrash() {
        mInfoMediaManager.mPackageName = null;

        mInfoMediaManager.adjustSessionVolume(10);
    }

    @Test
    public void getSessionVolumeMax_packageNameIsNull_returnNotFound() {
        mInfoMediaManager.mPackageName = null;

        assertThat(mInfoMediaManager.getSessionVolumeMax()).isEqualTo(-1);
    }

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

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        mInfoMediaManager.getSessionVolumeMax();

        verify(info).getVolumeMax();
    }

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

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn("com.fake.packagename");

        assertThat(mInfoMediaManager.getSessionVolumeMax()).isEqualTo(-1);
    }

    @Test
    public void getSessionVolume_packageNameIsNull_returnNotFound() {
        mInfoMediaManager.mPackageName = null;

        assertThat(mInfoMediaManager.getSessionVolume()).isEqualTo(-1);
    }

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

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);

        mInfoMediaManager.getSessionVolume();

        verify(info).getVolume();
    }

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

        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
        when(info.getClientPackageName()).thenReturn("com.fake.packagename");

        assertThat(mInfoMediaManager.getSessionVolume()).isEqualTo(-1);
    }
}
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 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.testutils.shadow;

import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.RoutingSessionInfo;

import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;

import java.util.List;

@Implements(MediaRouter2Manager.class)
public class ShadowRouter2Manager {

    private List<MediaRoute2Info> mAvailableRoutes;
    private List<MediaRoute2Info> mAllRoutes;
    private List<RoutingSessionInfo> mActiveSessions;
    private List<RoutingSessionInfo> mRoutingSessions;

    @Implementation
    protected List<MediaRoute2Info> getAvailableRoutes(String packageName) {
        return mAvailableRoutes;
    }

    public void setAvailableRoutes(List<MediaRoute2Info> infos) {
        mAvailableRoutes = infos;
    }

    @Implementation
    protected List<MediaRoute2Info> getAllRoutes() {
        return mAllRoutes;
    }

    public void setAllRoutes(List<MediaRoute2Info> infos) {
        mAllRoutes = infos;
    }

    @Implementation
    protected List<RoutingSessionInfo> getActiveSessions() {
        return mActiveSessions;
    }

    public void setActiveSessions(List<RoutingSessionInfo> infos) {
        mActiveSessions = infos;
    }

    @Implementation
    protected List<RoutingSessionInfo> getRoutingSessions(String packageName) {
        return mRoutingSessions;
    }

    public void setRoutingSessions(List<RoutingSessionInfo> infos) {
        mRoutingSessions = infos;
    }

    public static ShadowRouter2Manager getShadow() {
        return (ShadowRouter2Manager) Shadow.extract(
                MediaRouter2Manager.getInstance(RuntimeEnvironment.application));
    }
}