Merge "[Output Switcher] Apply distance information for devices ranking" into tm-dev

This commit is contained in:
Shaowei Shen
2022-03-07 06:57:54 +00:00
committed by Android (Google) Code Review
9 changed files with 202 additions and 18 deletions

View File

@@ -22,9 +22,10 @@ import android.annotation.SystemApi;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
/** /**
* A parcelable representing a nearby device that can be used for media transfer. * A parcelable representing a nearby device that can be used for media transfer.
@@ -35,6 +36,7 @@ import java.lang.annotation.RetentionPolicy;
* <li>a range zone specifying how far away this device is from the device with the media route. * <li>a range zone specifying how far away this device is from the device with the media route.
* </li> * </li>
* </ul> * </ul>
*
* @hide * @hide
*/ */
@SystemApi @SystemApi
@@ -69,7 +71,7 @@ public final class NearbyDevice implements Parcelable {
* *
* @hide * @hide
*/ */
@IntDef(prefix = { "RANGE_" }, value = { @IntDef(prefix = {"RANGE_"}, value = {
RANGE_UNKNOWN, RANGE_UNKNOWN,
RANGE_FAR, RANGE_FAR,
RANGE_LONG, RANGE_LONG,
@@ -77,7 +79,8 @@ public final class NearbyDevice implements Parcelable {
RANGE_WITHIN_REACH RANGE_WITHIN_REACH
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface RangeZone {} public @interface RangeZone {
}
/** /**
* Gets a human-readable string of the range zone. * Gets a human-readable string of the range zone.
@@ -102,8 +105,17 @@ public final class NearbyDevice implements Parcelable {
} }
} }
@NonNull private final String mMediaRoute2Id; /**
@RangeZone private final int mRangeZone; * A list stores all the range and list from far to close, used for range comparison.
*/
private static final List<Integer> RANGE_WEIGHT_LIST =
Arrays.asList(RANGE_UNKNOWN,
RANGE_FAR, RANGE_LONG, RANGE_CLOSE, RANGE_WITHIN_REACH);
@NonNull
private final String mMediaRoute2Id;
@RangeZone
private final int mRangeZone;
/** Creates a device object with the given ID and range zone. */ /** Creates a device object with the given ID and range zone. */
public NearbyDevice(@NonNull String mediaRoute2Id, @RangeZone int rangeZone) { public NearbyDevice(@NonNull String mediaRoute2Id, @RangeZone int rangeZone) {
@@ -129,6 +141,22 @@ public final class NearbyDevice implements Parcelable {
} }
}; };
/**
* Compares two ranges and return result.
*
* @return 0 means two ranges are the same, -1 means first range is closer, 1 means farther
*
* @hide
*/
public static int compareRangeZones(@RangeZone int rangeZone, @RangeZone int anotherRangeZone) {
if (rangeZone == anotherRangeZone) {
return 0;
} else {
return RANGE_WEIGHT_LIST.indexOf(rangeZone) > RANGE_WEIGHT_LIST.indexOf(
anotherRangeZone) ? -1 : 1;
}
}
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

View File

@@ -35,6 +35,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.media.MediaRoute2Info; import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager; import android.media.MediaRouter2Manager;
import android.media.NearbyDevice;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@@ -77,6 +78,8 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
private int mConnectedRecord; private int mConnectedRecord;
private int mState; private int mState;
@NearbyDevice.RangeZone
private int mRangeZone = NearbyDevice.RANGE_UNKNOWN;
protected final Context mContext; protected final Context mContext;
protected final MediaRoute2Info mRouteInfo; protected final MediaRoute2Info mRouteInfo;
@@ -136,6 +139,14 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
getId()); getId());
} }
public @NearbyDevice.RangeZone int getRangeZone() {
return mRangeZone;
}
public void setRangeZone(@NearbyDevice.RangeZone int rangeZone) {
mRangeZone = rangeZone;
}
/** /**
* Get name from MediaDevice. * Get name from MediaDevice.
* *
@@ -319,6 +330,11 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
} }
} }
// Both devices have same connection status, compare the range zone
if (NearbyDevice.compareRangeZones(getRangeZone(), another.getRangeZone()) != 0) {
return NearbyDevice.compareRangeZones(getRangeZone(), another.getRangeZone());
}
if (mType == another.mType) { if (mType == another.mType) {
// Check device is muting expected device // Check device is muting expected device
if (isMutingExpectedDevice()) { if (isMutingExpectedDevice()) {

View File

@@ -31,6 +31,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context; import android.content.Context;
import android.media.MediaRoute2Info; import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager; import android.media.MediaRouter2Manager;
import android.media.NearbyDevice;
import android.os.Parcel; import android.os.Parcel;
import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.A2dpProfile;
@@ -199,6 +200,18 @@ public class MediaDeviceTest {
assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2); assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2);
} }
@Test
public void compareTo_differentRange_sortWithRange() {
mBluetoothMediaDevice1.setRangeZone(NearbyDevice.RANGE_FAR);
mBluetoothMediaDevice2.setRangeZone(NearbyDevice.RANGE_CLOSE);
mMediaDevices.add(mBluetoothMediaDevice1);
mMediaDevices.add(mBluetoothMediaDevice2);
assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
Collections.sort(mMediaDevices, COMPARATOR);
assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice2);
}
@Test @Test
public void compareTo_carKit_info_carKitFirst() { public void compareTo_carKit_info_carKitFirst() {
when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass); when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);

View File

@@ -30,12 +30,16 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.media.INearbyMediaDevicesUpdateCallback;
import android.media.MediaMetadata; import android.media.MediaMetadata;
import android.media.MediaRoute2Info; import android.media.MediaRoute2Info;
import android.media.NearbyDevice;
import android.media.RoutingSessionInfo; import android.media.RoutingSessionInfo;
import android.media.session.MediaController; import android.media.session.MediaController;
import android.media.session.MediaSessionManager; import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState; import android.media.session.PlaybackState;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.provider.Settings; import android.provider.Settings;
@@ -61,6 +65,7 @@ import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator; import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.monet.ColorScheme; import com.android.systemui.monet.ColorScheme;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -70,6 +75,9 @@ import com.android.systemui.statusbar.phone.ShadeController;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject; import javax.inject.Inject;
@@ -77,7 +85,8 @@ import javax.inject.Inject;
/** /**
* Controller for media output dialog * Controller for media output dialog
*/ */
public class MediaOutputController implements LocalMediaManager.DeviceCallback { public class MediaOutputController implements LocalMediaManager.DeviceCallback,
INearbyMediaDevicesUpdateCallback {
private static final String TAG = "MediaOutputController"; private static final String TAG = "MediaOutputController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -95,6 +104,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
private final CommonNotifCollection mNotifCollection; private final CommonNotifCollection mNotifCollection;
@VisibleForTesting @VisibleForTesting
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
private final NearbyMediaDevicesManager mNearbyMediaDevicesManager;
private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>();
private MediaController mMediaController; private MediaController mMediaController;
@VisibleForTesting @VisibleForTesting
@@ -116,7 +127,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager
lbm, ShadeController shadeController, ActivityStarter starter, lbm, ShadeController shadeController, ActivityStarter starter,
CommonNotifCollection notifCollection, UiEventLogger uiEventLogger, CommonNotifCollection notifCollection, UiEventLogger uiEventLogger,
DialogLaunchAnimator dialogLaunchAnimator) { DialogLaunchAnimator dialogLaunchAnimator,
Optional<NearbyMediaDevicesManager> nearbyMediaDevicesManagerOptional) {
mContext = context; mContext = context;
mPackageName = packageName; mPackageName = packageName;
mMediaSessionManager = mediaSessionManager; mMediaSessionManager = mediaSessionManager;
@@ -130,6 +142,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName); mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
mUiEventLogger = uiEventLogger; mUiEventLogger = uiEventLogger;
mDialogLaunchAnimator = dialogLaunchAnimator; mDialogLaunchAnimator = dialogLaunchAnimator;
mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
mColorActiveItem = Utils.getColorStateListDefaultColor(mContext, mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
R.color.media_dialog_active_item_main_content); R.color.media_dialog_active_item_main_content);
mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext, mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
@@ -144,6 +157,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
void start(@NonNull Callback cb) { void start(@NonNull Callback cb) {
mMediaDevices.clear(); mMediaDevices.clear();
mNearbyDeviceInfoMap.clear();
if (mNearbyMediaDevicesManager != null) {
mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this);
}
if (!TextUtils.isEmpty(mPackageName)) { if (!TextUtils.isEmpty(mPackageName)) {
for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) { for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
if (TextUtils.equals(controller.getPackageName(), mPackageName)) { if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
@@ -187,6 +204,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
mLocalMediaManager.stopScan(); mLocalMediaManager.stopScan();
} }
mMediaDevices.clear(); mMediaDevices.clear();
if (mNearbyMediaDevicesManager != null) {
mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
}
mNearbyDeviceInfoMap.clear();
} }
@Override @Override
@@ -417,6 +438,15 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
} }
mMediaDevices.clear(); mMediaDevices.clear();
mMediaDevices.addAll(targetMediaDevices); mMediaDevices.addAll(targetMediaDevices);
attachRangeInfo();
}
private void attachRangeInfo() {
for (MediaDevice mediaDevice : mMediaDevices) {
if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
mediaDevice.setRangeZone(mNearbyDeviceInfoMap.get(mediaDevice.getId()));
}
}
} }
List<MediaDevice> getGroupMediaDevices() { List<MediaDevice> getGroupMediaDevices() {
@@ -604,7 +634,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
// We show the output group dialog from the output dialog. // We show the output group dialog from the output dialog.
MediaOutputController controller = new MediaOutputController(mContext, mPackageName, MediaOutputController controller = new MediaOutputController(mContext, mPackageName,
mAboveStatusbar, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mAboveStatusbar, mMediaSessionManager, mLocalBluetoothManager, mShadeController,
mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator); mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
MediaOutputGroupDialog dialog = new MediaOutputGroupDialog(mContext, mAboveStatusbar, MediaOutputGroupDialog dialog = new MediaOutputGroupDialog(mContext, mAboveStatusbar,
controller); controller);
mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog); mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog);
@@ -629,6 +661,20 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
|| mLocalMediaManager.isMediaSessionAvailableForVolumeControl(); || mLocalMediaManager.isMediaSessionAvailableForVolumeControl();
} }
@Override
public void onDevicesUpdated(List<NearbyDevice> nearbyDevices) throws RemoteException {
mNearbyDeviceInfoMap.clear();
for (NearbyDevice nearbyDevice : nearbyDevices) {
mNearbyDeviceInfoMap.put(nearbyDevice.getMediaRoute2Id(), nearbyDevice.getRangeZone());
}
mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
}
@Override
public IBinder asBinder() {
return null;
}
private final MediaController.Callback mCb = new MediaController.Callback() { private final MediaController.Callback mCb = new MediaController.Callback() {
@Override @Override
public void onMetadataChanged(MediaMetadata metadata) { public void onMetadataChanged(MediaMetadata metadata) {

View File

@@ -22,9 +22,11 @@ import android.view.View
import com.android.internal.logging.UiEventLogger import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.media.nearby.NearbyMediaDevicesManager
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import com.android.systemui.statusbar.phone.ShadeController import com.android.systemui.statusbar.phone.ShadeController
import java.util.Optional
import javax.inject.Inject import javax.inject.Inject
/** /**
@@ -38,7 +40,8 @@ class MediaOutputDialogFactory @Inject constructor(
private val starter: ActivityStarter, private val starter: ActivityStarter,
private val notifCollection: CommonNotifCollection, private val notifCollection: CommonNotifCollection,
private val uiEventLogger: UiEventLogger, private val uiEventLogger: UiEventLogger,
private val dialogLaunchAnimator: DialogLaunchAnimator private val dialogLaunchAnimator: DialogLaunchAnimator,
private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager>
) { ) {
companion object { companion object {
var mediaOutputDialog: MediaOutputDialog? = null var mediaOutputDialog: MediaOutputDialog? = null
@@ -50,8 +53,8 @@ class MediaOutputDialogFactory @Inject constructor(
mediaOutputDialog?.dismiss() mediaOutputDialog?.dismiss()
val controller = MediaOutputController(context, packageName, aboveStatusBar, val controller = MediaOutputController(context, packageName, aboveStatusBar,
mediaSessionManager, lbm, shadeController, starter, notifCollection, mediaSessionManager, lbm, shadeController, starter, notifCollection,
uiEventLogger, dialogLaunchAnimator) uiEventLogger, dialogLaunchAnimator, nearbyMediaDevicesManagerOptional)
val dialog = MediaOutputDialog(context, aboveStatusBar, controller, uiEventLogger) val dialog = MediaOutputDialog(context, aboveStatusBar, controller, uiEventLogger)
mediaOutputDialog = dialog mediaOutputDialog = dialog

View File

@@ -42,6 +42,7 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.ShadeController;
@@ -50,6 +51,8 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.util.Optional;
@SmallTest @SmallTest
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true) @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -66,6 +69,8 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
private NotificationEntryManager mNotificationEntryManager = private NotificationEntryManager mNotificationEntryManager =
mock(NotificationEntryManager.class); mock(NotificationEntryManager.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class); private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
NearbyMediaDevicesManager.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl; private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl;
@@ -80,7 +85,8 @@ public class MediaOutputBaseDialogTest extends SysuiTestCase {
public void setUp() { public void setUp() {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false, mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator); mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext,
mMediaOutputController); mMediaOutputController);
mMediaOutputBaseDialogImpl.onCreate(new Bundle()); mMediaOutputBaseDialogImpl.onCreate(new Bundle());

View File

@@ -33,9 +33,11 @@ import android.content.Context;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.media.MediaDescription; import android.media.MediaDescription;
import android.media.MediaMetadata; import android.media.MediaMetadata;
import android.media.NearbyDevice;
import android.media.RoutingSessionInfo; import android.media.RoutingSessionInfo;
import android.media.session.MediaController; import android.media.session.MediaController;
import android.media.session.MediaSessionManager; import android.media.session.MediaSessionManager;
import android.os.RemoteException;
import android.service.notification.StatusBarNotification; import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.text.TextUtils; import android.text.TextUtils;
@@ -51,17 +53,21 @@ import com.android.settingslib.media.MediaDevice;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.ShadeController;
import com.google.common.collect.ImmutableList;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
@SmallTest @SmallTest
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@@ -86,6 +92,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class); private MediaOutputController.Callback mCb = mock(MediaOutputController.Callback.class);
private MediaDevice mMediaDevice1 = mock(MediaDevice.class); private MediaDevice mMediaDevice1 = mock(MediaDevice.class);
private MediaDevice mMediaDevice2 = mock(MediaDevice.class); private MediaDevice mMediaDevice2 = mock(MediaDevice.class);
private NearbyDevice mNearbyDevice1 = mock(NearbyDevice.class);
private NearbyDevice mNearbyDevice2 = mock(NearbyDevice.class);
private MediaMetadata mMediaMetadata = mock(MediaMetadata.class); private MediaMetadata mMediaMetadata = mock(MediaMetadata.class);
private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class); private RoutingSessionInfo mRemoteSessionInfo = mock(RoutingSessionInfo.class);
private ShadeController mShadeController = mock(ShadeController.class); private ShadeController mShadeController = mock(ShadeController.class);
@@ -93,12 +101,15 @@ public class MediaOutputControllerTest extends SysuiTestCase {
private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class); private CommonNotifCollection mNotifCollection = mock(CommonNotifCollection.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class); private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
NearbyMediaDevicesManager.class);
private Context mSpyContext; private Context mSpyContext;
private MediaOutputController mMediaOutputController; private MediaOutputController mMediaOutputController;
private LocalMediaManager mLocalMediaManager; private LocalMediaManager mLocalMediaManager;
private List<MediaController> mMediaControllers = new ArrayList<>(); private List<MediaController> mMediaControllers = new ArrayList<>();
private List<MediaDevice> mMediaDevices = new ArrayList<>(); private List<MediaDevice> mMediaDevices = new ArrayList<>();
private List<NearbyDevice> mNearbyDevices = new ArrayList<>();
private MediaDescription mMediaDescription; private MediaDescription mMediaDescription;
private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>(); private List<RoutingSessionInfo> mRoutingSessionInfos = new ArrayList<>();
@@ -115,7 +126,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, false, mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
mNotifCollection, mUiEventLogger, mDialogLaunchAnimator); mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager); mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
MediaDescription.Builder builder = new MediaDescription.Builder(); MediaDescription.Builder builder = new MediaDescription.Builder();
@@ -127,6 +139,13 @@ public class MediaOutputControllerTest extends SysuiTestCase {
when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID); when(mMediaDevice2.getId()).thenReturn(TEST_DEVICE_2_ID);
mMediaDevices.add(mMediaDevice1); mMediaDevices.add(mMediaDevice1);
mMediaDevices.add(mMediaDevice2); mMediaDevices.add(mMediaDevice2);
when(mNearbyDevice1.getMediaRoute2Id()).thenReturn(TEST_DEVICE_1_ID);
when(mNearbyDevice1.getRangeZone()).thenReturn(NearbyDevice.RANGE_CLOSE);
when(mNearbyDevice2.getMediaRoute2Id()).thenReturn(TEST_DEVICE_2_ID);
when(mNearbyDevice2.getRangeZone()).thenReturn(NearbyDevice.RANGE_FAR);
mNearbyDevices.add(mNearbyDevice1);
mNearbyDevices.add(mNearbyDevice2);
} }
@Test @Test
@@ -159,13 +178,21 @@ public class MediaOutputControllerTest extends SysuiTestCase {
public void start_withoutPackageName_verifyMediaControllerInit() { public void start_withoutPackageName_verifyMediaControllerInit() {
mMediaOutputController = new MediaOutputController(mSpyContext, null, false, mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
mNotifCollection, mUiEventLogger, mDialogLaunchAnimator); mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.start(mCb); mMediaOutputController.start(mCb);
verify(mMediaController, never()).registerCallback(any()); verify(mMediaController, never()).registerCallback(any());
} }
@Test
public void start_nearbyMediaDevicesManagerNotNull_registersNearbyDevicesCallback() {
mMediaOutputController.start(mCb);
verify(mNearbyMediaDevicesManager).registerNearbyDevicesCallback(any());
}
@Test @Test
public void stop_withPackageName_verifyMediaControllerDeinit() { public void stop_withPackageName_verifyMediaControllerDeinit() {
mMediaOutputController.start(mCb); mMediaOutputController.start(mCb);
@@ -180,7 +207,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
public void stop_withoutPackageName_verifyMediaControllerDeinit() { public void stop_withoutPackageName_verifyMediaControllerDeinit() {
mMediaOutputController = new MediaOutputController(mSpyContext, null, false, mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
mNotifCollection, mUiEventLogger, mDialogLaunchAnimator); mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.start(mCb); mMediaOutputController.start(mCb);
@@ -189,6 +217,39 @@ public class MediaOutputControllerTest extends SysuiTestCase {
verify(mMediaController, never()).unregisterCallback(any()); verify(mMediaController, never()).unregisterCallback(any());
} }
@Test
public void stop_nearbyMediaDevicesManagerNotNull_unregistersNearbyDevicesCallback() {
mMediaOutputController.start(mCb);
reset(mMediaController);
mMediaOutputController.stop();
verify(mNearbyMediaDevicesManager).unregisterNearbyDevicesCallback(any());
}
@Test
public void onDevicesUpdated_unregistersNearbyDevicesCallback() throws RemoteException {
mMediaOutputController.start(mCb);
mMediaOutputController.onDevicesUpdated(ImmutableList.of());
verify(mNearbyMediaDevicesManager).unregisterNearbyDevicesCallback(any());
}
@Test
public void onDeviceListUpdate_withNearbyDevices_updatesRangeInformation()
throws RemoteException {
mMediaOutputController.start(mCb);
reset(mCb);
mMediaOutputController.onDevicesUpdated(mNearbyDevices);
mMediaOutputController.onDeviceListUpdate(mMediaDevices);
verify(mMediaDevice1).setRangeZone(NearbyDevice.RANGE_CLOSE);
verify(mMediaDevice2).setRangeZone(NearbyDevice.RANGE_FAR);
}
@Test @Test
public void onDeviceListUpdate_verifyDeviceListCallback() { public void onDeviceListUpdate_verifyDeviceListCallback() {
mMediaOutputController.start(mCb); mMediaOutputController.start(mCb);
@@ -451,7 +512,8 @@ public class MediaOutputControllerTest extends SysuiTestCase {
public void getNotificationLargeIcon_withoutPackageName_returnsNull() { public void getNotificationLargeIcon_withoutPackageName_returnsNull() {
mMediaOutputController = new MediaOutputController(mSpyContext, null, false, mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
mNotifCollection, mUiEventLogger, mDialogLaunchAnimator); mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
assertThat(mMediaOutputController.getNotificationIcon()).isNull(); assertThat(mMediaOutputController.getNotificationIcon()).isNull();
} }

View File

@@ -37,6 +37,7 @@ import com.android.settingslib.media.LocalMediaManager;
import com.android.settingslib.media.MediaDevice; import com.android.settingslib.media.MediaDevice;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.ShadeController;
@@ -48,6 +49,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
@SmallTest @SmallTest
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@@ -67,6 +69,8 @@ public class MediaOutputDialogTest extends SysuiTestCase {
mock(NotificationEntryManager.class); mock(NotificationEntryManager.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class); private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
NearbyMediaDevicesManager.class);
private MediaOutputDialog mMediaOutputDialog; private MediaOutputDialog mMediaOutputDialog;
private MediaOutputController mMediaOutputController; private MediaOutputController mMediaOutputController;
@@ -76,7 +80,8 @@ public class MediaOutputDialogTest extends SysuiTestCase {
public void setUp() { public void setUp() {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false, mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator); mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
mMediaOutputDialog = new MediaOutputDialog(mContext, false, mMediaOutputDialog = new MediaOutputDialog(mContext, false,
mMediaOutputController, mUiEventLogger); mMediaOutputController, mUiEventLogger);

View File

@@ -35,6 +35,7 @@ import com.android.settingslib.media.MediaDevice;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.ShadeController;
@@ -46,6 +47,7 @@ import org.junit.runner.RunWith;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
@SmallTest @SmallTest
@RunWith(AndroidTestingRunner.class) @RunWith(AndroidTestingRunner.class)
@@ -66,6 +68,8 @@ public class MediaOutputGroupDialogTest extends SysuiTestCase {
mock(NotificationEntryManager.class); mock(NotificationEntryManager.class);
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class); private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class); private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
private NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
NearbyMediaDevicesManager.class);
private MediaOutputGroupDialog mMediaOutputGroupDialog; private MediaOutputGroupDialog mMediaOutputGroupDialog;
private MediaOutputController mMediaOutputController; private MediaOutputController mMediaOutputController;
@@ -75,7 +79,8 @@ public class MediaOutputGroupDialogTest extends SysuiTestCase {
public void setUp() { public void setUp() {
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false, mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter, mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator); mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
Optional.of(mNearbyMediaDevicesManager));
mMediaOutputController.mLocalMediaManager = mLocalMediaManager; mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false, mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false,
mMediaOutputController); mMediaOutputController);