Fix BluetoothDevicesSlice doesn't appear issue.

In Settings cold launch, it took a little bit time to do Bluetooth
profile service connection. If we get the Bluetooth device connected
state before service connected, the return value will always false.
This behavior caused BluetoothDevicesSlice can't collect media devices
immediately in cold launch, therefore, no data to build this card.

According latest discussion, this card is used for all Bluetooth
devices, so we don't need to wait profile to get specific devices.
Hence, update design to show all connected Bluetooth devices and
keep the operations are the same with Settings > Connected devices.

Fixes: 124462139
Test: visual, robotests
Change-Id: I1418e09f2cdc7ea8beaa73d7a59440ee2baae63b
This commit is contained in:
Yanting Yang
2019-02-26 21:33:27 +08:00
parent 4b01c8468c
commit cbbc008a97
2 changed files with 44 additions and 16 deletions

View File

@@ -179,14 +179,9 @@ public class BluetoothDevicesSlice implements CustomSliceable {
final Collection<CachedBluetoothDevice> cachedDevices = final Collection<CachedBluetoothDevice> cachedDevices =
bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy(); bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy();
/** // Get all connected devices and sort them.
* TODO(b/114807655): Contextual Home Page - Connected Device
* It's under discussion for including available media devices and currently connected
* devices from Bluetooth. Will update the devices list or remove TODO later.
*/
// Get available media device list and sort them.
return cachedDevices.stream() return cachedDevices.stream()
.filter(device -> device.isConnected() && device.isConnectedA2dpDevice()) .filter(device -> device.getDevice().isConnected())
.sorted(COMPARATOR).collect(Collectors.toList()); .sorted(COMPARATOR).collect(Collectors.toList());
} }
@@ -217,7 +212,7 @@ public class BluetoothDevicesSlice implements CustomSliceable {
return Utils.createIconWithDrawable(pair.first); return Utils.createIconWithDrawable(pair.first);
} else { } else {
return IconCompat.createWithResource(mContext, return IconCompat.createWithResource(mContext,
com.android.internal.R.drawable.ic_settings_bluetooth); com.android.internal.R.drawable.ic_settings_bluetooth);
} }
} }
@@ -226,18 +221,29 @@ public class BluetoothDevicesSlice implements CustomSliceable {
final List<ListBuilder.RowBuilder> bluetoothRows = new ArrayList<>(); final List<ListBuilder.RowBuilder> bluetoothRows = new ArrayList<>();
final List<CachedBluetoothDevice> bluetoothDevices = getConnectedBluetoothDevices(); final List<CachedBluetoothDevice> bluetoothDevices = getConnectedBluetoothDevices();
for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) { for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) {
bluetoothRows.add(new ListBuilder.RowBuilder() final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder()
.setTitleItem(getBluetoothDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE) .setTitleItem(getBluetoothDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE)
.setTitle(bluetoothDevice.getName()) .setTitle(bluetoothDevice.getName())
.setSubtitle(bluetoothDevice.getConnectionSummary()) .setSubtitle(bluetoothDevice.getConnectionSummary());
.setPrimaryAction(buildBluetoothDeviceAction(bluetoothDevice))
.addEndItem(buildBluetoothDetailDeepLinkAction(bluetoothDevice))); if (bluetoothDevice.isConnectedA2dpDevice()) {
// For available media devices, the primary action is to active audio stream and
// add setting icon to the end to link detail page.
rowBuilder.setPrimaryAction(buildMediaBluetoothAction(bluetoothDevice));
rowBuilder.addEndItem(buildBluetoothDetailDeepLinkAction(bluetoothDevice));
} else {
// For other devices, the primary action is to link detail page.
rowBuilder.setPrimaryAction(buildBluetoothDetailDeepLinkAction(bluetoothDevice));
}
bluetoothRows.add(rowBuilder);
} }
return bluetoothRows; return bluetoothRows;
} }
private SliceAction buildBluetoothDeviceAction(CachedBluetoothDevice bluetoothDevice) { @VisibleForTesting
SliceAction buildMediaBluetoothAction(CachedBluetoothDevice bluetoothDevice) {
// Send broadcast to activate available media device. // Send broadcast to activate available media device.
final Intent intent = new Intent(getUri().toString()) final Intent intent = new Intent(getUri().toString())
.setClass(mContext, SliceBroadcastReceiver.class) .setClass(mContext, SliceBroadcastReceiver.class)
@@ -250,7 +256,8 @@ public class BluetoothDevicesSlice implements CustomSliceable {
bluetoothDevice.getName()); bluetoothDevice.getName());
} }
private SliceAction buildBluetoothDetailDeepLinkAction(CachedBluetoothDevice bluetoothDevice) { @VisibleForTesting
SliceAction buildBluetoothDetailDeepLinkAction(CachedBluetoothDevice bluetoothDevice) {
return SliceAction.createDeeplink( return SliceAction.createDeeplink(
getBluetoothDetailIntent(bluetoothDevice), getBluetoothDetailIntent(bluetoothDevice),
IconCompat.createWithResource(mContext, R.drawable.ic_settings_24dp), IconCompat.createWithResource(mContext, R.drawable.ic_settings_24dp),

View File

@@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -83,7 +84,7 @@ public class BluetoothDevicesSliceTest {
// Mock the icon and detail intent of Bluetooth. // Mock the icon and detail intent of Bluetooth.
mIcon = IconCompat.createWithResource(mContext, mIcon = IconCompat.createWithResource(mContext,
com.android.internal.R.drawable.ic_settings_bluetooth); com.android.internal.R.drawable.ic_settings_bluetooth);
mDetailIntent = PendingIntent.getActivity(mContext, 0, new Intent("test action"), 0); mDetailIntent = PendingIntent.getActivity(mContext, 0, new Intent("test action"), 0);
doReturn(mIcon).when(mBluetoothDevicesSlice).getBluetoothDeviceIcon(any()); doReturn(mIcon).when(mBluetoothDevicesSlice).getBluetoothDeviceIcon(any());
doReturn(mDetailIntent).when(mBluetoothDevicesSlice).getBluetoothDetailIntent(any()); doReturn(mDetailIntent).when(mBluetoothDevicesSlice).getBluetoothDetailIntent(any());
@@ -121,6 +122,27 @@ public class BluetoothDevicesSliceTest {
SliceTester.assertAnySliceItemContainsTitle(sliceItems, BLUETOOTH_MOCK_TITLE); SliceTester.assertAnySliceItemContainsTitle(sliceItems, BLUETOOTH_MOCK_TITLE);
} }
@Test
public void getSlice_hasMediaBluetoothDevice_shouldBuildMediaBluetoothAction() {
mockBluetoothDeviceList(1 /* deviceCount */);
doReturn(true).when(mBluetoothDeviceList.get(0)).isConnectedA2dpDevice();
doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices();
mBluetoothDevicesSlice.getSlice();
verify(mBluetoothDevicesSlice).buildMediaBluetoothAction(any());
}
@Test
public void getSlice_noMediaBluetoothDevice_shouldNotBuildMediaBluetoothAction() {
mockBluetoothDeviceList(1 /* deviceCount */);
doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices();
mBluetoothDevicesSlice.getSlice();
verify(mBluetoothDevicesSlice, never()).buildMediaBluetoothAction(any());
}
@Test @Test
public void getSlice_noBluetoothDevices_shouldHaveNoBluetoothDevicesTitle() { public void getSlice_noBluetoothDevices_shouldHaveNoBluetoothDevicesTitle() {
doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices();
@@ -175,7 +197,6 @@ public class BluetoothDevicesSliceTest {
doReturn(BLUETOOTH_MOCK_TITLE).when(mCachedBluetoothDevice).getName(); doReturn(BLUETOOTH_MOCK_TITLE).when(mCachedBluetoothDevice).getName();
doReturn(BLUETOOTH_MOCK_SUMMARY).when(mCachedBluetoothDevice).getConnectionSummary(); doReturn(BLUETOOTH_MOCK_SUMMARY).when(mCachedBluetoothDevice).getConnectionSummary();
doReturn(BLUETOOTH_MOCK_ADDRESS).when(mCachedBluetoothDevice).getAddress(); doReturn(BLUETOOTH_MOCK_ADDRESS).when(mCachedBluetoothDevice).getAddress();
doReturn(true).when(mCachedBluetoothDevice).isConnectedA2dpDevice();
for (int i = 0; i < deviceCount; i++) { for (int i = 0; i < deviceCount; i++) {
mBluetoothDeviceList.add(mCachedBluetoothDevice); mBluetoothDeviceList.add(mCachedBluetoothDevice);
} }