Loading AndroidManifest.xml +2 −1 Original line number Diff line number Diff line Loading @@ -123,7 +123,8 @@ android:label="@string/settings_label_launcher" android:theme="@style/Theme.Settings.Home" android:taskAffinity="com.android.settings.root" android:launchMode="singleTask"> android:launchMode="singleTask" android:configChanges="keyboard|keyboardHidden"> <intent-filter android:priority="1"> <action android:name="android.settings.SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> Loading src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java +3 −4 Original line number Diff line number Diff line Loading @@ -69,18 +69,17 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback, public BluetoothDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback) { this(fragment, devicePreferenceCallback, Utils.getLocalBtManager(context)); this(context, fragment, devicePreferenceCallback, Utils.getLocalBtManager(context)); } @VisibleForTesting BluetoothDeviceUpdater(DashboardFragment fragment, BluetoothDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback, LocalBluetoothManager localManager) { mFragment = fragment; mDevicePreferenceCallback = devicePreferenceCallback; mPreferenceMap = new HashMap<>(); mLocalManager = localManager; mMetricsFeatureProvider = FeatureFactory.getFactory(mFragment.getContext()) .getMetricsFeatureProvider(); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } /** Loading src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java +37 −28 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.SubSettings; import com.android.settings.Utils; import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater; import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment; import com.android.settings.bluetooth.BluetoothPairingDetail; import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; import com.android.settings.core.SubSettingLauncher; import com.android.settings.slices.CustomSliceRegistry; Loading Loading @@ -78,9 +80,15 @@ public class BluetoothDevicesSlice implements CustomSliceable { private static final String TAG = "BluetoothDevicesSlice"; private final Context mContext; private final AvailableMediaBluetoothDeviceUpdater mAvailableMediaBtDeviceUpdater; private final SavedBluetoothDeviceUpdater mSavedBtDeviceUpdater; public BluetoothDevicesSlice(Context context) { mContext = context; mAvailableMediaBtDeviceUpdater = new AvailableMediaBluetoothDeviceUpdater(mContext, null /* fragment */, null /* devicePreferenceCallback */); mSavedBtDeviceUpdater = new SavedBluetoothDeviceUpdater(mContext, null /* fragment */, null /* devicePreferenceCallback */); } @Override Loading Loading @@ -123,10 +131,10 @@ public class BluetoothDevicesSlice implements CustomSliceable { final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilder(); // Get displayable device count. final int deviceCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT); final int displayableCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT); // According to the displayable device count to add bluetooth device rows. for (int i = 0; i < deviceCount; i++) { for (int i = 0; i < displayableCount; i++) { listBuilder.addRow(rows.get(i)); } Loading @@ -148,11 +156,14 @@ public class BluetoothDevicesSlice implements CustomSliceable { @Override public void onNotifyChange(Intent intent) { // Activate available media device. final int bluetoothDeviceHashCode = intent.getIntExtra(BLUETOOTH_DEVICE_HASH_CODE, -1); for (CachedBluetoothDevice cachedBluetoothDevice : getConnectedBluetoothDevices()) { if (cachedBluetoothDevice.hashCode() == bluetoothDeviceHashCode) { cachedBluetoothDevice.setActive(); for (CachedBluetoothDevice device : getPairedBluetoothDevices()) { if (device.hashCode() == bluetoothDeviceHashCode) { if (device.isConnected()) { device.setActive(); } else if (!device.isBusy()) { device.connect(); } return; } } Loading @@ -164,7 +175,7 @@ public class BluetoothDevicesSlice implements CustomSliceable { } @VisibleForTesting List<CachedBluetoothDevice> getConnectedBluetoothDevices() { List<CachedBluetoothDevice> getPairedBluetoothDevices() { final List<CachedBluetoothDevice> bluetoothDeviceList = new ArrayList<>(); // If Bluetooth is disable, skip to get the Bluetooth devices. Loading @@ -174,19 +185,18 @@ public class BluetoothDevicesSlice implements CustomSliceable { } // Get the Bluetooth devices from LocalBluetoothManager. final LocalBluetoothManager bluetoothManager = final LocalBluetoothManager localBtManager = com.android.settings.bluetooth.Utils.getLocalBtManager(mContext); if (bluetoothManager == null) { if (localBtManager == null) { Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is unsupported."); return bluetoothDeviceList; } final Collection<CachedBluetoothDevice> cachedDevices = bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy(); localBtManager.getCachedDeviceManager().getCachedDevicesCopy(); // Get all connected devices and sort them. // Get all paired devices and sort them. return cachedDevices.stream() .filter(device -> device.getDevice().getBondState() == BluetoothDevice.BOND_BONDED && device.getDevice().isConnected()) .filter(device -> device.getDevice().getBondState() == BluetoothDevice.BOND_BONDED) .sorted(COMPARATOR).collect(Collectors.toList()); } Loading Loading @@ -242,21 +252,21 @@ public class BluetoothDevicesSlice implements CustomSliceable { private List<ListBuilder.RowBuilder> getBluetoothRowBuilder() { // According to Bluetooth devices to create row builders. final List<ListBuilder.RowBuilder> bluetoothRows = new ArrayList<>(); final List<CachedBluetoothDevice> bluetoothDevices = getConnectedBluetoothDevices(); for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) { for (CachedBluetoothDevice device : getPairedBluetoothDevices()) { final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() .setTitleItem(getBluetoothDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE) .setTitle(bluetoothDevice.getName()) .setSubtitle(bluetoothDevice.getConnectionSummary()); if (bluetoothDevice.isConnectedA2dpDevice()) { // For available media devices, the primary action is to activate audio stream and // add setting icon to the end to link detail page. rowBuilder.setPrimaryAction(buildMediaBluetoothAction(bluetoothDevice)); rowBuilder.addEndItem(buildBluetoothDetailDeepLinkAction(bluetoothDevice)); .setTitleItem(getBluetoothDeviceIcon(device), ListBuilder.ICON_IMAGE) .setTitle(device.getName()) .setSubtitle(device.getConnectionSummary()); if (mAvailableMediaBtDeviceUpdater.isFilterMatched(device) || mSavedBtDeviceUpdater.isFilterMatched(device)) { // For all available media devices and previously connected devices, the primary // action is to activate or connect, and the end gear icon links to detail page. rowBuilder.setPrimaryAction(buildPrimaryBluetoothAction(device)); rowBuilder.addEndItem(buildBluetoothDetailDeepLinkAction(device)); } else { // For other devices, the primary action is to link detail page. rowBuilder.setPrimaryAction(buildBluetoothDetailDeepLinkAction(bluetoothDevice)); // For other devices, the primary action is to link to detail page. rowBuilder.setPrimaryAction(buildBluetoothDetailDeepLinkAction(device)); } bluetoothRows.add(rowBuilder); Loading @@ -266,8 +276,7 @@ public class BluetoothDevicesSlice implements CustomSliceable { } @VisibleForTesting SliceAction buildMediaBluetoothAction(CachedBluetoothDevice bluetoothDevice) { // Send broadcast to activate available media device. SliceAction buildPrimaryBluetoothAction(CachedBluetoothDevice bluetoothDevice) { final Intent intent = new Intent(getUri().toString()) .setClass(mContext, SliceBroadcastReceiver.class) .putExtra(BLUETOOTH_DEVICE_HASH_CODE, bluetoothDevice.hashCode()); Loading tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public class BluetoothDeviceUpdaterTest { mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice, false, BluetoothDevicePreference.SortType.TYPE_DEFAULT); mBluetoothDeviceUpdater = new BluetoothDeviceUpdater(mDashboardFragment, mDevicePreferenceCallback, new BluetoothDeviceUpdater(mContext, mDashboardFragment, mDevicePreferenceCallback, mLocalManager) { @Override public boolean isFilterMatched(CachedBluetoothDevice cachedBluetoothDevice) { Loading tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java +72 −26 Original line number Diff line number Diff line Loading @@ -23,12 +23,15 @@ 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.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.Intent; Loading Loading @@ -62,6 +65,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowBluetoothAdapter.class) public class BluetoothDevicesSliceTest { private static final String BLUETOOTH_MOCK_ADDRESS = "00:11:00:11:00:11"; Loading Loading @@ -96,6 +100,13 @@ public class BluetoothDevicesSliceTest { // Initial Bluetooth device list. mBluetoothDeviceList = new ArrayList<>(); final BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter(); if (defaultAdapter != null) { final ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract(defaultAdapter); shadowBluetoothAdapter.setEnabled(true); shadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON); } } @After Loading @@ -114,7 +125,6 @@ public class BluetoothDevicesSliceTest { } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_hasBluetoothHardware_shouldHaveBluetoothDevicesTitleAndPairNewDevice() { final Slice slice = mBluetoothDevicesSlice.getSlice(); Loading @@ -127,12 +137,9 @@ public class BluetoothDevicesSliceTest { } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_hasBluetoothDevices_shouldMatchBluetoothMockTitle() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(1); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Slice slice = mBluetoothDevicesSlice.getSlice(); Loading @@ -141,39 +148,43 @@ public class BluetoothDevicesSliceTest { } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_hasMediaBluetoothDevice_shouldBuildMediaBluetoothAction() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(1 /* deviceCount */); doReturn(true).when(mBluetoothDeviceList.get(0)).isConnectedA2dpDevice(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); public void getSlice_hasAvailableMediaDevice_shouldBuildPrimaryBluetoothAction() { mockBluetoothDeviceList(1); when(mBluetoothDeviceList.get(0).getDevice().isConnected()).thenReturn(true); doReturn(true).when(mBluetoothDeviceList.get(0)).isConnectedHearingAidDevice(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); mBluetoothDevicesSlice.getSlice(); verify(mBluetoothDevicesSlice).buildMediaBluetoothAction(any()); verify(mBluetoothDevicesSlice).buildPrimaryBluetoothAction(any()); } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_noMediaBluetoothDevice_shouldNotBuildMediaBluetoothAction() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(1 /* deviceCount */); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); public void getSlice_hasPreviouslyConnectedDevice_shouldBuildPrimaryBluetoothAction() { mockBluetoothDeviceList(1); when(mBluetoothDeviceList.get(0).getDevice().isConnected()).thenReturn(false); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); mBluetoothDevicesSlice.getSlice(); verify(mBluetoothDevicesSlice, never()).buildMediaBluetoothAction(any()); verify(mBluetoothDevicesSlice).buildPrimaryBluetoothAction(any()); } @Test public void getSlice_hasNonMediaDeviceConnected_shouldNotBuildPrimaryBluetoothAction() { mockBluetoothDeviceList(1); when(mBluetoothDeviceList.get(0).getDevice().isConnected()).thenReturn(true); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); mBluetoothDevicesSlice.getSlice(); verify(mBluetoothDevicesSlice, never()).buildPrimaryBluetoothAction(any()); } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_exceedDefaultRowCount_shouldOnlyShowDefaultRows() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(BluetoothDevicesSlice.DEFAULT_EXPANDED_ROW_COUNT + 1); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Slice slice = mBluetoothDevicesSlice.getSlice(); Loading @@ -183,9 +194,10 @@ public class BluetoothDevicesSliceTest { } @Test public void onNotifyChange_mediaDevice_shouldActivateDevice() { public void onNotifyChange_connectedDevice_shouldActivateDevice() { mockBluetoothDeviceList(1); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); doReturn(true).when(mBluetoothDeviceList.get(0)).isConnected(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Intent intent = new Intent().putExtra( BluetoothDevicesSlice.BLUETOOTH_DEVICE_HASH_CODE, mCachedBluetoothDevice.hashCode()); Loading @@ -195,7 +207,41 @@ public class BluetoothDevicesSliceTest { verify(mCachedBluetoothDevice).setActive(); } @Test public void onNotifyChange_availableDisconnectedDevice_shouldConnectToDevice() { mockBluetoothDeviceList(1); doReturn(false).when(mBluetoothDeviceList.get(0)).isConnected(); doReturn(false).when(mBluetoothDeviceList.get(0)).isBusy(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Intent intent = new Intent().putExtra( BluetoothDevicesSlice.BLUETOOTH_DEVICE_HASH_CODE, mCachedBluetoothDevice.hashCode()); mBluetoothDevicesSlice.onNotifyChange(intent); verify(mCachedBluetoothDevice).connect(); } @Test public void onNotifyChange_busyDisconnectedDevice_shouldDoNothing() { mockBluetoothDeviceList(1); doReturn(false).when(mBluetoothDeviceList.get(0)).isConnected(); doReturn(true).when(mBluetoothDeviceList.get(0)).isBusy(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Intent intent = new Intent().putExtra( BluetoothDevicesSlice.BLUETOOTH_DEVICE_HASH_CODE, mCachedBluetoothDevice.hashCode()); mBluetoothDevicesSlice.onNotifyChange(intent); verify(mCachedBluetoothDevice, never()).setActive(); verify(mCachedBluetoothDevice, never()).connect(); } private void mockBluetoothDeviceList(int deviceCount) { final BluetoothDevice device = mock(BluetoothDevice.class); doReturn(BluetoothDevice.BOND_BONDED).when(device).getBondState(); doReturn(device).when(mCachedBluetoothDevice).getDevice(); doReturn(BLUETOOTH_MOCK_TITLE).when(mCachedBluetoothDevice).getName(); doReturn(BLUETOOTH_MOCK_SUMMARY).when(mCachedBluetoothDevice).getConnectionSummary(); doReturn(BLUETOOTH_MOCK_ADDRESS).when(mCachedBluetoothDevice).getAddress(); Loading Loading
AndroidManifest.xml +2 −1 Original line number Diff line number Diff line Loading @@ -123,7 +123,8 @@ android:label="@string/settings_label_launcher" android:theme="@style/Theme.Settings.Home" android:taskAffinity="com.android.settings.root" android:launchMode="singleTask"> android:launchMode="singleTask" android:configChanges="keyboard|keyboardHidden"> <intent-filter android:priority="1"> <action android:name="android.settings.SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> Loading
src/com/android/settings/bluetooth/BluetoothDeviceUpdater.java +3 −4 Original line number Diff line number Diff line Loading @@ -69,18 +69,17 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback, public BluetoothDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback) { this(fragment, devicePreferenceCallback, Utils.getLocalBtManager(context)); this(context, fragment, devicePreferenceCallback, Utils.getLocalBtManager(context)); } @VisibleForTesting BluetoothDeviceUpdater(DashboardFragment fragment, BluetoothDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback, LocalBluetoothManager localManager) { mFragment = fragment; mDevicePreferenceCallback = devicePreferenceCallback; mPreferenceMap = new HashMap<>(); mLocalManager = localManager; mMetricsFeatureProvider = FeatureFactory.getFactory(mFragment.getContext()) .getMetricsFeatureProvider(); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } /** Loading
src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java +37 −28 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.SubSettings; import com.android.settings.Utils; import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater; import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment; import com.android.settings.bluetooth.BluetoothPairingDetail; import com.android.settings.bluetooth.SavedBluetoothDeviceUpdater; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; import com.android.settings.core.SubSettingLauncher; import com.android.settings.slices.CustomSliceRegistry; Loading Loading @@ -78,9 +80,15 @@ public class BluetoothDevicesSlice implements CustomSliceable { private static final String TAG = "BluetoothDevicesSlice"; private final Context mContext; private final AvailableMediaBluetoothDeviceUpdater mAvailableMediaBtDeviceUpdater; private final SavedBluetoothDeviceUpdater mSavedBtDeviceUpdater; public BluetoothDevicesSlice(Context context) { mContext = context; mAvailableMediaBtDeviceUpdater = new AvailableMediaBluetoothDeviceUpdater(mContext, null /* fragment */, null /* devicePreferenceCallback */); mSavedBtDeviceUpdater = new SavedBluetoothDeviceUpdater(mContext, null /* fragment */, null /* devicePreferenceCallback */); } @Override Loading Loading @@ -123,10 +131,10 @@ public class BluetoothDevicesSlice implements CustomSliceable { final List<ListBuilder.RowBuilder> rows = getBluetoothRowBuilder(); // Get displayable device count. final int deviceCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT); final int displayableCount = Math.min(rows.size(), DEFAULT_EXPANDED_ROW_COUNT); // According to the displayable device count to add bluetooth device rows. for (int i = 0; i < deviceCount; i++) { for (int i = 0; i < displayableCount; i++) { listBuilder.addRow(rows.get(i)); } Loading @@ -148,11 +156,14 @@ public class BluetoothDevicesSlice implements CustomSliceable { @Override public void onNotifyChange(Intent intent) { // Activate available media device. final int bluetoothDeviceHashCode = intent.getIntExtra(BLUETOOTH_DEVICE_HASH_CODE, -1); for (CachedBluetoothDevice cachedBluetoothDevice : getConnectedBluetoothDevices()) { if (cachedBluetoothDevice.hashCode() == bluetoothDeviceHashCode) { cachedBluetoothDevice.setActive(); for (CachedBluetoothDevice device : getPairedBluetoothDevices()) { if (device.hashCode() == bluetoothDeviceHashCode) { if (device.isConnected()) { device.setActive(); } else if (!device.isBusy()) { device.connect(); } return; } } Loading @@ -164,7 +175,7 @@ public class BluetoothDevicesSlice implements CustomSliceable { } @VisibleForTesting List<CachedBluetoothDevice> getConnectedBluetoothDevices() { List<CachedBluetoothDevice> getPairedBluetoothDevices() { final List<CachedBluetoothDevice> bluetoothDeviceList = new ArrayList<>(); // If Bluetooth is disable, skip to get the Bluetooth devices. Loading @@ -174,19 +185,18 @@ public class BluetoothDevicesSlice implements CustomSliceable { } // Get the Bluetooth devices from LocalBluetoothManager. final LocalBluetoothManager bluetoothManager = final LocalBluetoothManager localBtManager = com.android.settings.bluetooth.Utils.getLocalBtManager(mContext); if (bluetoothManager == null) { if (localBtManager == null) { Log.i(TAG, "Cannot get Bluetooth devices, Bluetooth is unsupported."); return bluetoothDeviceList; } final Collection<CachedBluetoothDevice> cachedDevices = bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy(); localBtManager.getCachedDeviceManager().getCachedDevicesCopy(); // Get all connected devices and sort them. // Get all paired devices and sort them. return cachedDevices.stream() .filter(device -> device.getDevice().getBondState() == BluetoothDevice.BOND_BONDED && device.getDevice().isConnected()) .filter(device -> device.getDevice().getBondState() == BluetoothDevice.BOND_BONDED) .sorted(COMPARATOR).collect(Collectors.toList()); } Loading Loading @@ -242,21 +252,21 @@ public class BluetoothDevicesSlice implements CustomSliceable { private List<ListBuilder.RowBuilder> getBluetoothRowBuilder() { // According to Bluetooth devices to create row builders. final List<ListBuilder.RowBuilder> bluetoothRows = new ArrayList<>(); final List<CachedBluetoothDevice> bluetoothDevices = getConnectedBluetoothDevices(); for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) { for (CachedBluetoothDevice device : getPairedBluetoothDevices()) { final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() .setTitleItem(getBluetoothDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE) .setTitle(bluetoothDevice.getName()) .setSubtitle(bluetoothDevice.getConnectionSummary()); if (bluetoothDevice.isConnectedA2dpDevice()) { // For available media devices, the primary action is to activate audio stream and // add setting icon to the end to link detail page. rowBuilder.setPrimaryAction(buildMediaBluetoothAction(bluetoothDevice)); rowBuilder.addEndItem(buildBluetoothDetailDeepLinkAction(bluetoothDevice)); .setTitleItem(getBluetoothDeviceIcon(device), ListBuilder.ICON_IMAGE) .setTitle(device.getName()) .setSubtitle(device.getConnectionSummary()); if (mAvailableMediaBtDeviceUpdater.isFilterMatched(device) || mSavedBtDeviceUpdater.isFilterMatched(device)) { // For all available media devices and previously connected devices, the primary // action is to activate or connect, and the end gear icon links to detail page. rowBuilder.setPrimaryAction(buildPrimaryBluetoothAction(device)); rowBuilder.addEndItem(buildBluetoothDetailDeepLinkAction(device)); } else { // For other devices, the primary action is to link detail page. rowBuilder.setPrimaryAction(buildBluetoothDetailDeepLinkAction(bluetoothDevice)); // For other devices, the primary action is to link to detail page. rowBuilder.setPrimaryAction(buildBluetoothDetailDeepLinkAction(device)); } bluetoothRows.add(rowBuilder); Loading @@ -266,8 +276,7 @@ public class BluetoothDevicesSlice implements CustomSliceable { } @VisibleForTesting SliceAction buildMediaBluetoothAction(CachedBluetoothDevice bluetoothDevice) { // Send broadcast to activate available media device. SliceAction buildPrimaryBluetoothAction(CachedBluetoothDevice bluetoothDevice) { final Intent intent = new Intent(getUri().toString()) .setClass(mContext, SliceBroadcastReceiver.class) .putExtra(BLUETOOTH_DEVICE_HASH_CODE, bluetoothDevice.hashCode()); Loading
tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceUpdaterTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,7 @@ public class BluetoothDeviceUpdaterTest { mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice, false, BluetoothDevicePreference.SortType.TYPE_DEFAULT); mBluetoothDeviceUpdater = new BluetoothDeviceUpdater(mDashboardFragment, mDevicePreferenceCallback, new BluetoothDeviceUpdater(mContext, mDashboardFragment, mDevicePreferenceCallback, mLocalManager) { @Override public boolean isFilterMatched(CachedBluetoothDevice cachedBluetoothDevice) { Loading
tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java +72 −26 Original line number Diff line number Diff line Loading @@ -23,12 +23,15 @@ 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.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.content.Intent; Loading Loading @@ -62,6 +65,7 @@ import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowBluetoothAdapter.class) public class BluetoothDevicesSliceTest { private static final String BLUETOOTH_MOCK_ADDRESS = "00:11:00:11:00:11"; Loading Loading @@ -96,6 +100,13 @@ public class BluetoothDevicesSliceTest { // Initial Bluetooth device list. mBluetoothDeviceList = new ArrayList<>(); final BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter(); if (defaultAdapter != null) { final ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract(defaultAdapter); shadowBluetoothAdapter.setEnabled(true); shadowBluetoothAdapter.setState(BluetoothAdapter.STATE_ON); } } @After Loading @@ -114,7 +125,6 @@ public class BluetoothDevicesSliceTest { } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_hasBluetoothHardware_shouldHaveBluetoothDevicesTitleAndPairNewDevice() { final Slice slice = mBluetoothDevicesSlice.getSlice(); Loading @@ -127,12 +137,9 @@ public class BluetoothDevicesSliceTest { } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_hasBluetoothDevices_shouldMatchBluetoothMockTitle() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(1); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Slice slice = mBluetoothDevicesSlice.getSlice(); Loading @@ -141,39 +148,43 @@ public class BluetoothDevicesSliceTest { } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_hasMediaBluetoothDevice_shouldBuildMediaBluetoothAction() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(1 /* deviceCount */); doReturn(true).when(mBluetoothDeviceList.get(0)).isConnectedA2dpDevice(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); public void getSlice_hasAvailableMediaDevice_shouldBuildPrimaryBluetoothAction() { mockBluetoothDeviceList(1); when(mBluetoothDeviceList.get(0).getDevice().isConnected()).thenReturn(true); doReturn(true).when(mBluetoothDeviceList.get(0)).isConnectedHearingAidDevice(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); mBluetoothDevicesSlice.getSlice(); verify(mBluetoothDevicesSlice).buildMediaBluetoothAction(any()); verify(mBluetoothDevicesSlice).buildPrimaryBluetoothAction(any()); } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_noMediaBluetoothDevice_shouldNotBuildMediaBluetoothAction() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(1 /* deviceCount */); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); public void getSlice_hasPreviouslyConnectedDevice_shouldBuildPrimaryBluetoothAction() { mockBluetoothDeviceList(1); when(mBluetoothDeviceList.get(0).getDevice().isConnected()).thenReturn(false); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); mBluetoothDevicesSlice.getSlice(); verify(mBluetoothDevicesSlice, never()).buildMediaBluetoothAction(any()); verify(mBluetoothDevicesSlice).buildPrimaryBluetoothAction(any()); } @Test public void getSlice_hasNonMediaDeviceConnected_shouldNotBuildPrimaryBluetoothAction() { mockBluetoothDeviceList(1); when(mBluetoothDeviceList.get(0).getDevice().isConnected()).thenReturn(true); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); mBluetoothDevicesSlice.getSlice(); verify(mBluetoothDevicesSlice, never()).buildPrimaryBluetoothAction(any()); } @Test @Config(shadows = ShadowBluetoothAdapter.class) public void getSlice_exceedDefaultRowCount_shouldOnlyShowDefaultRows() { final ShadowBluetoothAdapter adapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); adapter.setState(BluetoothAdapter.STATE_ON); mockBluetoothDeviceList(BluetoothDevicesSlice.DEFAULT_EXPANDED_ROW_COUNT + 1); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Slice slice = mBluetoothDevicesSlice.getSlice(); Loading @@ -183,9 +194,10 @@ public class BluetoothDevicesSliceTest { } @Test public void onNotifyChange_mediaDevice_shouldActivateDevice() { public void onNotifyChange_connectedDevice_shouldActivateDevice() { mockBluetoothDeviceList(1); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getConnectedBluetoothDevices(); doReturn(true).when(mBluetoothDeviceList.get(0)).isConnected(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Intent intent = new Intent().putExtra( BluetoothDevicesSlice.BLUETOOTH_DEVICE_HASH_CODE, mCachedBluetoothDevice.hashCode()); Loading @@ -195,7 +207,41 @@ public class BluetoothDevicesSliceTest { verify(mCachedBluetoothDevice).setActive(); } @Test public void onNotifyChange_availableDisconnectedDevice_shouldConnectToDevice() { mockBluetoothDeviceList(1); doReturn(false).when(mBluetoothDeviceList.get(0)).isConnected(); doReturn(false).when(mBluetoothDeviceList.get(0)).isBusy(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Intent intent = new Intent().putExtra( BluetoothDevicesSlice.BLUETOOTH_DEVICE_HASH_CODE, mCachedBluetoothDevice.hashCode()); mBluetoothDevicesSlice.onNotifyChange(intent); verify(mCachedBluetoothDevice).connect(); } @Test public void onNotifyChange_busyDisconnectedDevice_shouldDoNothing() { mockBluetoothDeviceList(1); doReturn(false).when(mBluetoothDeviceList.get(0)).isConnected(); doReturn(true).when(mBluetoothDeviceList.get(0)).isBusy(); doReturn(mBluetoothDeviceList).when(mBluetoothDevicesSlice).getPairedBluetoothDevices(); final Intent intent = new Intent().putExtra( BluetoothDevicesSlice.BLUETOOTH_DEVICE_HASH_CODE, mCachedBluetoothDevice.hashCode()); mBluetoothDevicesSlice.onNotifyChange(intent); verify(mCachedBluetoothDevice, never()).setActive(); verify(mCachedBluetoothDevice, never()).connect(); } private void mockBluetoothDeviceList(int deviceCount) { final BluetoothDevice device = mock(BluetoothDevice.class); doReturn(BluetoothDevice.BOND_BONDED).when(device).getBondState(); doReturn(device).when(mCachedBluetoothDevice).getDevice(); doReturn(BLUETOOTH_MOCK_TITLE).when(mCachedBluetoothDevice).getName(); doReturn(BLUETOOTH_MOCK_SUMMARY).when(mCachedBluetoothDevice).getConnectionSummary(); doReturn(BLUETOOTH_MOCK_ADDRESS).when(mCachedBluetoothDevice).getAddress(); Loading