diff --git a/res/values/strings.xml b/res/values/strings.xml index d8c0d377b1e..0b79470e2bd 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10245,15 +10245,13 @@ Scan again - - + + %1$d device connected %1$d devices connected - - Bluetooth Devices - - No connected devices + + No Bluetooth devices Settings Panel diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java index 6373519c770..e631d22e216 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java @@ -20,7 +20,7 @@ import static android.app.slice.Slice.HINT_ERROR; import static androidx.slice.widget.SliceLiveData.SUPPORTED_SPECS; -import static com.android.settings.slices.CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI; +import static com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI; import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; import android.content.ContentProviderClient; @@ -196,7 +196,7 @@ public class ContextualCardLoader extends AsyncLoaderCompat private int getNumberOfLargeCard(List cards) { return (int) cards.stream() .filter(card -> card.getSliceUri().equals(WIFI_SLICE_URI) - || card.getSliceUri().equals(CONNECTED_DEVICE_SLICE_URI)) + || card.getSliceUri().equals(BLUETOOTH_DEVICES_SLICE_URI)) .count(); } diff --git a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java index 376bb83606a..d5500fb37e3 100644 --- a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java +++ b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java @@ -40,8 +40,8 @@ public class SettingsContextualCardProvider extends ContextualCardProvider { .build(); final ContextualCard connectedDeviceCard = ContextualCard.newBuilder() - .setSliceUri(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI.toString()) - .setCardName(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI.toString()) + .setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()) + .setCardName(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()) .setCardCategory(ContextualCard.Category.IMPORTANT) .build(); final ContextualCard lowStorageCard = diff --git a/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java similarity index 82% rename from src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java rename to src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java index b5d58b6176c..ad8d4a644aa 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java @@ -57,19 +57,12 @@ import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; -/** - * TODO(b/114807655): Contextual Home Page - Connected Device - * - * Show connected device info if one is currently connected. UI for connected device should - * match Connected Devices > Currently Connected Devices - * - * TODO This class will be refactor for Bluetooth connected devices only. - */ -public class ConnectedDeviceSlice implements CustomSliceable { +public class BluetoothDevicesSlice implements CustomSliceable { /** - * To sort the Bluetooth devices by {@link CachedBluetoothDevice}. - * Refer compareTo method from {@link com.android.settings.bluetooth.BluetoothDevicePreference}. + * TODO(b/114807655): Contextual Home Page - Connected Device + * Re-design sorting for new rule: + * Sorting rule: Audio Streaming > Last connected > Recently connected. */ private static final Comparator COMPARATOR = Comparator.naturalOrder(); @@ -80,11 +73,11 @@ public class ConnectedDeviceSlice implements CustomSliceable { */ private static final int DEFAULT_EXPANDED_ROW_COUNT = 3; - private static final String TAG = "ConnectedDeviceSlice"; + private static final String TAG = "BluetoothDevicesSlice"; private final Context mContext; - public ConnectedDeviceSlice(Context context) { + public BluetoothDevicesSlice(Context context) { mContext = context; } @@ -101,38 +94,38 @@ public class ConnectedDeviceSlice implements CustomSliceable { @Override public Uri getUri() { - return CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI; + return CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI; } @Override public Slice getSlice() { final IconCompat icon = IconCompat.createWithResource(mContext, - R.drawable.ic_homepage_connected_device); - final CharSequence title = mContext.getText(R.string.bluetooth_connected_devices); - final CharSequence titleNoConnectedDevices = mContext.getText( - R.string.no_connected_devices); + R.drawable.ic_settings_bluetooth); + final CharSequence title = mContext.getText(R.string.bluetooth_devices); + final CharSequence titleNoBluetoothDevices = mContext.getText( + R.string.no_bluetooth_devices); final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext, 0, getIntent(), 0); final SliceAction primarySliceAction = SliceAction.createDeeplink(primaryActionIntent, icon, ListBuilder.ICON_IMAGE, title); final ListBuilder listBuilder = - new ListBuilder(mContext, CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI, + new ListBuilder(mContext, CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI, ListBuilder.INFINITY) .setAccentColor(Utils.getColorAccentDefaultColor(mContext)); - // Get row builders by connected devices, e.g. Bluetooth. + // Get row builders by Bluetooth devices. final List rows = getBluetoothRowBuilder(primarySliceAction); - // Return a header with IsError flag, if no connected devices. + // Return a header with IsError flag, if no Bluetooth devices. if (rows.isEmpty()) { return listBuilder.setHeader(new ListBuilder.HeaderBuilder() - .setTitle(titleNoConnectedDevices) + .setTitle(titleNoBluetoothDevices) .setPrimaryAction(primarySliceAction)) .setIsError(true) .build(); } - // According the number of connected devices to set sub title of header. + // According the number of Bluetooth devices to set sub title of header. listBuilder.setHeader(new ListBuilder.HeaderBuilder() .setTitle(title) .setSubtitle(getSubTitle(rows.size())) @@ -161,7 +154,7 @@ public class ConnectedDeviceSlice implements CustomSliceable { screenTitle, MetricsProto.MetricsEvent.SLICE) .setClassName(mContext.getPackageName(), SubSettings.class.getName()) - .setData(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI); + .setData(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI); } @Override @@ -174,25 +167,30 @@ public class ConnectedDeviceSlice implements CustomSliceable { } @VisibleForTesting - List getBluetoothConnectedDevices() { - final List connectedBluetoothList = new ArrayList<>(); + List getBluetoothDevices() { + final List bluetoothDeviceList = new ArrayList<>(); // If Bluetooth is disable, skip to get the bluetooth devices. if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) { - Log.i(TAG, "Cannot get Bluetooth connected devices, Bluetooth is disabled."); - return connectedBluetoothList; + Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is disabled."); + return bluetoothDeviceList; } // Get the Bluetooth devices from LocalBluetoothManager. final LocalBluetoothManager bluetoothManager = com.android.settings.bluetooth.Utils.getLocalBtManager(mContext); if (bluetoothManager == null) { - Log.i(TAG, "Cannot get Bluetooth connected devices, Bluetooth is unsupported."); - return connectedBluetoothList; + Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is unsupported."); + return bluetoothDeviceList; } final Collection cachedDevices = bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy(); + /** + * TODO(b/114807655): Contextual Home Page - Connected Device + * Re-design to get all Bluetooth devices and sort them by new rule: + * Sorting rule: Audio Streaming > Last connected > Recently connected. + */ // Get connected Bluetooth devices and sort them. return cachedDevices.stream().filter(device -> device.isConnected()).sorted( COMPARATOR).collect(Collectors.toList()); @@ -217,25 +215,29 @@ public class ConnectedDeviceSlice implements CustomSliceable { } @VisibleForTesting - IconCompat getConnectedDeviceIcon(CachedBluetoothDevice device) { + IconCompat getBluetoothDeviceIcon(CachedBluetoothDevice device) { final Pair pair = BluetoothUtils .getBtClassDrawableWithDescription(mContext, device); if (pair.first != null) { return IconCompat.createWithBitmap(getBitmapFromVectorDrawable(pair.first)); } else { - return IconCompat.createWithResource(mContext, R.drawable.ic_homepage_connected_device); + return IconCompat.createWithResource(mContext, R.drawable.ic_settings_bluetooth); } } private List getBluetoothRowBuilder(SliceAction primarySliceAction) { final List bluetoothRows = new ArrayList<>(); - // According Bluetooth connected device to create row builders. - final List bluetoothDevices = getBluetoothConnectedDevices(); + /** + * TODO(b/114807655): Contextual Home Page - Connected Device + * Re-design to do action "activating" in primary action. + */ + // According Bluetooth device to create row builders. + final List bluetoothDevices = getBluetoothDevices(); for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) { bluetoothRows.add(new ListBuilder.RowBuilder() - .setTitleItem(getConnectedDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE) + .setTitleItem(getBluetoothDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE) .setTitle(bluetoothDevice.getName()) .setSubtitle(bluetoothDevice.getConnectionSummary()) .setPrimaryAction(primarySliceAction) @@ -254,7 +256,7 @@ public class ConnectedDeviceSlice implements CustomSliceable { } private CharSequence getSubTitle(int deviceCount) { - return mContext.getResources().getQuantityString(R.plurals.show_connected_devices, + return mContext.getResources().getQuantityString(R.plurals.show_bluetooth_devices, deviceCount, deviceCount); } diff --git a/src/com/android/settings/slices/CustomSliceManager.java b/src/com/android/settings/slices/CustomSliceManager.java index 8f8ee967fc4..4a9de15d841 100644 --- a/src/com/android/settings/slices/CustomSliceManager.java +++ b/src/com/android/settings/slices/CustomSliceManager.java @@ -29,7 +29,7 @@ import com.android.settings.homepage.contextualcards.deviceinfo.DeviceInfoSlice; import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice; import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice; import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice; -import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice; +import com.android.settings.homepage.contextualcards.slices.BluetoothDevicesSlice; import com.android.settings.homepage.contextualcards.slices.LowStorageSlice; import com.android.settings.location.LocationSlice; import com.android.settings.wifi.WifiSlice; @@ -106,7 +106,7 @@ public class CustomSliceManager { private void addSlices() { mUriMap.put(CustomSliceRegistry.BATTERY_FIX_SLICE_URI, BatteryFixSlice.class); mUriMap.put(CustomSliceRegistry.BATTERY_INFO_SLICE_URI, BatterySlice.class); - mUriMap.put(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI, ConnectedDeviceSlice.class); + mUriMap.put(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI, BluetoothDevicesSlice.class); mUriMap.put(CustomSliceRegistry.DATA_USAGE_SLICE_URI, DataUsageSlice.class); mUriMap.put(CustomSliceRegistry.DEVICE_INFO_SLICE_URI, DeviceInfoSlice.class); mUriMap.put(CustomSliceRegistry.EMERGENCY_INFO_SLICE_URI, EmergencyInfoSlice.class); diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java index 80de3b2b9eb..1b8cffef509 100644 --- a/src/com/android/settings/slices/CustomSliceRegistry.java +++ b/src/com/android/settings/slices/CustomSliceRegistry.java @@ -72,13 +72,13 @@ public class CustomSliceRegistry { .build(); /** - * Backing Uri for Connected device Slice. + * Backing Uri for Bluetooth devices Slice. */ - public static final Uri CONNECTED_DEVICE_SLICE_URI = new Uri.Builder() + public static final Uri BLUETOOTH_DEVICES_SLICE_URI = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority(SettingsSliceProvider.SLICE_AUTHORITY) .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) - .appendPath("connected_device") + .appendPath("bluetooth_devices") .build(); /** * Backing Uri for the Data usage Slice. diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java index 4f501970416..98943a0e07c 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLoaderTest.java @@ -162,7 +162,7 @@ public class ContextualCardLoaderTest { cards.add(new ContextualCard.Builder() .setName("test_connected") .setCardType(ContextualCard.CardType.SLICE) - .setSliceUri(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI) + .setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI) .build()); cards.add(new ContextualCard.Builder() .setName("test_gesture") diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java similarity index 64% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSliceTest.java rename to tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java index 14a2c477668..ac6557e67d8 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSliceTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java @@ -52,7 +52,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) -public class ConnectedDeviceSliceTest { +public class BluetoothDevicesSliceTest { private static final String BLUETOOTH_MOCK_SUMMARY = "BluetoothSummary"; private static final String BLUETOOTH_MOCK_TITLE = "BluetoothTitle"; @@ -60,8 +60,8 @@ public class ConnectedDeviceSliceTest { @Mock private CachedBluetoothDevice mCachedBluetoothDevice; - private List mBluetoothConnectedDeviceList; - private ConnectedDeviceSlice mConnectedDeviceSlice; + private List mBluetoothDeviceList; + private BluetoothDevicesSlice mBluetoothDevicesSlice; private Context mContext; private IconCompat mIcon; private PendingIntent mDetailIntent; @@ -74,57 +74,53 @@ public class ConnectedDeviceSliceTest { // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); - mConnectedDeviceSlice = spy(new ConnectedDeviceSlice(mContext)); + mBluetoothDevicesSlice = spy(new BluetoothDevicesSlice(mContext)); // Mock the icon and detail intent of Bluetooth. - mIcon = IconCompat.createWithResource(mContext, R.drawable.ic_homepage_connected_device); + mIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_bluetooth); mDetailIntent = PendingIntent.getActivity(mContext, 0, new Intent("test action"), 0); - doReturn(mIcon).when(mConnectedDeviceSlice).getConnectedDeviceIcon(any()); - doReturn(mDetailIntent).when(mConnectedDeviceSlice).getBluetoothDetailIntent(any()); + doReturn(mIcon).when(mBluetoothDevicesSlice).getBluetoothDeviceIcon(any()); + doReturn(mDetailIntent).when(mBluetoothDevicesSlice).getBluetoothDetailIntent(any()); - // Initial Bluetooth connected device list. - mBluetoothConnectedDeviceList = new ArrayList<>(); + // Initial Bluetooth device list. + mBluetoothDeviceList = new ArrayList<>(); } @After public void tearDown() { - if (!mBluetoothConnectedDeviceList.isEmpty()) { - mBluetoothConnectedDeviceList.clear(); + if (!mBluetoothDeviceList.isEmpty()) { + mBluetoothDeviceList.clear(); } } @Test - public void getSlice_hasConnectedDevices_shouldHaveConnectedDeviceTitle() { + public void getSlice_hasBluetoothDevices_shouldHaveBluetoothDevicesTitle() { mockBluetoothDeviceList(); - doReturn(mBluetoothConnectedDeviceList).when( - mConnectedDeviceSlice).getBluetoothConnectedDevices(); + doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getBluetoothDevices(); - final Slice slice = mConnectedDeviceSlice.getSlice(); + final Slice slice = mBluetoothDevicesSlice.getSlice(); final List sliceItems = slice.getItems(); - SliceTester.assertTitle(sliceItems, - mContext.getString(R.string.bluetooth_connected_devices)); + SliceTester.assertTitle(sliceItems, mContext.getString(R.string.bluetooth_devices)); } @Test - public void getSlice_hasConnectedDevices_shouldMatchBluetoothMockTitle() { + public void getSlice_hasBluetoothDevices_shouldMatchBluetoothMockTitle() { mockBluetoothDeviceList(); - doReturn(mBluetoothConnectedDeviceList).when( - mConnectedDeviceSlice).getBluetoothConnectedDevices(); + doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getBluetoothDevices(); - final Slice slice = mConnectedDeviceSlice.getSlice(); + final Slice slice = mBluetoothDevicesSlice.getSlice(); final List sliceItems = slice.getItems(); SliceTester.assertTitle(sliceItems, BLUETOOTH_MOCK_TITLE); } @Test - public void getSlice_hasConnectedDevices_shouldHavePairNewDevice() { + public void getSlice_hasBluetoothDevices_shouldHavePairNewDevice() { mockBluetoothDeviceList(); - doReturn(mBluetoothConnectedDeviceList).when( - mConnectedDeviceSlice).getBluetoothConnectedDevices(); + doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getBluetoothDevices(); - final Slice slice = mConnectedDeviceSlice.getSlice(); + final Slice slice = mBluetoothDevicesSlice.getSlice(); final List sliceItems = slice.getItems(); SliceTester.assertTitle(sliceItems, @@ -132,22 +128,20 @@ public class ConnectedDeviceSliceTest { } @Test - public void getSlice_noConnectedDevices_shouldHaveNoConnectedDeviceTitle() { - doReturn(mBluetoothConnectedDeviceList).when( - mConnectedDeviceSlice).getBluetoothConnectedDevices(); + public void getSlice_noBluetoothDevices_shouldHaveNoBluetoothDevicesTitle() { + doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getBluetoothDevices(); - final Slice slice = mConnectedDeviceSlice.getSlice(); + final Slice slice = mBluetoothDevicesSlice.getSlice(); final List sliceItems = slice.getItems(); - SliceTester.assertTitle(sliceItems, mContext.getString(R.string.no_connected_devices)); + SliceTester.assertTitle(sliceItems, mContext.getString(R.string.no_bluetooth_devices)); } @Test - public void getSlice_noConnectedDevices_shouldNotHavePairNewDevice() { - doReturn(mBluetoothConnectedDeviceList).when( - mConnectedDeviceSlice).getBluetoothConnectedDevices(); + public void getSlice_noBluetoothDevices_shouldNotHavePairNewDevice() { + doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getBluetoothDevices(); - final Slice slice = mConnectedDeviceSlice.getSlice(); + final Slice slice = mBluetoothDevicesSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, slice); assertThat(hasTitle(metadata, @@ -157,7 +151,7 @@ public class ConnectedDeviceSliceTest { private void mockBluetoothDeviceList() { doReturn(BLUETOOTH_MOCK_TITLE).when(mCachedBluetoothDevice).getName(); doReturn(BLUETOOTH_MOCK_SUMMARY).when(mCachedBluetoothDevice).getConnectionSummary(); - mBluetoothConnectedDeviceList.add(mCachedBluetoothDevice); + mBluetoothDeviceList.add(mCachedBluetoothDevice); } private boolean hasTitle(SliceMetadata metadata, String title) {