diff options
7 files changed, 89 insertions, 73 deletions
diff --git a/packages/SystemUI/res/layout/bluetooth_device_item.xml b/packages/SystemUI/res/layout/bluetooth_device_item.xml index 1c7e9977afe5..6d779438ad6c 100644 --- a/packages/SystemUI/res/layout/bluetooth_device_item.xml +++ b/packages/SystemUI/res/layout/bluetooth_device_item.xml @@ -27,7 +27,6 @@ <ImageView android:id="@+id/bluetooth_device_icon" - android:contentDescription="@string/accessibility_bluetooth_device_icon" android:layout_width="24dp" android:layout_height="24dp" app:layout_constraintStart_toStartOf="parent" @@ -39,8 +38,12 @@ android:layout_width="0dp" android:id="@+id/bluetooth_device_name" style="@style/BluetoothTileDialog.DeviceName" + android:textDirection="locale" + android:textAlignment="gravity" android:paddingStart="20dp" android:paddingTop="10dp" + android:maxLines="1" + android:ellipsize="end" app:layout_constraintWidth_percent="0.7" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toEndOf="@+id/bluetooth_device_icon" @@ -55,6 +58,8 @@ style="@style/BluetoothTileDialog.DeviceSummary" android:paddingStart="20dp" android:paddingBottom="10dp" + android:maxLines="1" + android:ellipsize="end" app:layout_constraintWidth_percent="0.7" app:layout_constraintTop_toBottomOf="@+id/bluetooth_device_name" app:layout_constraintStart_toEndOf="@+id/bluetooth_device_icon" @@ -66,6 +71,7 @@ android:id="@+id/gear_icon" android:layout_width="0dp" android:layout_height="0dp" + android:contentDescription="@string/accessibility_bluetooth_device_settings_gear" app:layout_constraintStart_toEndOf="@+id/bluetooth_device_name" app:layout_constraintEnd_toEndOf="@+id/gear_icon_image" app:layout_constraintTop_toTopOf="parent" diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml index 16aeb951822c..5d986e00deed 100644 --- a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml +++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml @@ -27,6 +27,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="24dp" + android:maxLines="1" android:ellipsize="end" android:gravity="center_vertical|center_horizontal" android:text="@string/quick_settings_bluetooth_label" @@ -58,9 +59,12 @@ style="@style/BluetoothTileDialog.Device" android:layout_width="0dp" android:layout_height="64dp" + android:maxLines="1" + android:ellipsize="end" android:gravity="center_vertical" android:layout_marginTop="4dp" android:text="@string/turn_on_bluetooth" + android:clickable="false" android:textAppearance="@style/TextAppearance.Dialog.Body.Message" android:textSize="16sp" app:layout_constraintEnd_toStartOf="@+id/bluetooth_toggle" @@ -84,53 +88,17 @@ app:layout_constraintStart_toEndOf="@+id/bluetooth_toggle_title" app:layout_constraintTop_toBottomOf="@id/bluetooth_tile_dialog_subtitle" /> - <androidx.constraintlayout.widget.Group - android:id="@+id/pair_new_device_layout_group" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:visibility="gone" - app:constraint_referenced_ids="ic_add,pair_new_device_text" /> - - <ImageView - android:id="@+id/ic_add" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_marginStart="36dp" - android:gravity="center_vertical" - android:importantForAccessibility="no" - android:src="@drawable/ic_add" - app:layout_constraintBottom_toTopOf="@id/device_list" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toStartOf="@id/pair_new_device_text" - app:layout_constraintTop_toBottomOf="@id/bluetooth_toggle_title" - android:tint="?android:attr/textColorPrimary" /> - - <TextView - android:id="@+id/pair_new_device_text" - style="@style/BluetoothTileDialog.Device" - android:layout_width="0dp" - android:layout_height="@dimen/bluetooth_dialog_device_height" - android:gravity="center_vertical" - android:layout_marginStart="0dp" - android:paddingStart="20dp" - android:text="@string/pair_new_bluetooth_devices" - android:textSize="14sp" - android:textAppearance="@style/TextAppearance.Dialog.Title" - app:layout_constraintBottom_toTopOf="@id/device_list" - app:layout_constraintStart_toEndOf="@+id/ic_add" - app:layout_constraintTop_toBottomOf="@id/bluetooth_toggle_title" - app:layout_constraintEnd_toEndOf="parent" /> - <androidx.recyclerview.widget.RecyclerView android:id="@+id/device_list" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="20dp" android:nestedScrollingEnabled="false" android:overScrollMode="never" android:scrollbars="vertical" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/pair_new_device_text" + app:layout_constraintTop_toBottomOf="@id/bluetooth_toggle" app:layout_constraintBottom_toTopOf="@+id/see_all_text" /> <androidx.constraintlayout.widget.Group @@ -148,7 +116,7 @@ android:importantForAccessibility="no" android:gravity="center_vertical" android:src="@drawable/ic_arrow_forward" - app:layout_constraintBottom_toTopOf="@+id/done_button" + app:layout_constraintBottom_toTopOf="@+id/pair_new_device_text" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@id/see_all_text" app:layout_constraintTop_toBottomOf="@id/device_list" /> @@ -157,18 +125,59 @@ android:id="@+id/see_all_text" style="@style/BluetoothTileDialog.Device" android:layout_width="0dp" - android:layout_height="@dimen/bluetooth_dialog_device_height" + android:layout_height="64dp" + android:maxLines="1" + android:ellipsize="end" android:gravity="center_vertical" android:layout_marginStart="0dp" android:paddingStart="20dp" android:text="@string/see_all_bluetooth_devices" android:textSize="14sp" android:textAppearance="@style/TextAppearance.Dialog.Title" - app:layout_constraintBottom_toTopOf="@+id/done_button" + app:layout_constraintBottom_toTopOf="@+id/pair_new_device_text" app:layout_constraintStart_toEndOf="@+id/ic_arrow" app:layout_constraintTop_toBottomOf="@id/device_list" app:layout_constraintEnd_toEndOf="parent" /> + <androidx.constraintlayout.widget.Group + android:id="@+id/pair_new_device_layout_group" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" + app:constraint_referenced_ids="ic_add,pair_new_device_text" /> + + <ImageView + android:id="@+id/ic_add" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginStart="36dp" + android:gravity="center_vertical" + android:importantForAccessibility="no" + android:src="@drawable/ic_add" + app:layout_constraintBottom_toTopOf="@id/done_button" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/pair_new_device_text" + app:layout_constraintTop_toBottomOf="@id/see_all_text" + android:tint="?android:attr/textColorPrimary" /> + + <TextView + android:id="@+id/pair_new_device_text" + style="@style/BluetoothTileDialog.Device" + android:layout_width="0dp" + android:layout_height="64dp" + android:maxLines="1" + android:ellipsize="end" + android:gravity="center_vertical" + android:layout_marginStart="0dp" + android:paddingStart="20dp" + android:text="@string/pair_new_bluetooth_devices" + android:textSize="14sp" + android:textAppearance="@style/TextAppearance.Dialog.Title" + app:layout_constraintBottom_toTopOf="@id/done_button" + app:layout_constraintStart_toEndOf="@+id/ic_add" + app:layout_constraintTop_toBottomOf="@id/see_all_text" + app:layout_constraintEnd_toEndOf="parent" /> + <Button android:id="@+id/done_button" style="@style/Widget.Dialog.Button" @@ -184,5 +193,5 @@ android:text="@string/inline_done_button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toBottomOf="@id/see_all_text" /> + app:layout_constraintTop_toBottomOf="@id/pair_new_device_text" /> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt index 8ae2dc227998..80af76de23df 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt @@ -102,9 +102,10 @@ constructor( showSeeAll: Boolean, showPairNewDevice: Boolean ) { - seeAllViewGroup.visibility = if (showSeeAll) VISIBLE else GONE - pairNewDeviceViewGroup.visibility = if (showPairNewDevice) VISIBLE else GONE - deviceItemAdapter.refreshDeviceItemList(deviceItem) + deviceItemAdapter.refreshDeviceItemList(deviceItem) { + seeAllViewGroup.visibility = if (showSeeAll) VISIBLE else GONE + pairNewDeviceViewGroup.visibility = if (showPairNewDevice) VISIBLE else GONE + } } internal fun onBluetoothStateUpdated(isEnabled: Boolean, subtitleResId: Int) { @@ -173,8 +174,8 @@ constructor( internal fun getItem(position: Int) = asyncListDiffer.currentList[position] - internal fun refreshDeviceItemList(updated: List<DeviceItem>) { - asyncListDiffer.submitList(updated) + internal fun refreshDeviceItemList(updated: List<DeviceItem>, callback: () -> Unit) { + asyncListDiffer.submitList(updated, callback) } internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt index 97e178371f2d..8e274932d4d2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt @@ -113,7 +113,6 @@ constructor( .launchIn(this) deviceItemInteractor.deviceItemUpdate - .filterNotNull() .onEach { dialog!!.onDeviceItemUpdated( it.take(MAX_DEVICE_ITEM_ENTRY), diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt index 14d24f952c8d..e196c6c27c8b 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt @@ -34,10 +34,10 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.withContext @@ -55,10 +55,10 @@ constructor( @Background private val backgroundDispatcher: CoroutineDispatcher, ) { - private val mutableDeviceItemUpdate: MutableStateFlow<List<DeviceItem>?> = - MutableStateFlow(null) + private val mutableDeviceItemUpdate: MutableSharedFlow<List<DeviceItem>> = + MutableSharedFlow(extraBufferCapacity = 1) internal val deviceItemUpdate - get() = mutableDeviceItemUpdate.asStateFlow() + get() = mutableDeviceItemUpdate.asSharedFlow() internal val deviceItemUpdateRequest: SharedFlow<Unit> = conflatedCallbackFlow { @@ -119,16 +119,15 @@ constructor( internal suspend fun updateDeviceItems(context: Context) { withContext(backgroundDispatcher) { - val mostRecentlyConnectedDevices = bluetoothAdapter?.mostRecentlyConnectedDevices - - mutableDeviceItemUpdate.value = + mutableDeviceItemUpdate.tryEmit( bluetoothTileDialogRepository.cachedDevices .mapNotNull { cachedDevice -> deviceItemFactoryList .firstOrNull { it.isFilterMatched(cachedDevice, audioManager) } ?.create(context, cachedDevice) } - .sort(displayPriority, mostRecentlyConnectedDevices) + .sort(displayPriority, bluetoothAdapter?.mostRecentlyConnectedDevices) + ) } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt index a0ff2ab330b8..dcda005b6109 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt @@ -32,6 +32,7 @@ import com.android.systemui.util.mockito.nullable import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.test.TestCoroutineScheduler @@ -95,8 +96,7 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() { testScope.backgroundScope, dispatcher, ) - `when`(deviceItemInteractor.deviceItemUpdate) - .thenReturn(MutableStateFlow(null).asStateFlow()) + `when`(deviceItemInteractor.deviceItemUpdate).thenReturn(MutableSharedFlow()) `when`(bluetoothStateInteractor.bluetoothStateUpdate) .thenReturn(MutableStateFlow(null).asStateFlow()) `when`(deviceItemInteractor.deviceItemUpdateRequest) diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt index 3593075c70fd..428f79cf9b1b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt @@ -27,10 +27,11 @@ import com.android.internal.logging.UiEventLogger import com.android.settingslib.bluetooth.CachedBluetoothDevice import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule @@ -78,7 +79,7 @@ class DeviceItemInteractorTest : SysuiTestCase() { @Before fun setUp() { - dispatcher = StandardTestDispatcher() + dispatcher = UnconfinedTestDispatcher() testScope = TestScope(dispatcher) interactor = DeviceItemInteractor( @@ -107,9 +108,10 @@ class DeviceItemInteractorTest : SysuiTestCase() { listOf(createFactory({ true }, deviceItem1)) ) + val latest by collectLastValue(interactor.deviceItemUpdate) interactor.updateDeviceItems(mContext) - assertThat(interactor.deviceItemUpdate.value).isEmpty() + assertThat(latest).isEqualTo(emptyList<DeviceItem>()) } } @@ -121,9 +123,10 @@ class DeviceItemInteractorTest : SysuiTestCase() { listOf(createFactory({ false }, deviceItem1)) ) + val latest by collectLastValue(interactor.deviceItemUpdate) interactor.updateDeviceItems(mContext) - assertThat(interactor.deviceItemUpdate.value).isEmpty() + assertThat(latest).isEqualTo(emptyList<DeviceItem>()) } } @@ -135,10 +138,10 @@ class DeviceItemInteractorTest : SysuiTestCase() { listOf(createFactory({ true }, deviceItem1)) ) + val latest by collectLastValue(interactor.deviceItemUpdate) interactor.updateDeviceItems(mContext) - assertThat(interactor.deviceItemUpdate.value).hasSize(1) - assertThat(interactor.deviceItemUpdate.value!![0]).isEqualTo(deviceItem1) + assertThat(latest).isEqualTo(listOf(deviceItem1)) } } @@ -150,11 +153,10 @@ class DeviceItemInteractorTest : SysuiTestCase() { listOf(createFactory({ false }, deviceItem1), createFactory({ true }, deviceItem2)) ) + val latest by collectLastValue(interactor.deviceItemUpdate) interactor.updateDeviceItems(mContext) - assertThat(interactor.deviceItemUpdate.value).hasSize(2) - assertThat(interactor.deviceItemUpdate.value!![0]).isEqualTo(deviceItem2) - assertThat(interactor.deviceItemUpdate.value!![1]).isEqualTo(deviceItem2) + assertThat(latest).isEqualTo(listOf(deviceItem2, deviceItem2)) } } @@ -177,10 +179,10 @@ class DeviceItemInteractorTest : SysuiTestCase() { `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) `when`(deviceItem2.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE) + val latest by collectLastValue(interactor.deviceItemUpdate) interactor.updateDeviceItems(mContext) - assertThat(interactor.deviceItemUpdate.value) - .isEqualTo(listOf(deviceItem2, deviceItem1)) + assertThat(latest).isEqualTo(listOf(deviceItem2, deviceItem1)) } } @@ -200,10 +202,10 @@ class DeviceItemInteractorTest : SysuiTestCase() { `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) `when`(deviceItem2.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE) + val latest by collectLastValue(interactor.deviceItemUpdate) interactor.updateDeviceItems(mContext) - assertThat(interactor.deviceItemUpdate.value) - .isEqualTo(listOf(deviceItem2, deviceItem1)) + assertThat(latest).isEqualTo(listOf(deviceItem2, deviceItem1)) } } |