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
This commit is contained in:
@@ -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>
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -22,11 +22,14 @@ import android.support.v14.preference.PreferenceFragment;
|
||||
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 @@ public class BluetoothDetailsHeaderController extends BluetoothDetailsController
|
||||
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 @@ public class BluetoothDetailsHeaderController extends BluetoothDetailsController
|
||||
.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);
|
||||
|
@@ -142,7 +142,7 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
||||
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,
|
||||
|
@@ -152,7 +152,12 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback {
|
||||
}
|
||||
|
||||
@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) {
|
||||
|
@@ -85,6 +85,8 @@ public class EntityHeaderController {
|
||||
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 @@ public class EntityHeaderController {
|
||||
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 @@ public class EntityHeaderController {
|
||||
}
|
||||
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));
|
||||
|
@@ -32,6 +32,9 @@ import com.android.settings.testutils.shadow.SettingsShadowBluetoothDevice;
|
||||
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 @@ public class BluetoothDetailsHeaderControllerTest extends BluetoothDetailsContro
|
||||
|
||||
@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 @@ public class BluetoothDetailsHeaderControllerTest extends BluetoothDetailsContro
|
||||
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);
|
||||
}
|
||||
|
||||
|
@@ -106,6 +106,16 @@ public class BluetoothDeviceUpdaterTest {
|
||||
assertThat(mBluetoothDeviceUpdater.mPreferenceMap.containsKey(mBluetoothDevice)).isFalse();
|
||||
}
|
||||
|
||||
@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);
|
||||
|
@@ -115,18 +115,22 @@ public class EntityHeaderControllerTest {
|
||||
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
|
||||
|
Reference in New Issue
Block a user