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

Commit 45ff2b09 authored by Hugh Chen's avatar Hugh Chen Committed by Android (Google) Code Review
Browse files

Merge changes I04291231,Ia224f6e3,I6daa22a7 into rvc-dev

* changes:
  Add null check when build MediaDevice
  Base on MediaDeviceType to ranking devices list
  Add new route type for support 3.5 mm headset and usb headset
parents d8759bb3 71a7f826
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -88,6 +88,13 @@ public class BluetoothMediaDevice extends MediaDevice {
        return false;
    }

    @Override
    public boolean isFastPairDevice() {
        return mCachedDevice != null
                && BluetoothUtils.getBooleanMetaData(
                mCachedDevice.getDevice(), BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET);
    }

    @Override
    public boolean isConnected() {
        return mCachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
+19 −5
Original line number Diff line number Diff line
@@ -17,11 +17,16 @@ package com.android.settingslib.media;

import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_DOCK;
import static android.media.MediaRoute2Info.TYPE_GROUP;
import static android.media.MediaRoute2Info.TYPE_HDMI;
import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY;
import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
@@ -339,7 +344,7 @@ public class InfoMediaManager extends MediaManager {
        for (MediaRoute2Info route : mRouterManager.getAllRoutes()) {
            if (DEBUG) {
                Log.d(TAG, "buildAllRoutes() route : " + route.getName() + ", volume : "
                        + route.getVolume());
                        + route.getVolume() + ", type : " + route.getType());
            }
            if (route.isSystemRoute()) {
                addMediaDevice(route);
@@ -350,13 +355,15 @@ public class InfoMediaManager extends MediaManager {
    private void buildAvailableRoutes() {
        for (MediaRoute2Info route : mRouterManager.getAvailableRoutes(mPackageName)) {
            if (DEBUG) {
                Log.d(TAG, "buildAvailableRoutes() route : " + route.getName());
                Log.d(TAG, "buildAvailableRoutes() route : " + route.getName()
                        + ", type : " + route.getType());
            }
            addMediaDevice(route);
        }
    }

    private void addMediaDevice(MediaRoute2Info route) {
    @VisibleForTesting
    void addMediaDevice(MediaRoute2Info route) {
        final int deviceType = route.getType();
        MediaDevice mediaDevice = null;
        switch (deviceType) {
@@ -374,6 +381,11 @@ public class InfoMediaManager extends MediaManager {
                }
                break;
            case TYPE_BUILTIN_SPEAKER:
            case TYPE_USB_DEVICE:
            case TYPE_USB_HEADSET:
            case TYPE_USB_ACCESSORY:
            case TYPE_DOCK:
            case TYPE_HDMI:
            case TYPE_WIRED_HEADSET:
            case TYPE_WIRED_HEADPHONES:
                mediaDevice =
@@ -385,8 +397,10 @@ public class InfoMediaManager extends MediaManager {
                        BluetoothAdapter.getDefaultAdapter().getRemoteDevice(route.getOriginalId());
                final CachedBluetoothDevice cachedDevice =
                        mBluetoothManager.getCachedDeviceManager().findDevice(device);
                if (cachedDevice != null) {
                    mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice, mRouterManager,
                            route, mPackageName);
                }
                break;
            default:
                Log.w(TAG, "addMediaDevice() unknown device type : " + deviceType);
+2 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -185,7 +186,7 @@ public class LocalMediaManager implements BluetoothCallback {
    }

    void dispatchDeviceListUpdate() {
        //TODO(b/149260820): Use new rule to rank device once device type api is ready.
        Collections.sort(mMediaDevices, COMPARATOR);
        for (DeviceCallback callback : getCallbacks()) {
            callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices));
        }
+69 −32
Original line number Diff line number Diff line
@@ -17,11 +17,16 @@ package com.android.settingslib.media;

import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_DOCK;
import static android.media.MediaRoute2Info.TYPE_GROUP;
import static android.media.MediaRoute2Info.TYPE_HDMI;
import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY;
import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;

@@ -102,6 +107,13 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
            case TYPE_WIRED_HEADPHONES:
                mType = MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE;
                break;
            case TYPE_USB_DEVICE:
            case TYPE_USB_HEADSET:
            case TYPE_USB_ACCESSORY:
            case TYPE_DOCK:
            case TYPE_HDMI:
                mType = MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE;
                break;
            case TYPE_HEARING_AID:
            case TYPE_BLUETOOTH_A2DP:
                mType = MediaDeviceType.TYPE_BLUETOOTH_DEVICE;
@@ -266,16 +278,22 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {

    /**
     * Rules:
     * 1. If there is one of the connected devices identified as a carkit, this carkit will
     * be always on the top of the device list. Rule 2 and Rule 3 can’t overrule this rule.
     * 1. If there is one of the connected devices identified as a carkit or fast pair device,
     * the fast pair device will be always on the first of the device list and carkit will be
     * second. Rule 2 and Rule 3 can’t overrule this rule.
     * 2. For devices without any usage data yet
     * WiFi device group sorted by alphabetical order + BT device group sorted by alphabetical
     * order + phone speaker
     * 3. For devices with usage record.
     * The most recent used one + device group with usage info sorted by how many times the
     * device has been used.
     * 4. Phone device always in the top and the connected Bluetooth devices, cast devices and
     * phone device will be always above on the disconnect Bluetooth devices.
     * 4. The order is followed below rule:
     *    1. USB-C audio device
     *    2. 3.5 mm audio device
     *    3. Bluetooth device
     *    4. Cast device
     *    5. Cast group device
     *    6. Phone
     *
     * So the device list will look like 5 slots ranked as below.
     * Rule 4 + Rule 1 + the most recently used device + Rule 3 + Rule 2
@@ -295,20 +313,24 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
            }
        }

        // Phone device always in the top.
        if (mType == MediaDeviceType.TYPE_PHONE_DEVICE) {
        if (mType == another.mType) {
            // Check fast pair device
            if (isFastPairDevice()) {
                return -1;
        } else if (another.mType == MediaDeviceType.TYPE_PHONE_DEVICE) {
            } else if (another.isFastPairDevice()) {
                return 1;
            }

            // Check carkit
            if (isCarKitDevice()) {
                return -1;
            } else if (another.isCarKitDevice()) {
                return 1;
            }

            // Set last used device at the first item
        String lastSelectedDevice = ConnectionRecordManager.getInstance().getLastSelectedDevice();
            final String lastSelectedDevice = ConnectionRecordManager.getInstance()
                    .getLastSelectedDevice();
            if (TextUtils.equals(lastSelectedDevice, getId())) {
                return -1;
            } else if (TextUtils.equals(lastSelectedDevice, another.getId())) {
@@ -319,15 +341,22 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
                    && (another.mConnectedRecord > 0 || mConnectedRecord > 0)) {
                return (another.mConnectedRecord - mConnectedRecord);
            }

            // Both devices have never been used
            // To devices with the same type, sort by alphabetical order
        if (mType == another.mType) {
            final String s1 = getName();
            final String s2 = another.getName();
            return s1.compareToIgnoreCase(s2);
        } else {
            // Both devices have never been used, the priority is:
            // 1. USB-C audio device
            // 2. 3.5 mm audio device
            // 3. Bluetooth device
            // 4. Cast device
            // 5. Cast group device
            // 6. Phone
            return mType < another.mType ? -1 : 1;
        }
        // Both devices have never been used, the priority is Phone > Cast > Bluetooth
        return mType - another.mType;
    }

    /**
@@ -338,6 +367,14 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
        return false;
    }

    /**
     * Check if it is FastPair device
     * @return {@code true} if it is FastPair device, otherwise return {@code false}
     */
    protected boolean isFastPairDevice() {
        return false;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof MediaDevice)) {
+17 −0
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@
package com.android.settingslib.media;

import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
import static android.media.MediaRoute2Info.TYPE_DOCK;
import static android.media.MediaRoute2Info.TYPE_HDMI;
import static android.media.MediaRoute2Info.TYPE_USB_ACCESSORY;
import static android.media.MediaRoute2Info.TYPE_USB_DEVICE;
import static android.media.MediaRoute2Info.TYPE_USB_HEADSET;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADPHONES;
import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;

@@ -53,6 +58,13 @@ public class PhoneMediaDevice extends MediaDevice {
        switch (mRouteInfo.getType()) {
            case TYPE_WIRED_HEADSET:
            case TYPE_WIRED_HEADPHONES:
                name = mContext.getString(R.string.media_transfer_wired_device_name);
                break;
            case TYPE_USB_DEVICE:
            case TYPE_USB_HEADSET:
            case TYPE_USB_ACCESSORY:
            case TYPE_DOCK:
            case TYPE_HDMI:
                name = mRouteInfo.getName();
                break;
            case TYPE_BUILTIN_SPEAKER:
@@ -78,6 +90,11 @@ public class PhoneMediaDevice extends MediaDevice {
    int getDrawableResId() {
        int resId;
        switch (mRouteInfo.getType()) {
            case TYPE_USB_DEVICE:
            case TYPE_USB_HEADSET:
            case TYPE_USB_ACCESSORY:
            case TYPE_DOCK:
            case TYPE_HDMI:
            case TYPE_WIRED_HEADSET:
            case TYPE_WIRED_HEADPHONES:
                resId = com.android.internal.R.drawable.ic_bt_headphones_a2dp;
Loading