summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SettingsLib/res/values/strings.xml3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java86
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java15
3 files changed, 104 insertions, 0 deletions
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 66e89237ac6d..a1ef831523b1 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1186,4 +1186,7 @@
<!-- Name of the this device. [CHAR LIMIT=30] -->
<string name="media_transfer_this_device_name">This device</string>
+
+ <!-- Warning message to tell user is have problem during profile connect, it need to turn off device and back on. [CHAR_LIMIT=NONE] -->
+ <string name="profile_connect_timeout_subtext">Problem connecting. Turn device off &amp; back on</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 98db7c8fb59c..2507a3486f2b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -24,6 +24,9 @@ import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.ParcelUuid;
import android.os.SystemClock;
import android.text.TextUtils;
@@ -55,6 +58,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
// Some Hearing Aids (especially the 2nd device) needs more time to do service discovery
private static final long MAX_HEARING_AIDS_DELAY_FOR_AUTO_CONNECT = 15000;
private static final long MAX_HOGP_DELAY_FOR_AUTO_CONNECT = 30000;
+ private static final long MAX_MEDIA_PROFILE_CONNECT_DELAY = 60000;
private final Context mContext;
private final BluetoothAdapter mLocalAdapter;
@@ -90,9 +94,35 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
private boolean mIsActiveDeviceA2dp = false;
private boolean mIsActiveDeviceHeadset = false;
private boolean mIsActiveDeviceHearingAid = false;
+ // Media profile connect state
+ private boolean mIsA2dpProfileConnectedFail = false;
+ private boolean mIsHeadsetProfileConnectedFail = false;
+ private boolean mIsHearingAidProfileConnectedFail = false;
// Group second device for Hearing Aid
private CachedBluetoothDevice mSubDevice;
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case BluetoothProfile.A2DP:
+ mIsA2dpProfileConnectedFail = true;
+ break;
+ case BluetoothProfile.HEADSET:
+ mIsHeadsetProfileConnectedFail = true;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mIsHearingAidProfileConnectedFail = true;
+ break;
+ default:
+ Log.w(TAG, "handleMessage(): unknown message : " + msg.what);
+ break;
+ }
+ Log.w(TAG, "Connect to profile : " + msg.what + " timeout, show error message !");
+ refresh();
+ }
+ };
+
CachedBluetoothDevice(Context context, LocalBluetoothProfileManager profileManager,
BluetoothDevice device) {
mContext = context;
@@ -133,6 +163,35 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
synchronized (mProfileLock) {
+ if (profile instanceof A2dpProfile || profile instanceof HeadsetProfile
+ || profile instanceof HearingAidProfile) {
+ setProfileConnectedStatus(profile.getProfileId(), false);
+ switch (newProfileState) {
+ case BluetoothProfile.STATE_CONNECTED:
+ mHandler.removeMessages(profile.getProfileId());
+ break;
+ case BluetoothProfile.STATE_CONNECTING:
+ mHandler.sendEmptyMessageDelayed(profile.getProfileId(),
+ MAX_MEDIA_PROFILE_CONNECT_DELAY);
+ break;
+ case BluetoothProfile.STATE_DISCONNECTING:
+ if (mHandler.hasMessages(profile.getProfileId())) {
+ mHandler.removeMessages(profile.getProfileId());
+ }
+ break;
+ case BluetoothProfile.STATE_DISCONNECTED:
+ if (mHandler.hasMessages(profile.getProfileId())) {
+ mHandler.removeMessages(profile.getProfileId());
+ setProfileConnectedStatus(profile.getProfileId(), true);
+ }
+ break;
+ default:
+ Log.w(TAG, "onProfileStateChanged(): unknown profile state : "
+ + newProfileState);
+ break;
+ }
+ }
+
if (newProfileState == BluetoothProfile.STATE_CONNECTED) {
if (profile instanceof MapProfile) {
profile.setPreferred(mDevice, true);
@@ -162,6 +221,24 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
fetchActiveDevices();
}
+ @VisibleForTesting
+ void setProfileConnectedStatus(int profileId, boolean isFailed) {
+ switch (profileId) {
+ case BluetoothProfile.A2DP:
+ mIsA2dpProfileConnectedFail = isFailed;
+ break;
+ case BluetoothProfile.HEADSET:
+ mIsHeadsetProfileConnectedFail = isFailed;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mIsHearingAidProfileConnectedFail = isFailed;
+ break;
+ default:
+ Log.w(TAG, "setProfileConnectedStatus(): unknown profile id : " + profileId);
+ break;
+ }
+ }
+
public void disconnect() {
synchronized (mProfileLock) {
for (LocalBluetoothProfile profile : mProfiles) {
@@ -844,6 +921,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
int leftBattery = -1;
int rightBattery = -1;
+ if (isProfileConnectedFail() && isConnected()) {
+ return mContext.getString(R.string.profile_connect_timeout_subtext);
+ }
+
synchronized (mProfileLock) {
for (LocalBluetoothProfile profile : getProfiles()) {
int connectionStatus = getProfileConnectionState(profile);
@@ -943,6 +1024,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
return leftBattery >= 0 && rightBattery >= 0;
}
+ private boolean isProfileConnectedFail() {
+ return mIsA2dpProfileConnectedFail || mIsHearingAidProfileConnectedFail
+ || mIsHeadsetProfileConnectedFail;
+ }
+
/**
* @return resource for android auto string that describes the connection state of this device.
*/
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 93dcbfeab172..5c89a019bf82 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -31,6 +32,8 @@ import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioManager;
+import com.android.settingslib.R;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -922,4 +925,16 @@ public class CachedBluetoothDeviceTest {
assertThat(subCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_1);
assertThat(subCachedDevice.mDevice).isEqualTo(mDevice);
}
+
+ @Test
+ public void getConnectionSummary_profileConnectedFail_showErrorMessage() {
+ final A2dpProfile profle = mock(A2dpProfile.class);
+ mCachedDevice.onProfileStateChanged(profle, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.setProfileConnectedStatus(BluetoothProfile.A2DP, true);
+
+ when(profle.getConnectionStatus(mDevice)).thenReturn(BluetoothProfile.STATE_CONNECTED);
+
+ assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
+ mContext.getString(R.string.profile_connect_timeout_subtext));
+ }
}