Merge changes I3af271d0,I46df1c8b,I1eb116e4,I492bfc97

* changes:
  CachedBluetoothDevice: Add tests for connect fail
  CachedBluetoothDevice: Fix merge conflict
  CachedBluetoothDevice: Fix detecting connect fail
  CachedBluetoothDevice: Add missing LeAudioProfile
This commit is contained in:
Michał Narajowski
2023-03-07 09:36:25 +00:00
committed by Gerrit Code Review
2 changed files with 85 additions and 2 deletions

View File

@@ -208,7 +208,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
synchronized (mProfileLock) { synchronized (mProfileLock) {
if (profile instanceof A2dpProfile || profile instanceof HeadsetProfile if (profile instanceof A2dpProfile || profile instanceof HeadsetProfile
|| profile instanceof HearingAidProfile) { || profile instanceof HearingAidProfile || profile instanceof LeAudioProfile) {
setProfileConnectedStatus(profile.getProfileId(), false); setProfileConnectedStatus(profile.getProfileId(), false);
switch (newProfileState) { switch (newProfileState) {
case BluetoothProfile.STATE_CONNECTED: case BluetoothProfile.STATE_CONNECTED:
@@ -226,7 +226,20 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
case BluetoothProfile.STATE_DISCONNECTED: case BluetoothProfile.STATE_DISCONNECTED:
if (mHandler.hasMessages(profile.getProfileId())) { if (mHandler.hasMessages(profile.getProfileId())) {
mHandler.removeMessages(profile.getProfileId()); mHandler.removeMessages(profile.getProfileId());
setProfileConnectedStatus(profile.getProfileId(), true); if (profile.getConnectionPolicy(mDevice) >
BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
/*
* If we received state DISCONNECTED and previous state was
* CONNECTING and connection policy is FORBIDDEN or UNKNOWN
* then it's not really a failure to connect.
*
* Connection profile is considered as failed when connection
* policy indicates that profile should be connected
* but it got disconnected.
*/
Log.w(TAG, "onProfileStateChanged(): Failed to connect profile");
setProfileConnectedStatus(profile.getProfileId(), true);
}
} }
break; break;
default: default:
@@ -1188,6 +1201,13 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
} }
private boolean isProfileConnectedFail() { private boolean isProfileConnectedFail() {
Log.d(TAG, "anonymizedAddress=" + mDevice.getAnonymizedAddress()
+ " mIsA2dpProfileConnectedFail=" + mIsA2dpProfileConnectedFail
+ " mIsHearingAidProfileConnectedFail=" + mIsHearingAidProfileConnectedFail
+ " mIsLeAudioProfileConnectedFail=" + mIsLeAudioProfileConnectedFail
+ " mIsHeadsetProfileConnectedFail=" + mIsHeadsetProfileConnectedFail
+ " isConnectedSapDevice()=" + isConnectedSapDevice());
return mIsA2dpProfileConnectedFail || mIsHearingAidProfileConnectedFail return mIsA2dpProfileConnectedFail || mIsHearingAidProfileConnectedFail
|| (!isConnectedSapDevice() && mIsHeadsetProfileConnectedFail) || (!isConnectedSapDevice() && mIsHeadsetProfileConnectedFail)
|| mIsLeAudioProfileConnectedFail; || mIsLeAudioProfileConnectedFail;

View File

@@ -74,6 +74,8 @@ public class CachedBluetoothDeviceTest {
@Mock @Mock
private HearingAidProfile mHearingAidProfile; private HearingAidProfile mHearingAidProfile;
@Mock @Mock
private LeAudioProfile mLeAudioProfile;
@Mock
private BluetoothDevice mDevice; private BluetoothDevice mDevice;
@Mock @Mock
private BluetoothDevice mSubDevice; private BluetoothDevice mSubDevice;
@@ -92,15 +94,76 @@ public class CachedBluetoothDeviceTest {
mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS); when(mDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
when(mHfpProfile.isProfileReady()).thenReturn(true); when(mHfpProfile.isProfileReady()).thenReturn(true);
when(mHfpProfile.getProfileId()).thenReturn(BluetoothProfile.HEADSET);
when(mA2dpProfile.isProfileReady()).thenReturn(true); when(mA2dpProfile.isProfileReady()).thenReturn(true);
when(mA2dpProfile.getProfileId()).thenReturn(BluetoothProfile.A2DP);
when(mPanProfile.isProfileReady()).thenReturn(true); when(mPanProfile.isProfileReady()).thenReturn(true);
when(mPanProfile.getProfileId()).thenReturn(BluetoothProfile.PAN);
when(mHearingAidProfile.isProfileReady()).thenReturn(true); when(mHearingAidProfile.isProfileReady()).thenReturn(true);
when(mHearingAidProfile.getProfileId()).thenReturn(BluetoothProfile.HEARING_AID);
when(mLeAudioProfile.isProfileReady()).thenReturn(true);
when(mLeAudioProfile.getProfileId()).thenReturn(BluetoothProfile.LE_AUDIO);
mCachedDevice = spy(new CachedBluetoothDevice(mContext, mProfileManager, mDevice)); mCachedDevice = spy(new CachedBluetoothDevice(mContext, mProfileManager, mDevice));
mSubCachedDevice = spy(new CachedBluetoothDevice(mContext, mProfileManager, mSubDevice)); mSubCachedDevice = spy(new CachedBluetoothDevice(mContext, mProfileManager, mSubDevice));
doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel(); doAnswer((invocation) -> mBatteryLevel).when(mCachedDevice).getBatteryLevel();
doAnswer((invocation) -> mBatteryLevel).when(mSubCachedDevice).getBatteryLevel(); doAnswer((invocation) -> mBatteryLevel).when(mSubCachedDevice).getBatteryLevel();
} }
private void testTransitionFromConnectingToDisconnected(
LocalBluetoothProfile connectingProfile, LocalBluetoothProfile connectedProfile,
int connectionPolicy, String expectedSummary) {
// Arrange:
// At least one profile has to be connected
updateProfileStatus(connectedProfile, BluetoothProfile.STATE_CONNECTED);
// Set profile under test to CONNECTING
updateProfileStatus(connectingProfile, BluetoothProfile.STATE_CONNECTING);
// Set connection policy
when(connectingProfile.getConnectionPolicy(mDevice)).thenReturn(connectionPolicy);
// Act & Assert:
// Get the expected connection summary.
updateProfileStatus(connectingProfile, BluetoothProfile.STATE_DISCONNECTED);
assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(expectedSummary);
}
@Test
public void onProfileStateChanged_testConnectingToDisconnected_policyAllowed_problem() {
String connectTimeoutString = mContext.getString(R.string.profile_connect_timeout_subtext);
testTransitionFromConnectingToDisconnected(mA2dpProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_ALLOWED, connectTimeoutString);
testTransitionFromConnectingToDisconnected(mHearingAidProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_ALLOWED, connectTimeoutString);
testTransitionFromConnectingToDisconnected(mHfpProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_ALLOWED, connectTimeoutString);
testTransitionFromConnectingToDisconnected(mLeAudioProfile, mA2dpProfile,
BluetoothProfile.CONNECTION_POLICY_ALLOWED, connectTimeoutString);
}
@Test
public void onProfileStateChanged_testConnectingToDisconnected_policyForbidden_noProblem() {
testTransitionFromConnectingToDisconnected(mA2dpProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, null);
testTransitionFromConnectingToDisconnected(mHearingAidProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, null);
testTransitionFromConnectingToDisconnected(mHfpProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, null);
testTransitionFromConnectingToDisconnected(mLeAudioProfile, mA2dpProfile,
BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, null);
}
@Test
public void onProfileStateChanged_testConnectingToDisconnected_policyUnknown_noProblem() {
testTransitionFromConnectingToDisconnected(mA2dpProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_UNKNOWN, null);
testTransitionFromConnectingToDisconnected(mHearingAidProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_UNKNOWN, null);
testTransitionFromConnectingToDisconnected(mHfpProfile, mLeAudioProfile,
BluetoothProfile.CONNECTION_POLICY_UNKNOWN, null);
testTransitionFromConnectingToDisconnected(mLeAudioProfile, mA2dpProfile,
BluetoothProfile.CONNECTION_POLICY_UNKNOWN, null);
}
@Test @Test
public void getConnectionSummary_testProfilesInactive_returnPairing() { public void getConnectionSummary_testProfilesInactive_returnPairing() {
// Arrange: // Arrange: