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

Commit bd0dd494 authored by hughchen's avatar hughchen
Browse files

Add onConnectedDeviceChanged() onServiceConnected() callback

- Add onConnectedDeviceChanged() callback to notify MediaDevice
  to change their connect state.

- Add onServiceConnected() to handle profile not ready
  case. The profile may not ready when calling startScan().
  Device status are all disconnected since profiles are not ready to connected.
  In this case, we observe onServiceConnected() in LocalBluetoothProfileManager.
  When A2dpProfile or HearingAidProfile is connected will call buildBluetoothDeviceList()
  again to find the connected devices.

Bug: 121083246
Test: make -j50 RunSettingsLibRoboTests
Change-Id: I6d8bacb9bbd2221eb8c97bbd0419b4e8c9d8dfea
parent 4260098e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ public class A2dpProfile implements LocalBluetoothProfile {
                device.refresh();
            }
            mIsProfileReady=true;
            mProfileManager.callServiceConnectedListeners();
        }

        public void onServiceDisconnected(int profile) {
+1 −1
Original line number Diff line number Diff line
@@ -71,8 +71,8 @@ public class HearingAidProfile implements LocalBluetoothProfile {

            // Check current list of CachedDevices to see if any are Hearing Aid devices.
            mDeviceManager.updateHearingAidsDevices();

            mIsProfileReady=true;
            mProfileManager.callServiceConnectedListeners();
        }

        public void onServiceDisconnected(int profile) {
+5 −5
Original line number Diff line number Diff line
@@ -54,17 +54,17 @@ public class BluetoothMediaDevice extends MediaDevice {
    }

    @Override
    public void connect() {
    public boolean connect() {
        //TODO(b/117129183): add callback to notify LocalMediaManager connection state.
        mIsConnected = mCachedDevice.setActive();
        super.connect();
        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
        final boolean isConnected = mCachedDevice.setActive();
        setConnectedRecord();
        Log.d(TAG, "connect() device : " + getName() + ", is selected : " + isConnected);
        return isConnected;
    }

    @Override
    public void disconnect() {
        //TODO(b/117129183): disconnected last select device
        mIsConnected = false;
    }

    /**
+52 −29
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.settingslib.media;
import android.app.Notification;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.util.Log;

@@ -35,36 +36,48 @@ import java.util.List;
/**
 * BluetoothMediaManager provide interface to get Bluetooth device list.
 */
public class BluetoothMediaManager extends MediaManager implements BluetoothCallback {
public class BluetoothMediaManager extends MediaManager implements BluetoothCallback,
        LocalBluetoothProfileManager.ServiceListener {

    private static final String TAG = "BluetoothMediaManager";

    private final DeviceAttributeChangeCallback mCachedDeviceCallback =
            new DeviceAttributeChangeCallback();

    private LocalBluetoothManager mLocalBluetoothManager;
    private LocalBluetoothProfileManager mProfileManager;
    private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;

    private MediaDevice mLastAddedDevice;
    private MediaDevice mLastRemovedDevice;

    private boolean mIsA2dpProfileReady = false;
    private boolean mIsHearingAidProfileReady = false;

    BluetoothMediaManager(Context context, LocalBluetoothManager localBluetoothManager,
            Notification notification) {
        super(context, notification);

        mLocalBluetoothManager = localBluetoothManager;
        mProfileManager = mLocalBluetoothManager.getProfileManager();
        mCachedBluetoothDeviceManager = mLocalBluetoothManager.getCachedDeviceManager();
    }

    @Override
    public void startScan() {
        mMediaDevices.clear();
        mLocalBluetoothManager.getEventManager().registerCallback(this);
        buildBluetoothDeviceList();
        dispatchDeviceListAdded();

        // The profile may not ready when calling startScan().
        // Device status are all disconnected since profiles are not ready to connected.
        // In this case, we observe onServiceConnected() in LocalBluetoothProfileManager.
        // When A2dpProfile or HearingAidProfile is connected will call buildBluetoothDeviceList()
        // again to find the connected devices.
        if (!mIsA2dpProfileReady || !mIsHearingAidProfileReady) {
            mProfileManager.addServiceListener(this);
        }
    }

    private void buildBluetoothDeviceList() {
        mMediaDevices.clear();
        addConnectedA2dpDevices();
        addConnectedHearingAidDevices();
    }
@@ -77,12 +90,10 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
        }

        final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices();
        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
                mLocalBluetoothManager.getCachedDeviceManager();

        for (BluetoothDevice device : devices) {
            final CachedBluetoothDevice cachedDevice =
                    cachedBluetoothDeviceManager.findDevice(device);
                    mCachedBluetoothDeviceManager.findDevice(device);

            if (cachedDevice == null) {
                Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
@@ -96,6 +107,8 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
                addMediaDevice(cachedDevice);
            }
        }

        mIsA2dpProfileReady = a2dpProfile.isProfileReady();
    }

    private void addConnectedHearingAidDevices() {
@@ -107,12 +120,10 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall

        final List<Long> devicesHiSyncIds = new ArrayList<>();
        final List<BluetoothDevice> devices = hapProfile.getConnectedDevices();
        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
                mLocalBluetoothManager.getCachedDeviceManager();

        for (BluetoothDevice device : devices) {
            final CachedBluetoothDevice cachedDevice =
                    cachedBluetoothDeviceManager.findDevice(device);
                    mCachedBluetoothDeviceManager.findDevice(device);

            if (cachedDevice == null) {
                Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
@@ -130,13 +141,14 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
                addMediaDevice(cachedDevice);
            }
        }

        mIsHearingAidProfileReady = hapProfile.isProfileReady();
    }

    private void addMediaDevice(CachedBluetoothDevice cachedDevice) {
        MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
        if (mediaDevice == null) {
            mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice);
            cachedDevice.registerCallback(mCachedDeviceCallback);
            mLastAddedDevice = mediaDevice;
            mMediaDevices.add(mediaDevice);
        }
@@ -145,16 +157,6 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
    @Override
    public void stopScan() {
        mLocalBluetoothManager.getEventManager().unregisterCallback(this);
        unregisterCachedDeviceCallback();
    }

    private void unregisterCachedDeviceCallback() {
        for (MediaDevice device : mMediaDevices) {
            if (device instanceof BluetoothMediaDevice) {
                ((BluetoothMediaDevice) device).getCachedDevice()
                        .unregisterCallback(mCachedDeviceCallback);
            }
        }
    }

    @Override
@@ -166,8 +168,6 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
            final List<MediaDevice> removeDevicesList = new ArrayList<>();
            for (MediaDevice device : mMediaDevices) {
                if (device instanceof BluetoothMediaDevice) {
                    ((BluetoothMediaDevice) device).getCachedDevice()
                            .unregisterCallback(mCachedDeviceCallback);
                    removeDevicesList.add(device);
                }
            }
@@ -212,7 +212,6 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
    private void removeMediaDevice(CachedBluetoothDevice cachedDevice) {
        final MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
        if (mediaDevice != null) {
            cachedDevice.unregisterCallback(mCachedDeviceCallback);
            mLastRemovedDevice = mediaDevice;
            mMediaDevices.remove(mediaDevice);
        }
@@ -252,10 +251,34 @@ public class BluetoothMediaManager extends MediaManager implements BluetoothCall
            dispatchDeviceRemoved(cachedDevice);
        }
    }
    class DeviceAttributeChangeCallback implements CachedBluetoothDevice.Callback {

    @Override
        public void onDeviceAttributesChanged() {
            dispatchDeviceAttributesChanged();
    public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
        Log.d(TAG, "onActiveDeviceChanged : device : "
                + activeDevice + ", profile : " + bluetoothProfile);
        if (BluetoothProfile.HEARING_AID == bluetoothProfile
                || BluetoothProfile.A2DP == bluetoothProfile) {
            final String id = activeDevice == null
                    ? PhoneMediaDevice.ID : MediaDeviceUtils.getId(activeDevice);
            dispatchConnectedDeviceChanged(id);
        }
    }

    @Override
    public void onServiceConnected() {
        if (!mIsA2dpProfileReady || !mIsHearingAidProfileReady) {
            buildBluetoothDeviceList();
            dispatchDeviceListAdded();
        }

        //Remove the listener once a2dpProfile and hearingAidProfile are ready.
        if (mIsA2dpProfileReady && mIsHearingAidProfileReady) {
            mProfileManager.removeServiceListener(this);
        }
    }

    @Override
    public void onServiceDisconnected() {

    }
}
+8 −7
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.settingslib.media;

import android.content.Context;
import android.widget.Toast;

import androidx.mediarouter.media.MediaRouter;

@@ -43,7 +44,7 @@ public class InfoMediaDevice extends MediaDevice {

    @Override
    public int getIcon() {
        //TODO(b/117129183): This is not final icon for cast device, just for demo.
        //TODO(b/121083246): This is not final icon for cast device, just for demo.
        return R.drawable.ic_settings_print;
    }

@@ -53,15 +54,15 @@ public class InfoMediaDevice extends MediaDevice {
    }

    @Override
    public void connect() {
        //TODO(b/117129183): use MediaController2 to transfer media
        mIsConnected = true;
        super.connect();
    public boolean connect() {
        //TODO(b/121083246): use SystemApi to transfer media
        setConnectedRecord();
        Toast.makeText(mContext, "This is cast device !", Toast.LENGTH_SHORT).show();
        return false;
    }

    @Override
    public void disconnect() {
        //TODO(b/117129183): disconnected last select device
        mIsConnected = false;
        //TODO(b/121083246): disconnected last select device
    }
}
Loading