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

Commit d946904f authored by timhypeng's avatar timhypeng Committed by tim peng
Browse files

replace BluetoothUuid.isUuidPresent with getSupportedProfiles()

- getSupportedProfiles() is directly mapping to current supported
profile and it is more reasonable to create profile proxy according to
its list
- update test case

Bug: 112062630
Test: make -j50 RunSettingsLibRoboTests
Change-Id: Id2dc364dfa815e72db91b92bcee9745e6c40d34a
parent 3caa5404
Loading
Loading
Loading
Loading
+91 −163
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ import android.os.ParcelUuid;
import androidx.annotation.VisibleForTesting;
import android.util.Log;
import com.android.internal.R;
import com.android.internal.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -87,12 +89,12 @@ public class LocalBluetoothProfileManager {
    private HfpClientProfile mHfpClientProfile;
    private MapProfile mMapProfile;
    private MapClientProfile mMapClientProfile;
    private final HidProfile mHidProfile;
    private HidProfile mHidProfile;
    private HidDeviceProfile mHidDeviceProfile;
    private OppProfile mOppProfile;
    private final PanProfile mPanProfile;
    private PanProfile mPanProfile;
    private PbapClientProfile mPbapClientProfile;
    private final PbapServerProfile mPbapProfile;
    private PbapServerProfile mPbapProfile;
    private final boolean mUsePbapPce;
    private final boolean mUseMapClient;
    private HearingAidProfile mHearingAidProfile;
@@ -118,177 +120,106 @@ public class LocalBluetoothProfileManager {
        // pass this reference to adapter and event manager (circular dependency)
        mLocalAdapter.setProfileManager(this);

        ParcelUuid[] uuids = adapter.getUuids();

        // uuids may be null if Bluetooth is turned off
        if (uuids != null) {
            updateLocalProfiles(uuids);
        }

        // Always add HID host, HID device, and PAN profiles
        mHidProfile = new HidProfile(context, mLocalAdapter, mDeviceManager, this);
        addProfile(mHidProfile, HidProfile.NAME,
                BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED);

        mPanProfile = new PanProfile(context, mLocalAdapter);
        addPanProfile(mPanProfile, PanProfile.NAME,
                BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);

        mHidDeviceProfile = new HidDeviceProfile(context, mLocalAdapter, mDeviceManager, this);
        addProfile(mHidDeviceProfile, HidDeviceProfile.NAME,
                BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED);

        if(DEBUG) Log.d(TAG, "Adding local MAP profile");
        if (mUseMapClient) {
            mMapClientProfile = new MapClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mMapClientProfile, MapClientProfile.NAME,
                BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
        } else {
            mMapProfile = new MapProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mMapProfile, MapProfile.NAME,
                    BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
        }

        //Create PBAP server profile
        if(DEBUG) Log.d(TAG, "Adding local PBAP profile");

        mPbapProfile = new PbapServerProfile(context);
        addProfile(mPbapProfile, PbapServerProfile.NAME,
             BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);

        List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
        if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
            mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
                                                       this);
            addProfile(mHearingAidProfile, HearingAidProfile.NAME,
                       BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
        }
        updateLocalProfiles();
        if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
    }

    /**
     * Initialize or update the local profile objects. If a UUID was previously
     * present but has been removed, we print a warning but don't remove the
     * profile object as it might be referenced elsewhere, or the UUID might
     * come back and we don't want multiple copies of the profile objects.
     * @param uuids
     * create profile instance according to bluetooth supported profile list
     */
    void updateLocalProfiles(ParcelUuid[] uuids) {
        // A2DP SRC
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSource)) {
            if (mA2dpProfile == null) {
                if(DEBUG) Log.d(TAG, "Adding local A2DP SRC profile");
    void updateLocalProfiles() {
        List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
        if (CollectionUtils.isEmpty(supportedList)) {
            if(DEBUG) Log.d(TAG, "supportedList is null");
            return;
        }
        if (mA2dpProfile == null && supportedList.contains(BluetoothProfile.A2DP)) {
            if(DEBUG) Log.d(TAG, "Adding local A2DP profile");
            mA2dpProfile = new A2dpProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mA2dpProfile, A2dpProfile.NAME,
                    BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
        }
        } else if (mA2dpProfile != null) {
            Log.w(TAG, "Warning: A2DP profile was previously added but the UUID is now missing.");
        }

        // A2DP SINK
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSink)) {
            if (mA2dpSinkProfile == null) {
                if(DEBUG) Log.d(TAG, "Adding local A2DP Sink profile");
        if (mA2dpSinkProfile == null && supportedList.contains(BluetoothProfile.A2DP_SINK)) {
            if(DEBUG) Log.d(TAG, "Adding local A2DP SINK profile");
            mA2dpSinkProfile = new A2dpSinkProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mA2dpSinkProfile, A2dpSinkProfile.NAME,
                    BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED);
        }
        } else if (mA2dpSinkProfile != null) {
            Log.w(TAG, "Warning: A2DP Sink profile was previously added but the UUID is now missing.");
        }

        // Headset / Handsfree
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) ||
            BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP_AG)) {
            if (mHeadsetProfile == null) {
        if (mHeadsetProfile == null && supportedList.contains(BluetoothProfile.HEADSET)) {
            if (DEBUG) Log.d(TAG, "Adding local HEADSET profile");
                mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter,
                        mDeviceManager, this);
            mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addHeadsetProfile(mHeadsetProfile, HeadsetProfile.NAME,
                    BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
                    BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED,
                    BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
        }
        } else if (mHeadsetProfile != null) {
            Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing.");
        }

        // Headset HF
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree)) {
            if (mHfpClientProfile == null) {
        if (mHfpClientProfile == null && supportedList.contains(BluetoothProfile.HEADSET_CLIENT)) {
            if(DEBUG) Log.d(TAG, "Adding local HfpClient profile");
                mHfpClientProfile =
                    new HfpClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
            mHfpClientProfile = new HfpClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addHeadsetProfile(mHfpClientProfile, HfpClientProfile.NAME,
                    BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED,
                    BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED,
                    BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
        }
        } else if (mHfpClientProfile != null) {
            Log.w(TAG,
                "Warning: Hfp Client profile was previously added but the UUID is now missing.");
        } else {
            Log.d(TAG, "Handsfree Uuid not found.");
        }

        // Message Access Profile Client
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.MNS)) {
            if (mMapClientProfile == null) {
                if(DEBUG) Log.d(TAG, "Adding local Map Client profile");
        if (mUseMapClient) {
            if (mMapClientProfile == null && supportedList.contains(BluetoothProfile.MAP_CLIENT)) {
                if(DEBUG) Log.d(TAG, "Adding local MAP CLIENT profile");
                mMapClientProfile =
                        new MapClientProfile(mContext, mLocalAdapter, mDeviceManager,this);
                addProfile(mMapClientProfile, MapClientProfile.NAME,
                        BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
            }
        } else if (mMapClientProfile != null) {
            Log.w(TAG,
                    "Warning: MAP Client profile was previously added but the UUID is now missing.");
        } else {
            Log.d(TAG, "MAP Client Uuid not found.");
        } else if (mMapProfile == null && supportedList.contains(BluetoothProfile.MAP)) {
            if(DEBUG) Log.d(TAG, "Adding local MAP profile");
            mMapProfile = new MapProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mMapProfile, MapProfile.NAME, BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
        }

        // OPP
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) {
            if (mOppProfile == null) {
        if (mOppProfile == null && supportedList.contains(BluetoothProfile.OPP)) {
            if(DEBUG) Log.d(TAG, "Adding local OPP profile");
            mOppProfile = new OppProfile();
            // Note: no event handler for OPP, only name map.
            mProfileNameMap.put(OppProfile.NAME, mOppProfile);
        }
        } else if (mOppProfile != null) {
            Log.w(TAG, "Warning: OPP profile was previously added but the UUID is now missing.");
        if (mHearingAidProfile == null && supportedList.contains(BluetoothProfile.HEARING_AID)) {
            if(DEBUG) Log.d(TAG, "Adding local Hearing Aid profile");
            mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
                    this);
            addProfile(mHearingAidProfile, HearingAidProfile.NAME,
                    BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
        }
        if (mHidProfile == null && supportedList.contains(BluetoothProfile.HID_HOST)) {
            if(DEBUG) Log.d(TAG, "Adding local HID_HOST profile");
            mHidProfile = new HidProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mHidProfile, HidProfile.NAME,
                    BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED);
        }

        //PBAP Client
        if (mUsePbapPce) {
            if (mPbapClientProfile == null) {
        if (mHidDeviceProfile == null && supportedList.contains(BluetoothProfile.HID_DEVICE)) {
            if(DEBUG) Log.d(TAG, "Adding local HID_DEVICE profile");
            mHidDeviceProfile = new HidDeviceProfile(mContext, mLocalAdapter, mDeviceManager, this);
            addProfile(mHidDeviceProfile, HidDeviceProfile.NAME,
                    BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED);
        }
        if (mPanProfile == null && supportedList.contains(BluetoothProfile.PAN)) {
            if(DEBUG) Log.d(TAG, "Adding local PAN profile");
            mPanProfile = new PanProfile(mContext, mLocalAdapter);
            addPanProfile(mPanProfile, PanProfile.NAME,
                    BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
        }
        if (mPbapProfile == null && supportedList.contains(BluetoothProfile.PBAP)) {
            if(DEBUG) Log.d(TAG, "Adding local PBAP profile");
            mPbapProfile = new PbapServerProfile(mContext);
            addProfile(mPbapProfile, PbapServerProfile.NAME,
                    BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);
        }
        if (mUsePbapPce && mPbapClientProfile == null && supportedList.contains(
                BluetoothProfile.PBAP_CLIENT)) {
            if(DEBUG) Log.d(TAG, "Adding local PBAP Client profile");
            mPbapClientProfile = new PbapClientProfile(mContext, mLocalAdapter, mDeviceManager,
                    this);
            addProfile(mPbapClientProfile, PbapClientProfile.NAME,
                    BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
        }
        } else if (mPbapClientProfile != null) {
            Log.w(TAG,
                "Warning: PBAP Client profile was previously added but the UUID is now missing.");
        }

        //Hearing Aid Client
        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid)) {
            if (mHearingAidProfile == null) {
                if(DEBUG) Log.d(TAG, "Adding local Hearing Aid profile");
                mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager, this);
                addProfile(mHearingAidProfile, HearingAidProfile.NAME,
                        BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
            }
        } else if (mHearingAidProfile != null) {
            Log.w(TAG, "Warning: Hearing Aid profile was previously added but the UUID is now missing.");
        }

        mEventManager.registerProfileIntentReceiver();

        // There is no local SDP record for HID and Settings app doesn't control PBAP Server.
    }

    private void addHeadsetProfile(LocalBluetoothProfile profile, String profileName,
@@ -322,10 +253,7 @@ public class LocalBluetoothProfileManager {

    // Called from LocalBluetoothAdapter when state changes to ON
    void setBluetoothStateOn() {
        ParcelUuid[] uuids = mLocalAdapter.getUuids();
        if (uuids != null) {
            updateLocalProfiles(uuids);
        }
        updateLocalProfiles();
        mEventManager.readPairedDevices();
    }

+34 −11
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -80,6 +81,10 @@ public class LocalBluetoothProfileManagerTest {
     */
    @Test
    public void constructor_initiateHidAndHidDeviceProfile() {
        when(mAdapter.getSupportedProfiles()).thenReturn(
                generateList(new int[] {BluetoothProfile.HID_HOST}));
        when(mAdapter.getSupportedProfiles()).thenReturn(
                generateList(new int[] {BluetoothProfile.HID_HOST, BluetoothProfile.HID_DEVICE}));
        mProfileManager =
                new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);

@@ -94,12 +99,12 @@ public class LocalBluetoothProfileManagerTest {
    public void updateLocalProfiles_addA2dpToLocalProfiles() {
        mProfileManager =
                new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
        when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
        assertThat(mProfileManager.getA2dpProfile()).isNull();
        assertThat(mProfileManager.getHeadsetProfile()).isNull();

        ParcelUuid[] uuids = mAdapter.getUuids();
        mProfileManager.updateLocalProfiles(uuids);
        when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
                new int[] {BluetoothProfile.A2DP}));
        mProfileManager.updateLocalProfiles();

        assertThat(mProfileManager.getA2dpProfile()).isNotNull();
        assertThat(mProfileManager.getHeadsetProfile()).isNull();
@@ -110,6 +115,8 @@ public class LocalBluetoothProfileManagerTest {
     */
    @Test
    public void updateProfiles_addHidProfileForRemoteDevice() {
        when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
                new int[] {BluetoothProfile.HID_HOST}));
        mProfileManager =
                new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
        ParcelUuid[] uuids = new ParcelUuid[]{BluetoothUuid.Hid};
@@ -131,7 +138,8 @@ public class LocalBluetoothProfileManagerTest {
     */
    @Test
    public void stateChangedHandler_receiveA2dpConnectionStateChanged_shouldDispatchCallback() {
        when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
        when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
                new int[] {BluetoothProfile.A2DP}));
        mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
                mEventManager);
        // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
@@ -154,7 +162,8 @@ public class LocalBluetoothProfileManagerTest {
     */
    @Test
    public void stateChangedHandler_receiveHeadsetConnectionStateChanged_shouldDispatchCallback() {
        when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.Handsfree_AG});
        when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
                new int[] {BluetoothProfile.HEADSET}));
        mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
                mEventManager);
        // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
@@ -203,7 +212,8 @@ public class LocalBluetoothProfileManagerTest {
     */
    @Test
    public void stateChangedHandler_receivePanConnectionStateChanged_shouldNotDispatchCallback() {
        when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
        when(mAdapter.getSupportedProfiles()).thenReturn(
                generateList(new int[] {BluetoothProfile.PAN}));
        mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
                mEventManager);
        // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
@@ -225,8 +235,9 @@ public class LocalBluetoothProfileManagerTest {
     * handler and refresh CachedBluetoothDevice
     */
    @Test
    public void stateChangedHandler_receivePanConnectionStateChangedWithoutUuid_shouldNotRefresh() {
        when(mAdapter.getUuids()).thenReturn(null);
    public void stateChangedHandler_receivePanConnectionStateChangedWithoutProfile_shouldNotRefresh
    () {
        when(mAdapter.getSupportedProfiles()).thenReturn(null);
        mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
                mEventManager);
        // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
@@ -239,7 +250,7 @@ public class LocalBluetoothProfileManagerTest {

        mContext.sendBroadcast(mIntent);

        verify(mCachedBluetoothDevice).refresh();
        verify(mCachedBluetoothDevice, never()).refresh();
    }

    /**
@@ -247,8 +258,9 @@ public class LocalBluetoothProfileManagerTest {
     * handler and refresh CachedBluetoothDevice
     */
    @Test
    public void stateChangedHandler_receivePanConnectionStateChangedWithUuids_shouldRefresh() {
        when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
    public void stateChangedHandler_receivePanConnectionStateChangedWithProfile_shouldRefresh() {
        when(mAdapter.getSupportedProfiles()).thenReturn(generateList(
                new int[] {BluetoothProfile.PAN}));
        mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
                mEventManager);
        // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
@@ -263,4 +275,15 @@ public class LocalBluetoothProfileManagerTest {

        verify(mCachedBluetoothDevice).refresh();
    }

    private List<Integer> generateList(int[] profile) {
        if (profile == null) {
            return null;
        }
        final List<Integer> profileList = new ArrayList<>(profile.length);
        for(int i = 0; i < profile.length; i++) {
            profileList.add(profile[i]);
        }
        return profileList;
    }
}