Loading packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java +171 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +56 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java +218 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -53,6 +57,7 @@ public class InfoMediaManagerTest { private InfoMediaManager mInfoMediaManager; private Context mContext; private ShadowRouter2Manager mShadowRouter2Manager; @Before public void setUp() { Loading @@ -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 Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); } Loading Loading @@ -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); } } packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowRouter2Manager.java 0 → 100644 +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)); } } Loading
packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java +171 −18 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading
packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +56 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java +218 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -53,6 +57,7 @@ public class InfoMediaManagerTest { private InfoMediaManager mInfoMediaManager; private Context mContext; private ShadowRouter2Manager mShadowRouter2Manager; @Before public void setUp() { Loading @@ -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 Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -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(); Loading @@ -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(); Loading @@ -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(); } Loading Loading @@ -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); } }
packages/SettingsLib/tests/robotests/testutils/com/android/settingslib/testutils/shadow/ShadowRouter2Manager.java 0 → 100644 +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)); } }