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

Commit efadb12e authored by Shaowei Shen's avatar Shaowei Shen Committed by Automerger Merge Worker
Browse files

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

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17052086

Change-Id: Ie5fd30433bd43ed417c12fa394375561ab30cf8e
parents 5bd65343 9a373389
Loading
Loading
Loading
Loading
+33 −5
Original line number Diff line number Diff line
@@ -22,9 +22,10 @@ import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;


import java.lang.annotation.Retention;
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.
@@ -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>
 * </ul>
 *
 * @hide
 */
@SystemApi
@@ -77,7 +79,8 @@ public final class NearbyDevice implements Parcelable {
            RANGE_WITHIN_REACH
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface RangeZone {}
    public @interface RangeZone {
    }

    /**
     * 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. */
    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
    public int describeContents() {
        return 0;
+16 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.NearbyDevice;
import android.text.TextUtils;
import android.util.Log;

@@ -77,6 +78,8 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {

    private int mConnectedRecord;
    private int mState;
    @NearbyDevice.RangeZone
    private int mRangeZone = NearbyDevice.RANGE_UNKNOWN;

    protected final Context mContext;
    protected final MediaRoute2Info mRouteInfo;
@@ -136,6 +139,14 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
                getId());
    }

    public @NearbyDevice.RangeZone int getRangeZone() {
        return mRangeZone;
    }

    public void setRangeZone(@NearbyDevice.RangeZone int rangeZone) {
        mRangeZone = rangeZone;
    }

    /**
     * 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) {
            // Check device is muting expected device
            if (isMutingExpectedDevice()) {
+13 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.media.MediaRoute2Info;
import android.media.MediaRouter2Manager;
import android.media.NearbyDevice;
import android.os.Parcel;

import com.android.settingslib.bluetooth.A2dpProfile;
@@ -199,6 +200,18 @@ public class MediaDeviceTest {
        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
    public void compareTo_carKit_info_carKitFirst() {
        when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
+49 −3
Original line number Diff line number Diff line
@@ -30,12 +30,16 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.media.INearbyMediaDevicesUpdateCallback;
import android.media.MediaMetadata;
import android.media.MediaRoute2Info;
import android.media.NearbyDevice;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -61,6 +65,7 @@ import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
import com.android.systemui.monet.ColorScheme;
import com.android.systemui.plugins.ActivityStarter;
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.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.inject.Inject;
@@ -77,7 +85,8 @@ import javax.inject.Inject;
/**
 * 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 boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -95,6 +104,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
    private final CommonNotifCollection mNotifCollection;
    @VisibleForTesting
    final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
    private final NearbyMediaDevicesManager mNearbyMediaDevicesManager;
    private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>();

    private MediaController mMediaController;
    @VisibleForTesting
@@ -116,7 +127,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
            boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager
            lbm, ShadeController shadeController, ActivityStarter starter,
            CommonNotifCollection notifCollection, UiEventLogger uiEventLogger,
            DialogLaunchAnimator dialogLaunchAnimator) {
            DialogLaunchAnimator dialogLaunchAnimator,
            Optional<NearbyMediaDevicesManager> nearbyMediaDevicesManagerOptional) {
        mContext = context;
        mPackageName = packageName;
        mMediaSessionManager = mediaSessionManager;
@@ -130,6 +142,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
        mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
        mUiEventLogger = uiEventLogger;
        mDialogLaunchAnimator = dialogLaunchAnimator;
        mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
        mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
                R.color.media_dialog_active_item_main_content);
        mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
@@ -144,6 +157,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {

    void start(@NonNull Callback cb) {
        mMediaDevices.clear();
        mNearbyDeviceInfoMap.clear();
        if (mNearbyMediaDevicesManager != null) {
            mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this);
        }
        if (!TextUtils.isEmpty(mPackageName)) {
            for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
                if (TextUtils.equals(controller.getPackageName(), mPackageName)) {
@@ -187,6 +204,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
            mLocalMediaManager.stopScan();
        }
        mMediaDevices.clear();
        if (mNearbyMediaDevicesManager != null) {
            mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
        }
        mNearbyDeviceInfoMap.clear();
    }

    @Override
@@ -417,6 +438,15 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
        }
        mMediaDevices.clear();
        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() {
@@ -604,7 +634,9 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
        // We show the output group dialog from the output dialog.
        MediaOutputController controller = new MediaOutputController(mContext, mPackageName,
                mAboveStatusbar, mMediaSessionManager, mLocalBluetoothManager, mShadeController,
                mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
                mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
                Optional.of(mNearbyMediaDevicesManager));

        MediaOutputGroupDialog dialog = new MediaOutputGroupDialog(mContext, mAboveStatusbar,
                controller);
        mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog);
@@ -629,6 +661,20 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback {
                || 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() {
        @Override
        public void onMetadataChanged(MediaMetadata metadata) {
+6 −3
Original line number Diff line number Diff line
@@ -22,9 +22,11 @@ import android.view.View
import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.media.nearby.NearbyMediaDevicesManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import com.android.systemui.statusbar.phone.ShadeController
import java.util.Optional
import javax.inject.Inject

/**
@@ -38,7 +40,8 @@ class MediaOutputDialogFactory @Inject constructor(
    private val starter: ActivityStarter,
    private val notifCollection: CommonNotifCollection,
    private val uiEventLogger: UiEventLogger,
    private val dialogLaunchAnimator: DialogLaunchAnimator
    private val dialogLaunchAnimator: DialogLaunchAnimator,
    private val nearbyMediaDevicesManagerOptional: Optional<NearbyMediaDevicesManager>
) {
    companion object {
        var mediaOutputDialog: MediaOutputDialog? = null
@@ -51,7 +54,7 @@ class MediaOutputDialogFactory @Inject constructor(

        val controller = MediaOutputController(context, packageName, aboveStatusBar,
                mediaSessionManager, lbm, shadeController, starter, notifCollection,
            uiEventLogger, dialogLaunchAnimator)
                uiEventLogger, dialogLaunchAnimator, nearbyMediaDevicesManagerOptional)
        val dialog = MediaOutputDialog(context, aboveStatusBar, controller, uiEventLogger)
        mediaOutputDialog = dialog

Loading