Show only 1 entry for hearing aid devices without killing the activity.
This CL tries to detect Bluetooth hearing aid devices and tries to
combine the entry of the hearing aids with the same HiSyncIds and
show only 1 entry for each pair in the connected devices list.
This CL also shows 2 battery status in the device details page.
This change shows the combined entry after a user returns to the
settings activity after pressing the back button or somehow
without killing it. It also combines the entries just after pairing.
Test: RunSettingsRoboTests
Bug: 74204427
Change-Id: I47fb0bdd96b1cc972d88a4aef85d0113985d63bb
diff --git a/res/layout-sw320dp/settings_entity_header.xml b/res/layout-sw320dp/settings_entity_header.xml
index 481a9c4..79e12a9 100644
--- a/res/layout-sw320dp/settings_entity_header.xml
+++ b/res/layout-sw320dp/settings_entity_header.xml
@@ -81,6 +81,17 @@
android:textAppearance="@android:style/TextAppearance.Material.Body1"
android:textColor="?android:attr/textColorSecondary" />
+ <TextView
+ android:id="@+id/entity_header_second_summary"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="start"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAlignment="viewStart"
+ android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textColor="?android:attr/textColorSecondary" />
+
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/settings_entity_header.xml b/res/layout/settings_entity_header.xml
index 2660ef0..b534c5e 100644
--- a/res/layout/settings_entity_header.xml
+++ b/res/layout/settings_entity_header.xml
@@ -75,6 +75,17 @@
android:textAppearance="@android:style/TextAppearance.Material.Body1"
android:textColor="?android:attr/textColorSecondary" />
+ <TextView
+ android:id="@+id/entity_header_second_summary"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="start"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAlignment="viewStart"
+ android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textColor="?android:attr/textColorSecondary" />
+
</LinearLayout>
<LinearLayout
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
index df7b601..8679b55 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
@@ -22,11 +22,14 @@
import android.support.v7.preference.PreferenceScreen;
import android.util.Pair;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
/**
* This class adds a header with device name and status (connected/disconnected, etc.).
@@ -35,10 +38,15 @@
private static final String KEY_DEVICE_HEADER = "bluetooth_device_header";
private EntityHeaderController mHeaderController;
+ private LocalBluetoothManager mLocalManager;
+ private CachedBluetoothDeviceManager mDeviceManager;
public BluetoothDetailsHeaderController(Context context, PreferenceFragment fragment,
- CachedBluetoothDevice device, Lifecycle lifecycle) {
+ CachedBluetoothDevice device, Lifecycle lifecycle,
+ LocalBluetoothManager bluetoothManager) {
super(context, fragment, device, lifecycle);
+ mLocalManager = bluetoothManager;
+ mDeviceManager = mLocalManager.getCachedDeviceManager();
}
@Override
@@ -55,6 +63,12 @@
.getBtClassDrawableWithDescription(mContext, mCachedDevice,
mContext.getResources().getFraction(R.fraction.bt_battery_scale_fraction, 1, 1));
String summaryText = mCachedDevice.getConnectionSummary();
+ // If both the hearing aids are connected, two battery status should be shown.
+ final String pairDeviceSummary = mDeviceManager
+ .getHearingAidPairDeviceSummary(mCachedDevice);
+ if (pairDeviceSummary != null) {
+ mHeaderController.setSecondSummary(pairDeviceSummary);
+ }
mHeaderController.setLabel(mCachedDevice.getName());
mHeaderController.setIcon(pair.first);
mHeaderController.setIconContentDescription(pair.second);
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
index b9cfa00..1e82889 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragment.java
@@ -142,7 +142,7 @@
if (mCachedDevice != null) {
Lifecycle lifecycle = getLifecycle();
controllers.add(new BluetoothDetailsHeaderController(context, this, mCachedDevice,
- lifecycle));
+ lifecycle, mManager));
controllers.add(new BluetoothDetailsButtonsController(context, this, mCachedDevice,
lifecycle));
controllers.add(new BluetoothDetailsProfilesController(context, this, mManager,
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
index 67cf299..f71d27a 100644
--- a/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java
@@ -152,7 +152,12 @@
}
@Override
- public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {}
+ public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
+ // Used to combine the hearing aid entries just after pairing. Once both the hearing aids
+ // get connected and their hiSyncId gets populated, this gets called for one of the
+ // 2 hearing aids so that only one entry in the connected devices list will be seen.
+ removePreference(cachedDevice);
+ }
@Override
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
diff --git a/src/com/android/settings/widget/EntityHeaderController.java b/src/com/android/settings/widget/EntityHeaderController.java
index 4ebc369..5131159 100644
--- a/src/com/android/settings/widget/EntityHeaderController.java
+++ b/src/com/android/settings/widget/EntityHeaderController.java
@@ -85,6 +85,8 @@
private String mIconContentDescription;
private CharSequence mLabel;
private CharSequence mSummary;
+ // Required for hearing aid devices.
+ private CharSequence mSecondSummary;
private String mPackageName;
private Intent mAppNotifPrefIntent;
@UserIdInt
@@ -181,6 +183,18 @@
return this;
}
+ public EntityHeaderController setSecondSummary(CharSequence summary) {
+ mSecondSummary = summary;
+ return this;
+ }
+
+ public EntityHeaderController setSecondSummary(PackageInfo packageInfo) {
+ if (packageInfo != null) {
+ mSummary = packageInfo.versionName;
+ }
+ return this;
+ }
+
public EntityHeaderController setHasAppInfoLink(boolean hasAppInfoLink) {
mHasAppInfoLink = hasAppInfoLink;
return this;
@@ -242,6 +256,7 @@
}
setText(R.id.entity_header_title, mLabel);
setText(R.id.entity_header_summary, mSummary);
+ setText(R.id.entity_header_second_summary, mSecondSummary);
if (mIsInstantApp) {
setText(R.id.install_type,
mHeader.getResources().getString(R.string.install_type_instant));
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
index 39ec535..2567f53 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsHeaderControllerTest.java
@@ -32,6 +32,9 @@
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -50,14 +53,21 @@
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private EntityHeaderController mHeaderController;
+ @Mock
+ private LocalBluetoothManager mBluetoothManager;
+ @Mock
+ private CachedBluetoothDeviceManager mCachedDeviceManager;
@Override
public void setUp() {
super.setUp();
FakeFeatureFactory.setupForTest();
ShadowEntityHeaderController.setUseMock(mHeaderController);
+ when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
+ when(mCachedDeviceManager.getHearingAidPairDeviceSummary(mCachedDevice)).thenReturn("abc");
mController =
- new BluetoothDetailsHeaderController(mContext, mFragment, mCachedDevice, mLifecycle);
+ new BluetoothDetailsHeaderController(mContext, mFragment, mCachedDevice, mLifecycle,
+ mBluetoothManager);
mPreference = new LayoutPreference(mContext, R.layout.settings_entity_header);
mPreference.setKey(mController.getPreferenceKey());
mScreen.addPreference(mPreference);
@@ -86,6 +96,7 @@
verify(mHeaderController).setIcon(any(Drawable.class));
verify(mHeaderController).setIconContentDescription(any(String.class));
verify(mHeaderController).setSummary(any(String.class));
+ verify(mHeaderController).setSecondSummary(any(String.class));
verify(mHeaderController).done(mActivity, true);
}
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java
index 5334833..905924d 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java
@@ -107,6 +107,16 @@
}
@Test
+ public void testOnDeviceDeleted_deviceExists_removePreference() {
+ mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference);
+
+ mBluetoothDeviceUpdater.onDeviceDeleted(mCachedBluetoothDevice);
+
+ verify(mDevicePreferenceCallback).onDeviceRemoved(mPreference);
+ assertThat(mBluetoothDeviceUpdater.mPreferenceMap.containsKey(mBluetoothDevice)).isFalse();
+ }
+
+ @Test
public void testRemovePreference_deviceNotExist_doNothing() {
mBluetoothDeviceUpdater.removePreference(mCachedBluetoothDevice);
diff --git a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
index 0d294d5..e32ef77 100644
--- a/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/EntityHeaderControllerTest.java
@@ -115,18 +115,22 @@
final View header =
mLayoutInflater.inflate(R.layout.settings_entity_header, null /* root */);
final TextView label = header.findViewById(R.id.entity_header_title);
- final TextView version = header.findViewById(R.id.entity_header_summary);
+ final TextView summary = header.findViewById(R.id.entity_header_summary);
+ final TextView secondSummary = header.findViewById(R.id.entity_header_second_summary);
mController = EntityHeaderController.newInstance(mActivity, mFragment, header);
mController.setLabel(testString);
mController.setSummary(testString);
+ mController.setSecondSummary(testString);
mController.setIcon(mShadowContext.getDrawable(R.drawable.ic_add));
mController.done(mActivity);
assertThat(label).isNotNull();
assertThat(label.getText()).isEqualTo(testString);
- assertThat(version).isNotNull();
- assertThat(version.getText()).isEqualTo(testString);
+ assertThat(summary).isNotNull();
+ assertThat(summary.getText()).isEqualTo(testString);
+ assertThat(secondSummary).isNotNull();
+ assertThat(secondSummary.getText()).isEqualTo(testString);
}
@Test