From cbbc008a979d6cb316425ccf62c0775117c75361 Mon Sep 17 00:00:00 2001 From: Yanting Yang Date: Tue, 26 Feb 2019 21:33:27 +0800 Subject: [PATCH] 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 --- .../slices/BluetoothDevicesSlice.java | 35 +++++++++++-------- .../slices/BluetoothDevicesSliceTest.java | 25 +++++++++++-- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java index 95412a8b44e..3320be0a4f1 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java @@ -179,14 +179,9 @@ public class BluetoothDevicesSlice implements CustomSliceable { final Collection cachedDevices = bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy(); - /** - * 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. + // Get all connected devices and sort them. return cachedDevices.stream() - .filter(device -> device.isConnected() && device.isConnectedA2dpDevice()) + .filter(device -> device.getDevice().isConnected()) .sorted(COMPARATOR).collect(Collectors.toList()); } @@ -217,7 +212,7 @@ public class BluetoothDevicesSlice implements CustomSliceable { return Utils.createIconWithDrawable(pair.first); } else { 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 bluetoothRows = new ArrayList<>(); final List bluetoothDevices = getConnectedBluetoothDevices(); for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) { - bluetoothRows.add(new ListBuilder.RowBuilder() + final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() .setTitleItem(getBluetoothDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE) .setTitle(bluetoothDevice.getName()) - .setSubtitle(bluetoothDevice.getConnectionSummary()) - .setPrimaryAction(buildBluetoothDeviceAction(bluetoothDevice)) - .addEndItem(buildBluetoothDetailDeepLinkAction(bluetoothDevice))); + .setSubtitle(bluetoothDevice.getConnectionSummary()); + + 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; } - private SliceAction buildBluetoothDeviceAction(CachedBluetoothDevice bluetoothDevice) { + @VisibleForTesting + SliceAction buildMediaBluetoothAction(CachedBluetoothDevice bluetoothDevice) { // Send broadcast to activate available media device. final Intent intent = new Intent(getUri().toString()) .setClass(mContext, SliceBroadcastReceiver.class) @@ -250,7 +256,8 @@ public class BluetoothDevicesSlice implements CustomSliceable { bluetoothDevice.getName()); } - private SliceAction buildBluetoothDetailDeepLinkAction(CachedBluetoothDevice bluetoothDevice) { + @VisibleForTesting + SliceAction buildBluetoothDetailDeepLinkAction(CachedBluetoothDevice bluetoothDevice) { return SliceAction.createDeeplink( getBluetoothDetailIntent(bluetoothDevice), IconCompat.createWithResource(mContext, R.drawable.ic_settings_24dp), diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java index 77fc5d94eee..4a23c339c4a 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java @@ -23,6 +23,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -83,7 +84,7 @@ public class BluetoothDevicesSliceTest { // Mock the icon and detail intent of Bluetooth. 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); doReturn(mIcon).when(mBluetoothDevicesSlice).getBluetoothDeviceIcon(any()); doReturn(mDetailIntent).when(mBluetoothDevicesSlice).getBluetoothDetailIntent(any()); @@ -121,6 +122,27 @@ public class BluetoothDevicesSliceTest { 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 public void getSlice_noBluetoothDevices_shouldHaveNoBluetoothDevicesTitle() { doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); @@ -175,7 +197,6 @@ public class BluetoothDevicesSliceTest { doReturn(BLUETOOTH_MOCK_TITLE).when(mCachedBluetoothDevice).getName(); doReturn(BLUETOOTH_MOCK_SUMMARY).when(mCachedBluetoothDevice).getConnectionSummary(); doReturn(BLUETOOTH_MOCK_ADDRESS).when(mCachedBluetoothDevice).getAddress(); - doReturn(true).when(mCachedBluetoothDevice).isConnectedA2dpDevice(); for (int i = 0; i < deviceCount; i++) { mBluetoothDeviceList.add(mCachedBluetoothDevice); }