summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chelsea Hao <chelseahao@google.com> 2023-09-25 13:44:59 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-09-25 13:44:59 +0000
commitd4bbffb45cd0804acc6abb619be7d4237691f745 (patch)
treeff7d2fd5c1570eac4bb0dcf54e53b1d724257744
parent7eb14aeeefb1ce5f076007c3d06a8eeca9e06b9a (diff)
parentdf21e0df6c65063aef4bcba1ebf17739a6f58432 (diff)
Merge "Implemented click events for gear, see all and pair new device." into main
-rw-r--r--packages/SystemUI/res/layout/bluetooth_device_item.xml88
-rw-r--r--packages/SystemUI/res/layout/bluetooth_tile_dialog.xml306
-rw-r--r--packages/SystemUI/res/values/strings.xml8
-rw-r--r--packages/SystemUI/res/values/styles.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialog.kt68
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogUiEvent.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModel.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt68
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogViewModelTest.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractorTest.kt4
12 files changed, 458 insertions, 241 deletions
diff --git a/packages/SystemUI/res/layout/bluetooth_device_item.xml b/packages/SystemUI/res/layout/bluetooth_device_item.xml
index 4265c4b14ee9..6dd44fbe645d 100644
--- a/packages/SystemUI/res/layout/bluetooth_device_item.xml
+++ b/packages/SystemUI/res/layout/bluetooth_device_item.xml
@@ -14,55 +14,81 @@
~ limitations under the License.
-->
+<!-- TODO(b/298124674) remove this root -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/bluetooth_device_container"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/bluetooth_device_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="4dp">
- <LinearLayout
- android:id="@+id/bluetooth_device"
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/bluetooth_device_row"
style="@style/BluetoothTileDialog.Device"
android:layout_height="@dimen/bluetooth_dialog_device_height"
android:paddingEnd="24dp"
android:paddingStart="20dp"
android:baselineAligned="false">
- <FrameLayout
+ <ImageView
+ android:id="@+id/bluetooth_device_icon"
+ android:contentDescription="@string/accessibility_bluetooth_device_icon"
android:layout_width="24dp"
android:layout_height="24dp"
- android:layout_gravity="center_vertical|start"
- android:clickable="false">
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_gravity="center_vertical" />
- <ImageView
- android:id="@+id/bluetooth_device_icon"
- android:contentDescription="@string/accessibility_bluetooth_device_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center" />
- </FrameLayout>
+ <View
+ android:id="@+id/bluetooth_device"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintTop_toTopOf="@+id/bluetooth_device_name"
+ app:layout_constraintBottom_toBottomOf="@+id/bluetooth_device_summary"
+ app:layout_constraintStart_toStartOf="@+id/bluetooth_device_name"
+ app:layout_constraintEnd_toEndOf="@+id/bluetooth_device_name" />
- <LinearLayout
+ <TextView
android:layout_width="0dp"
- android:layout_height="@dimen/bluetooth_dialog_device_height"
+ android:id="@+id/bluetooth_device_name"
+ style="@style/BluetoothTileDialog.DeviceName"
android:paddingStart="20dp"
- android:paddingEnd="24dp"
- android:layout_marginEnd="30dp"
- android:layout_weight="1"
- android:clickable="false"
- android:gravity="start|center_vertical"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/bluetooth_device_name"
- style="@style/BluetoothTileDialog.DeviceName"
- android:textSize="14sp" />
+ android:paddingTop="10dp"
+ app:layout_constraintWidth_percent="0.7"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/bluetooth_device_icon"
+ app:layout_constraintEnd_toStartOf="@+id/gear_icon"
+ app:layout_constraintBottom_toTopOf="@+id/bluetooth_device_summary"
+ android:gravity="center_vertical"
+ android:textSize="14sp" />
- <TextView
- android:id="@+id/bluetooth_device_summary"
- style="@style/BluetoothTileDialog.DeviceSummary" />
- </LinearLayout>
- </LinearLayout>
+ <TextView
+ android:layout_width="0dp"
+ android:id="@+id/bluetooth_device_summary"
+ style="@style/BluetoothTileDialog.DeviceSummary"
+ android:paddingStart="20dp"
+ android:paddingBottom="10dp"
+ app:layout_constraintWidth_percent="0.7"
+ app:layout_constraintTop_toBottomOf="@+id/bluetooth_device_name"
+ app:layout_constraintStart_toEndOf="@+id/bluetooth_device_icon"
+ app:layout_constraintEnd_toStartOf="@+id/gear_icon"
+ app:layout_constraintBottom_toBottomOf="parent"
+ android:gravity="center_vertical" />
+ <ImageView
+ android:id="@+id/gear_icon"
+ android:src="@drawable/ic_settings_24dp"
+ android:contentDescription="@string/accessibility_bluetooth_device_settings_gear"
+ android:layout_width="0dp"
+ android:layout_height="24dp"
+ app:layout_constraintStart_toEndOf="@+id/bluetooth_device_name"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintWidth_percent="0.3"
+ android:gravity="center_vertical"
+ android:paddingStart="10dp" />
+ </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
index 9d14d0f36048..16aeb951822c 100644
--- a/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
+++ b/packages/SystemUI/res/layout/bluetooth_tile_dialog.xml
@@ -14,155 +14,175 @@
~ limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
- android:layout_width="@dimen/large_dialog_width"
- android:layout_height="wrap_content"
- android:orientation="vertical">
+ style="@style/Widget.SliceView.Panel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
- <LinearLayout
- style="@style/Widget.SliceView.Panel"
- android:layout_width="match_parent"
+ <TextView
+ android:id="@+id/bluetooth_tile_dialog_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="24dp"
+ android:ellipsize="end"
+ android:gravity="center_vertical|center_horizontal"
+ android:text="@string/quick_settings_bluetooth_label"
+ android:textAppearance="@style/TextAppearance.Dialog.Title"
+ android:textSize="24sp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/bluetooth_tile_dialog_subtitle"
+ app:layout_constraintTop_toTopOf="parent" />
+
+ <TextView
+ android:id="@+id/bluetooth_tile_dialog_subtitle"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
android:layout_marginBottom="@dimen/bluetooth_dialog_layout_margin"
- android:layout_marginTop="24dp"
+ android:ellipsize="end"
android:gravity="center_vertical|center_horizontal"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/bluetooth_tile_dialog_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:gravity="center_vertical|center_horizontal"
- android:text="@string/quick_settings_bluetooth_label"
- android:textAppearance="@style/TextAppearance.Dialog.Title"
- android:textSize="24sp" />
-
- <TextView
- android:id="@+id/bluetooth_tile_dialog_subtitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
- android:ellipsize="end"
- android:gravity="center_vertical|center_horizontal"
- android:maxLines="1"
- android:text="@string/quick_settings_bluetooth_tile_subtitle"
- android:textAppearance="@style/TextAppearance.Dialog.Body.Message" />
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/turn_on_bluetooth_layout"
+ android:maxLines="1"
+ android:text="@string/quick_settings_bluetooth_tile_subtitle"
+ android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/bluetooth_toggle_title"
+ app:layout_constraintTop_toBottomOf="@id/bluetooth_tile_dialog_title" />
+
+ <TextView
+ android:id="@+id/bluetooth_toggle_title"
style="@style/BluetoothTileDialog.Device"
+ android:layout_width="0dp"
+ android:layout_height="64dp"
+ android:gravity="center_vertical"
+ android:layout_marginTop="4dp"
+ android:text="@string/turn_on_bluetooth"
+ android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
+ android:textSize="16sp"
+ app:layout_constraintEnd_toStartOf="@+id/bluetooth_toggle"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/bluetooth_tile_dialog_subtitle" />
+
+ <Switch
+ android:id="@+id/bluetooth_toggle"
+ style="@style/BluetoothTileDialog.Device"
+ android:layout_width="0dp"
+ android:layout_height="48dp"
+ android:gravity="center|center_vertical"
+ android:paddingEnd="24dp"
+ android:layout_marginTop="10dp"
+ android:contentDescription="@string/turn_on_bluetooth"
+ android:switchMinWidth="@dimen/settingslib_switch_track_width"
+ android:theme="@style/MainSwitch.Settingslib"
+ android:thumb="@drawable/settingslib_thumb_selector"
+ android:track="@drawable/settingslib_track_selector"
+ app:layout_constraintEnd_toEndOf="parent"
+ 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"
- android:clickable="false"
- android:focusable="false"
- android:baselineAligned="false">
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="start|center_vertical"
- android:orientation="vertical"
- android:clickable="false">
- <TextView
- android:id="@+id/bluetooth_toggle_title"
- android:text="@string/turn_on_bluetooth"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="start|center_vertical"
- android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
- android:textSize="16sp"/>
- </LinearLayout>
-
- <FrameLayout
- android:layout_width="@dimen/settingslib_switch_track_width"
- android:layout_height="48dp"
- android:layout_marginTop="10dp"
- android:layout_marginBottom="10dp">
- <Switch
- android:id="@+id/bluetooth_toggle"
- android:contentDescription="@string/turn_on_bluetooth"
- android:switchMinWidth="@dimen/settingslib_switch_track_width"
- android:layout_gravity="center"
- android:layout_width="@dimen/settingslib_switch_track_width"
- android:layout_height="match_parent"
- android:track="@drawable/settingslib_track_selector"
- android:thumb="@drawable/settingslib_thumb_selector"
- android:theme="@style/MainSwitch.Settingslib"/>
- </FrameLayout>
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/body_layout"
+ 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:orientation="vertical">
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/device_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:nestedScrollingEnabled="false"
- android:overScrollMode="never"
- android:scrollbars="vertical" />
-
- <LinearLayout
- android:id="@+id/see_all_layout"
- style="@style/BluetoothTileDialog.Device"
- android:layout_height="64dp"
- android:paddingStart="20dp"
- android:visibility="gone">
-
- <FrameLayout
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:layout_gravity="center_vertical|start"
- android:clickable="false">
-
- <ImageView
- android:id="@+id/arrow_forward"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@drawable/ic_arrow_forward"
- android:importantForAccessibility="no" />
- </FrameLayout>
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin"
- android:clickable="false"
- android:orientation="vertical">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="start|center_vertical"
- android:text="@string/see_all_bluetooth_devices"
- android:textAppearance="@style/TextAppearance.Dialog.Body.Message"
- android:textSize="14sp" />
- </FrameLayout>
- </LinearLayout>
-
- <Button
- android:id="@+id/done_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginStart="@dimen/dialog_side_padding"
- android:layout_marginEnd="@dimen/dialog_side_padding"
- android:layout_marginBottom="@dimen/dialog_bottom_padding"
- android:text="@string/inline_done_button"
- android:layout_gravity="end|center_vertical"
- style="@style/Widget.Dialog.Button"
- android:maxLines="1"
- android:ellipsize="end"
- android:clickable="true"
- android:focusable="true"/>
- </LinearLayout>
-</LinearLayout> \ No newline at end of file
+ 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_constraintBottom_toTopOf="@+id/see_all_text" />
+
+ <androidx.constraintlayout.widget.Group
+ android:id="@+id/see_all_layout_group"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ app:constraint_referenced_ids="ic_arrow,see_all_text" />
+
+ <ImageView
+ android:id="@+id/ic_arrow"
+ android:layout_marginStart="36dp"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:importantForAccessibility="no"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_arrow_forward"
+ app:layout_constraintBottom_toTopOf="@+id/done_button"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/see_all_text"
+ app:layout_constraintTop_toBottomOf="@id/device_list" />
+
+ <TextView
+ android:id="@+id/see_all_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/see_all_bluetooth_devices"
+ android:textSize="14sp"
+ android:textAppearance="@style/TextAppearance.Dialog.Title"
+ app:layout_constraintBottom_toTopOf="@+id/done_button"
+ app:layout_constraintStart_toEndOf="@+id/ic_arrow"
+ app:layout_constraintTop_toBottomOf="@id/device_list"
+ app:layout_constraintEnd_toEndOf="parent" />
+
+ <Button
+ android:id="@+id/done_button"
+ style="@style/Widget.Dialog.Button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/dialog_bottom_padding"
+ android:layout_marginEnd="@dimen/dialog_side_padding"
+ android:layout_marginStart="@dimen/dialog_side_padding"
+ android:clickable="true"
+ android:ellipsize="end"
+ android:focusable="true"
+ android:maxLines="1"
+ android:text="@string/inline_done_button"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/see_all_text" />
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5f3ddda0e8bf..bbc363b855b7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -462,7 +462,9 @@
<!-- Content description of the bluetooth device icon. [CHAR LIMIT=NONE] -->
<string name="accessibility_bluetooth_device_icon">Bluetooth device icon</string>
- <!-- Content description of the bluetooth icon when connecting for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+
+ <!-- Content description of the bluetooth device settings gear icon. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_bluetooth_device_settings_gear">Bluetooth device settings gear</string>
<!-- Content description of the battery when battery state is unknown for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_battery_unknown">Battery percentage unknown.</string>
@@ -625,7 +627,9 @@
<!-- QuickSettings: Bluetooth detail panel, text when there are no items [CHAR LIMIT=NONE] -->
<string name="quick_settings_bluetooth_detail_empty_text">No paired devices available</string>
<!-- QuickSettings: Bluetooth dialog subtitle [CHAR LIMIT=NONE]-->
- <string name="quick_settings_bluetooth_tile_subtitle">Tap to connect or disconnect</string>
+ <string name="quick_settings_bluetooth_tile_subtitle">Tap a device to connect</string>
+ <!-- QuickSettings: Bluetooth dialog pair new devices [CHAR LIMIT=NONE]-->
+ <string name="pair_new_bluetooth_devices">Pair new device</string>
<!-- QuickSettings: Bluetooth dialog see all devices [CHAR LIMIT=NONE]-->
<string name="see_all_bluetooth_devices">See all</string>
<!-- QuickSettings: Bluetooth dialog turn on Bluetooth [CHAR LIMIT=NONE]-->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 3bd6ab0b32bc..084cb883d766 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1280,7 +1280,6 @@
</style>
<style name="BluetoothTileDialog.DeviceSummary">
- <item name="android:layout_marginEnd">7dp</item>
<item name="android:ellipsize">end</item>
<item name="android:maxLines">2</item>
<item name="android:textAppearance">@style/TextAppearance.Dialog.Body.Message</item>
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 7a436a761594..6815a7325081 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
@@ -28,6 +28,7 @@ import android.widget.Switch
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -42,11 +43,12 @@ internal class BluetoothTileDialog
constructor(
private val bluetoothToggleInitialValue: Boolean,
private val bluetoothTileDialogCallback: BluetoothTileDialogCallback,
+ private val uiEventLogger: UiEventLogger,
context: Context,
) : SystemUIDialog(context, DEFAULT_THEME, DEFAULT_DISMISS_ON_DEVICE_LOCK) {
- private val mutableBluetoothStateSwitchedFlow: MutableStateFlow<Boolean?> =
- MutableStateFlow(null)
+ private val mutableBluetoothStateSwitchedFlow: MutableStateFlow<Boolean> =
+ MutableStateFlow(bluetoothToggleInitialValue)
internal val bluetoothStateSwitchedFlow
get() = mutableBluetoothStateSwitchedFlow.asStateFlow()
@@ -55,31 +57,48 @@ constructor(
internal val deviceItemClickedFlow
get() = mutableClickedFlow.asSharedFlow()
- private val deviceItemAdapter: Adapter = Adapter()
+ private val deviceItemAdapter: Adapter = Adapter(bluetoothTileDialogCallback)
private lateinit var toggleView: Switch
private lateinit var doneButton: View
- private lateinit var seeAllView: View
+ private lateinit var seeAllViewGroup: View
+ private lateinit var pairNewDeviceViewGroup: View
+ private lateinit var seeAllText: View
+ private lateinit var pairNewDeviceText: View
private lateinit var deviceListView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TILE_DIALOG_SHOWN)
setContentView(LayoutInflater.from(context).inflate(R.layout.bluetooth_tile_dialog, null))
toggleView = requireViewById(R.id.bluetooth_toggle)
doneButton = requireViewById(R.id.done_button)
- seeAllView = requireViewById(R.id.see_all_layout)
+ seeAllViewGroup = requireViewById(R.id.see_all_layout_group)
+ pairNewDeviceViewGroup = requireViewById(R.id.pair_new_device_layout_group)
+ seeAllText = requireViewById(R.id.see_all_text)
+ pairNewDeviceText = requireViewById(R.id.pair_new_device_text)
deviceListView = requireViewById<RecyclerView>(R.id.device_list)
setupToggle()
setupRecyclerView()
doneButton.setOnClickListener { dismiss() }
+ seeAllText.setOnClickListener { bluetoothTileDialogCallback.onSeeAllClicked(it) }
+ pairNewDeviceText.setOnClickListener {
+ bluetoothTileDialogCallback.onPairNewDeviceClicked(it)
+ }
}
- internal fun onDeviceItemUpdated(deviceItem: List<DeviceItem>, showSeeAll: Boolean) {
- seeAllView.visibility = if (showSeeAll) VISIBLE else GONE
+ // TODO(b/298124674): use DiffUtil or AsyncListDiffer to avoid updating the whole list
+ internal fun onDeviceItemUpdated(
+ deviceItem: List<DeviceItem>,
+ showSeeAll: Boolean,
+ showPairNewDevice: Boolean
+ ) {
+ seeAllViewGroup.visibility = if (showSeeAll) VISIBLE else GONE
+ pairNewDeviceViewGroup.visibility = if (showPairNewDevice) VISIBLE else GONE
deviceItemAdapter.refreshDeviceItemList(deviceItem)
}
@@ -95,6 +114,7 @@ constructor(
toggleView.isChecked = bluetoothToggleInitialValue
toggleView.setOnCheckedChangeListener { _, isChecked ->
mutableBluetoothStateSwitchedFlow.value = isChecked
+ uiEventLogger.log(BluetoothTileDialogUiEvent.BLUETOOTH_TOGGLE_CLICKED)
}
}
@@ -105,11 +125,8 @@ constructor(
}
}
- internal inner class Adapter : RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() {
-
- init {
- setHasStableIds(true)
- }
+ internal inner class Adapter(private val onClickCallback: BluetoothTileDialogCallback) :
+ RecyclerView.Adapter<Adapter.DeviceItemViewHolder>() {
private val deviceItem: MutableList<DeviceItem> = mutableListOf()
@@ -122,11 +139,9 @@ constructor(
override fun getItemCount() = deviceItem.size
- override fun getItemId(position: Int) = position.toLong()
-
override fun onBindViewHolder(holder: DeviceItemViewHolder, position: Int) {
val item = getItem(position)
- holder.bind(item, position)
+ holder.bind(item, position, onClickCallback)
}
internal fun getItem(position: Int) = deviceItem[position]
@@ -143,17 +158,26 @@ constructor(
}
internal inner class DeviceItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
- private val container = view.requireViewById<View>(R.id.bluetooth_device)
+ private val container = view.requireViewById<View>(R.id.bluetooth_device_row)
+ private val deviceView = view.requireViewById<View>(R.id.bluetooth_device)
private val nameView = view.requireViewById<TextView>(R.id.bluetooth_device_name)
private val summaryView = view.requireViewById<TextView>(R.id.bluetooth_device_summary)
private val iconView = view.requireViewById<ImageView>(R.id.bluetooth_device_icon)
+ private val gearView = view.requireViewById<View>(R.id.gear_icon)
- internal fun bind(item: DeviceItem, position: Int) {
+ internal fun bind(
+ item: DeviceItem,
+ position: Int,
+ deviceItemOnClickCallback: BluetoothTileDialogCallback
+ ) {
container.apply {
isEnabled = item.isEnabled
alpha = item.alpha
background = item.background
- setOnClickListener { mutableClickedFlow.tryEmit(Pair(item, position)) }
+ }
+ deviceView.setOnClickListener {
+ mutableClickedFlow.tryEmit(Pair(item, position))
+ uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_CLICKED)
}
nameView.text = item.deviceName
summaryView.text = item.connectionSummary
@@ -163,6 +187,9 @@ constructor(
contentDescription = it.second
}
}
+ gearView.setOnClickListener {
+ deviceItemOnClickCallback.onDeviceItemGearClicked(item, it)
+ }
}
}
}
@@ -171,5 +198,10 @@ constructor(
const val ENABLED_ALPHA = 1.0f
const val DISABLED_ALPHA = 0.3f
const val MAX_DEVICE_ITEM_ENTRY = 3
+ const val ACTION_BLUETOOTH_DEVICE_DETAILS =
+ "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS"
+ const val ACTION_PREVIOUSLY_CONNECTED_DEVICE =
+ "com.android.settings.PREVIOUSLY_CONNECTED_DEVICE"
+ const val ACTION_PAIR_NEW_DEVICE = "android.settings.BLUETOOTH_PAIRING_SETTINGS"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogUiEvent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogUiEvent.kt
new file mode 100644
index 000000000000..2865ad7a3e83
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogUiEvent.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.dialog.bluetooth
+
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+
+/** UI Events for the bluetooth tile dialog. */
+enum class BluetoothTileDialogUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "The bluetooth tile dialog is shown") BLUETOOTH_TILE_DIALOG_SHOWN(1493),
+ @UiEvent(doc = "The master toggle is clicked") BLUETOOTH_TOGGLE_CLICKED(1494),
+ @UiEvent(doc = "Pair new device is clicked") PAIR_NEW_DEVICE_CLICKED(1495),
+ @UiEvent(doc = "See all is clicked") SEE_ALL_CLICKED(1496),
+ @UiEvent(doc = "Gear icon clicked") DEVICE_GEAR_CLICKED(1497),
+ @UiEvent(doc = "Device clicked") DEVICE_CLICKED(1498),
+ @UiEvent(doc = "Connected device clicked to active") CONNECTED_DEVICE_SET_ACTIVE(1499),
+ @UiEvent(doc = "Saved clicked to connect") SAVED_DEVICE_CONNECT(1500);
+
+ override fun getId() = metricId
+}
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 63f05318facc..012484f2f0a6 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
@@ -17,12 +17,19 @@
package com.android.systemui.qs.tiles.dialog.bluetooth
import android.content.Context
+import android.content.Intent
+import android.os.Bundle
import android.view.View
import androidx.annotation.VisibleForTesting
+import com.android.internal.logging.UiEventLogger
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ACTION_BLUETOOTH_DEVICE_DETAILS
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ACTION_PAIR_NEW_DEVICE
+import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.ACTION_PREVIOUSLY_CONNECTED_DEVICE
import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.MAX_DEVICE_ITEM_ENTRY
import com.android.systemui.statusbar.phone.SystemUIDialog
import javax.inject.Inject
@@ -42,6 +49,8 @@ constructor(
private val deviceItemInteractor: DeviceItemInteractor,
private val bluetoothStateInteractor: BluetoothStateInteractor,
private val dialogLaunchAnimator: DialogLaunchAnimator,
+ private val activityStarter: ActivityStarter,
+ private val uiEventLogger: UiEventLogger,
@Application private val coroutineScope: CoroutineScope,
@Main private val mainDispatcher: CoroutineDispatcher,
) : BluetoothTileDialogCallback {
@@ -93,14 +102,14 @@ constructor(
.onEach {
dialog!!.onDeviceItemUpdated(
it.take(MAX_DEVICE_ITEM_ENTRY),
- showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY
+ showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY,
+ showPairNewDevice = bluetoothStateInteractor.isBluetoothEnabled
)
}
.launchIn(this)
dialog!!
.bluetoothStateSwitchedFlow
- .filterNotNull()
.onEach { bluetoothStateInteractor.isBluetoothEnabled = it }
.launchIn(this)
@@ -119,19 +128,57 @@ constructor(
return BluetoothTileDialog(
bluetoothStateInteractor.isBluetoothEnabled,
this@BluetoothTileDialogViewModel,
+ uiEventLogger,
context
)
.apply { SystemUIDialog.registerDismissListener(this) { dismissDialog() } }
}
+ override fun onDeviceItemGearClicked(deviceItem: DeviceItem, view: View) {
+ uiEventLogger.log(BluetoothTileDialogUiEvent.DEVICE_GEAR_CLICKED)
+ val intent =
+ Intent(ACTION_BLUETOOTH_DEVICE_DETAILS).apply {
+ putExtra(
+ ":settings:show_fragment_args",
+ Bundle().apply {
+ putString("device_address", deviceItem.cachedBluetoothDevice.address)
+ }
+ )
+ }
+ startSettingsActivity(intent, view)
+ }
+
+ override fun onSeeAllClicked(view: View) {
+ uiEventLogger.log(BluetoothTileDialogUiEvent.SEE_ALL_CLICKED)
+ startSettingsActivity(Intent(ACTION_PREVIOUSLY_CONNECTED_DEVICE), view)
+ }
+
+ override fun onPairNewDeviceClicked(view: View) {
+ uiEventLogger.log(BluetoothTileDialogUiEvent.PAIR_NEW_DEVICE_CLICKED)
+ startSettingsActivity(Intent(ACTION_PAIR_NEW_DEVICE), view)
+ }
+
private fun dismissDialog() {
job?.cancel()
job = null
dialog?.dismiss()
dialog = null
}
+
+ private fun startSettingsActivity(intent: Intent, view: View) {
+ dialog?.run {
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
+ activityStarter.postStartActivityDismissingKeyguard(
+ intent,
+ 0,
+ dialogLaunchAnimator.createActivityLaunchController(view)
+ )
+ }
+ }
}
internal interface BluetoothTileDialogCallback {
- // TODO(b/298124674): Add click events for gear, see all and pair new device.
+ fun onDeviceItemGearClicked(deviceItem: DeviceItem, view: View)
+ fun onSeeAllClicked(view: View)
+ fun onPairNewDeviceClicked(view: View)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
index fd57fd490eb3..a16a9f1f1017 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
@@ -52,16 +52,16 @@ internal class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
cachedBluetoothDevice = cachedDevice,
deviceName = cachedDevice.name,
connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() }
- ?: context.getString(connected),
+ ?: context.getString(connected),
iconWithDescription =
- BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
- Pair(p.first, p.second)
- },
+ BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
+ Pair(p.first, p.second)
+ },
background = context.getDrawable(backgroundOn),
isEnabled = !cachedDevice.isBusy,
alpha =
- if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
- else BluetoothTileDialog.ENABLED_ALPHA,
+ if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
+ else BluetoothTileDialog.ENABLED_ALPHA,
)
}
}
@@ -80,16 +80,15 @@ internal class ConnectedDeviceItemFactory : DeviceItemFactory() {
cachedBluetoothDevice = cachedDevice,
deviceName = cachedDevice.name,
connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() }
- ?: context.getString(connected),
+ ?: context.getString(connected),
iconWithDescription =
- BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
- Pair(p.first, p.second)
- },
- background = context.getDrawable(backgroundOn),
+ BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
+ Pair(p.first, p.second)
+ },
isEnabled = !cachedDevice.isBusy,
alpha =
- if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
- else BluetoothTileDialog.ENABLED_ALPHA,
+ if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
+ else BluetoothTileDialog.ENABLED_ALPHA,
)
}
}
@@ -108,15 +107,15 @@ internal class SavedDeviceItemFactory : DeviceItemFactory() {
cachedBluetoothDevice = cachedDevice,
deviceName = cachedDevice.name,
connectionSummary = cachedDevice.connectionSummary.takeUnless { it.isNullOrEmpty() }
- ?: context.getString(saved),
+ ?: context.getString(saved),
iconWithDescription =
- BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
- Pair(p.first, p.second)
- },
+ BluetoothUtils.getBtClassDrawableWithDescription(context, cachedDevice).let { p ->
+ Pair(p.first, p.second)
+ },
isEnabled = !cachedDevice.isBusy,
alpha =
- if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
- else BluetoothTileDialog.ENABLED_ALPHA,
+ if (cachedDevice.isBusy) BluetoothTileDialog.DISABLED_ALPHA
+ else BluetoothTileDialog.ENABLED_ALPHA,
)
}
}
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 6ffb61439c0c..fcd0ce6807fd 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
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.media.AudioManager
+import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.BluetoothCallback
import com.android.settingslib.bluetooth.BluetoothUtils
import com.android.settingslib.bluetooth.CachedBluetoothDevice
@@ -49,6 +50,7 @@ constructor(
private val audioManager: AudioManager,
private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter(),
private val localBluetoothManager: LocalBluetoothManager?,
+ private val uiEventLogger: UiEventLogger,
@Application private val coroutineScope: CoroutineScope,
@Background private val backgroundDispatcher: CoroutineDispatcher,
) {
@@ -147,12 +149,14 @@ constructor(
DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
if (!BluetoothUtils.isActiveMediaDevice(deviceItem.cachedBluetoothDevice)) {
deviceItem.cachedBluetoothDevice.setActive()
+ uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_DEVICE_SET_ACTIVE)
isClicked = true
}
}
DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {}
DeviceItemType.SAVED_BLUETOOTH_DEVICE -> {
deviceItem.cachedBluetoothDevice.connect()
+ uiEventLogger.log(BluetoothTileDialogUiEvent.SAVED_DEVICE_CONNECT)
isClicked = true
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
index e1d177db2322..89fa55b319ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/bluetooth/BluetoothTileDialogTest.kt
@@ -26,6 +26,7 @@ import android.view.View.VISIBLE
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.systemui.SysuiTestCase
import com.android.systemui.qs.tiles.dialog.bluetooth.BluetoothTileDialog.Companion.DISABLED_ALPHA
@@ -59,13 +60,16 @@ class BluetoothTileDialogTest : SysuiTestCase() {
@Mock private lateinit var drawable: Drawable
+ @Mock private lateinit var uiEventLogger: UiEventLogger
+
private lateinit var icon: Pair<Drawable, String>
private lateinit var bluetoothTileDialog: BluetoothTileDialog
private lateinit var deviceItem: DeviceItem
@Before
fun setUp() {
- bluetoothTileDialog = BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext)
+ bluetoothTileDialog =
+ BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
icon = Pair(drawable, DEVICE_NAME)
deviceItem =
DeviceItem(
@@ -83,7 +87,7 @@ class BluetoothTileDialogTest : SysuiTestCase() {
fun testShowDialog_createRecyclerViewWithAdapter() {
bluetoothTileDialog.show()
- val recyclerView = bluetoothTileDialog.findViewById<RecyclerView>(R.id.device_list)
+ val recyclerView = bluetoothTileDialog.requireViewById<RecyclerView>(R.id.device_list)
assertThat(bluetoothTileDialog.isShowing).isTrue()
assertThat(recyclerView).isNotNull()
@@ -94,11 +98,16 @@ class BluetoothTileDialogTest : SysuiTestCase() {
@Test
fun testShowDialog_displayBluetoothDevice() {
- bluetoothTileDialog = BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext)
+ bluetoothTileDialog =
+ BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
bluetoothTileDialog.show()
- bluetoothTileDialog.onDeviceItemUpdated(listOf(deviceItem), false)
+ bluetoothTileDialog.onDeviceItemUpdated(
+ listOf(deviceItem),
+ showSeeAll = false,
+ showPairNewDevice = false
+ )
- val recyclerView = bluetoothTileDialog.findViewById<RecyclerView>(R.id.device_list)
+ val recyclerView = bluetoothTileDialog.requireViewById<RecyclerView>(R.id.device_list)
val adapter = recyclerView?.adapter as BluetoothTileDialog.Adapter
assertThat(adapter.itemCount).isEqualTo(1)
assertThat(adapter.getItem(0).deviceName).isEqualTo(DEVICE_NAME)
@@ -114,16 +123,17 @@ class BluetoothTileDialogTest : SysuiTestCase() {
val view =
LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
val viewHolder =
- BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext)
- .Adapter()
+ BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
+ .Adapter(bluetoothTileDialogCallback)
.DeviceItemViewHolder(view)
- viewHolder.bind(deviceItem, 0)
- val container = view.findViewById<View>(R.id.bluetooth_device)
+ viewHolder.bind(deviceItem, 0, bluetoothTileDialogCallback)
+ val container = view.requireViewById<View>(R.id.bluetooth_device)
+ val deviceView = view.requireViewById<View>(R.id.bluetooth_device)
assertThat(container).isNotNull()
- assertThat(container!!.isEnabled).isTrue()
+ assertThat(container.isEnabled).isTrue()
assertThat(container.alpha).isEqualTo(ENABLED_ALPHA)
- assertThat(container.hasOnClickListeners()).isTrue()
+ assertThat(deviceView.hasOnClickListeners()).isTrue()
}
@Test
@@ -134,30 +144,40 @@ class BluetoothTileDialogTest : SysuiTestCase() {
val view =
LayoutInflater.from(mContext).inflate(R.layout.bluetooth_device_item, null, false)
val viewHolder =
- BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext)
- .Adapter()
+ BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
+ .Adapter(bluetoothTileDialogCallback)
.DeviceItemViewHolder(view)
- viewHolder.bind(deviceItem, 0)
- val container = view.findViewById<View>(R.id.bluetooth_device)
+ viewHolder.bind(deviceItem, 0, bluetoothTileDialogCallback)
+ val container = view.requireViewById<View>(R.id.bluetooth_device_row)
+ val deviceView = view.requireViewById<View>(R.id.bluetooth_device)
assertThat(container).isNotNull()
- assertThat(container!!.isEnabled).isFalse()
+ assertThat(container.isEnabled).isFalse()
assertThat(container.alpha).isEqualTo(DISABLED_ALPHA)
- assertThat(container.hasOnClickListeners()).isTrue()
+ assertThat(deviceView.hasOnClickListeners()).isTrue()
}
@Test
- fun testOnDeviceUpdated_hideSeeAll() {
- bluetoothTileDialog = BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, mContext)
+ fun testOnDeviceUpdated_hideSeeAll_showPairNew() {
+ bluetoothTileDialog =
+ BluetoothTileDialog(ENABLED, bluetoothTileDialogCallback, uiEventLogger, mContext)
bluetoothTileDialog.show()
- bluetoothTileDialog.onDeviceItemUpdated(listOf(deviceItem), false)
-
- val seeAllLayout = bluetoothTileDialog.findViewById<View>(R.id.see_all_layout)
- val recyclerView = bluetoothTileDialog.findViewById<RecyclerView>(R.id.device_list)
+ bluetoothTileDialog.onDeviceItemUpdated(
+ listOf(deviceItem),
+ showSeeAll = false,
+ showPairNewDevice = true
+ )
+
+ val seeAllLayout = bluetoothTileDialog.requireViewById<View>(R.id.see_all_layout_group)
+ val pairNewLayout =
+ bluetoothTileDialog.requireViewById<View>(R.id.pair_new_device_layout_group)
+ val recyclerView = bluetoothTileDialog.requireViewById<RecyclerView>(R.id.device_list)
val adapter = recyclerView?.adapter as BluetoothTileDialog.Adapter
assertThat(seeAllLayout).isNotNull()
- assertThat(seeAllLayout!!.visibility).isEqualTo(GONE)
+ assertThat(seeAllLayout.visibility).isEqualTo(GONE)
+ assertThat(pairNewLayout).isNotNull()
+ assertThat(pairNewLayout.visibility).isEqualTo(VISIBLE)
assertThat(adapter.itemCount).isEqualTo(1)
}
}
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 975f1e25ba9d..7157cce8e607 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
@@ -18,10 +18,14 @@ package com.android.systemui.qs.tiles.dialog.bluetooth
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import android.view.View
import android.widget.LinearLayout
import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.nullable
@@ -38,6 +42,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.never
@@ -61,8 +66,16 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
@Mock private lateinit var deviceItemInteractor: DeviceItemInteractor
+ @Mock private lateinit var activityStarter: ActivityStarter
+
@Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+ @Mock private lateinit var cachedBluetoothDevice: CachedBluetoothDevice
+
+ @Mock private lateinit var deviceItem: DeviceItem
+
+ @Mock private lateinit var uiEventLogger: UiEventLogger
+
private lateinit var scheduler: TestCoroutineScheduler
private lateinit var dispatcher: CoroutineDispatcher
private lateinit var testScope: TestScope
@@ -77,6 +90,8 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
deviceItemInteractor,
bluetoothStateInteractor,
dialogLaunchAnimator,
+ activityStarter,
+ uiEventLogger,
testScope.backgroundScope,
dispatcher,
)
@@ -96,6 +111,7 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
assertThat(bluetoothTileDialogViewModel.dialog).isNotNull()
verify(dialogLaunchAnimator, never()).showFromView(any(), any(), any(), any())
assertThat(bluetoothTileDialogViewModel.dialog?.isShowing).isTrue()
+ verify(uiEventLogger).log(BluetoothTileDialogUiEvent.BLUETOOTH_TILE_DIALOG_SHOWN)
}
}
@@ -140,4 +156,16 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
verify(bluetoothStateInteractor).updateBluetoothStateFlow
}
}
+
+ @Test
+ fun testStartSettingsActivity_activityLaunched_dialogDismissed() {
+ `when`(deviceItem.cachedBluetoothDevice).thenReturn(cachedBluetoothDevice)
+ bluetoothTileDialogViewModel.showDialog(context, null)
+
+ val clickedView = View(context)
+ bluetoothTileDialogViewModel.onPairNewDeviceClicked(clickedView)
+
+ verify(uiEventLogger).log(BluetoothTileDialogUiEvent.PAIR_NEW_DEVICE_CLICKED)
+ verify(activityStarter).postStartActivityDismissingKeyguard(any(), anyInt(), nullable())
+ }
}
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 df9914a8d012..07a95ae330c6 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
@@ -23,6 +23,7 @@ import android.media.AudioManager
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
import com.android.settingslib.bluetooth.CachedBluetoothDevice
import com.android.settingslib.bluetooth.LocalBluetoothManager
import com.android.systemui.SysuiTestCase
@@ -67,6 +68,8 @@ class DeviceItemInteractorTest : SysuiTestCase() {
@Mock private lateinit var localBluetoothManager: LocalBluetoothManager
+ @Mock private lateinit var uiEventLogger: UiEventLogger
+
private lateinit var interactor: DeviceItemInteractor
private lateinit var dispatcher: CoroutineDispatcher
@@ -83,6 +86,7 @@ class DeviceItemInteractorTest : SysuiTestCase() {
audioManager,
adapter,
localBluetoothManager,
+ uiEventLogger,
testScope.backgroundScope,
dispatcher
)