Beautifies picker disabled dialogs (2/2).
Makes the dialog look like its spec.
Fix: 262773261
Test: https://screenshot.googleplex.com/6vukXFZHgDdQW7X
Change-Id: Ic4acf5bf8d7a28cfd4c2cec9b82ee1c85550c056
diff --git a/res/drawable/button_background.xml b/res/drawable/button_background.xml
new file mode 100644
index 0000000..24c7253
--- /dev/null
+++ b/res/drawable/button_background.xml
@@ -0,0 +1,20 @@
+<!--
+ Copyright (C) 2021 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="50dp" />
+ <solid android:color="@color/color_accent_primary" />
+</shape>
diff --git a/res/layout/keyguard_quick_affordance_enablement_dialog.xml b/res/layout/keyguard_quick_affordance_enablement_dialog.xml
new file mode 100644
index 0000000..d6ba105
--- /dev/null
+++ b/res/layout/keyguard_quick_affordance_enablement_dialog.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2022 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.
+ ~
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@drawable/keyguard_quick_affordance_picker_background"
+ android:orientation="vertical"
+ android:padding="24dp">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:tint="@color/color_accent_primary"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="16dp" />
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="16dp" />
+
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginBottom="38dp" />
+
+ <Button
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/ActionPrimaryButton"
+ android:background="@drawable/button_background"
+ android:layout_gravity="end" />
+
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 63fb560..13fc8a0 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -294,7 +294,7 @@
enabled. The dialog contains a list of instructions that the user needs to take in order to
enable the option before it can be selected again. [CHAR LIMIT=NONE].
-->
- <string name="keyguard_affordance_enablement_dialog_title">Additional setup needed</string>
+ <string name="keyguard_affordance_enablement_dialog_title">To select `<xliff:g id="appName" example="Wallet">%1$s</xliff:g>` check the following</string>
<!--
Template for an action that opens a specific app. [CHAR LIMIT=16]
diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt
new file mode 100644
index 0000000..809e09d
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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.customization.picker.quickaffordance.ui.binder
+
+import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
+import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
+import com.android.wallpaper.R
+
+object KeyguardQuickAffordanceEnablementDialogBinder {
+
+ fun bind(
+ view: View,
+ viewModel: KeyguardQuickAffordancePickerViewModel.DialogViewModel,
+ onDismissed: () -> Unit,
+ ) {
+ view.requireViewById<ImageView>(R.id.icon).setImageDrawable(viewModel.icon)
+ view.requireViewById<TextView>(R.id.title).text =
+ view.context.getString(
+ R.string.keyguard_affordance_enablement_dialog_title,
+ viewModel.name
+ )
+ view.requireViewById<TextView>(R.id.message).text = buildString {
+ viewModel.instructions.forEachIndexed { index, instruction ->
+ append(instruction)
+ if (index < viewModel.instructions.size - 1) {
+ append("\n")
+ }
+ }
+ }
+ view.requireViewById<TextView>(R.id.button).apply {
+ text = viewModel.actionText
+ setOnClickListener {
+ if (viewModel.intent != null) {
+ view.context.startActivity(viewModel.intent)
+ } else {
+ onDismissed()
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt
index 62f2e26..389f8f6 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt
@@ -20,8 +20,8 @@
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
-import android.content.DialogInterface
import android.graphics.Rect
+import android.view.LayoutInflater
import android.view.View
import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
@@ -88,7 +88,6 @@
onDismissed = viewModel::onDialogDismissed
)
} else {
- dialog?.dismiss()
null
}
}
@@ -102,34 +101,21 @@
request: KeyguardQuickAffordancePickerViewModel.DialogViewModel,
onDismissed: () -> Unit,
): Dialog {
- // TODO(b/254858701): make this dialog prettier and probably use a DialogFragment.
- return AlertDialog.Builder(context, context.themeResId)
- .setTitle(context.getString(R.string.keyguard_affordance_enablement_dialog_title))
- .setMessage(
- buildString {
- append(request.instructionHeader)
- if (request.instructions.isNotEmpty()) {
- append("\n")
- }
- request.instructions.forEachIndexed { index, instruction ->
- append(instruction)
- if (index < request.instructions.size - 1) {
- append("\n")
- }
- }
- }
- )
- .setOnDismissListener { onDismissed.invoke() }
- .setPositiveButton(
- request.actionText,
- if (request.intent != null) {
- DialogInterface.OnClickListener { _, _ ->
- context.startActivity(request.intent)
- }
- } else {
- DialogInterface.OnClickListener { _, _ -> onDismissed() }
- },
- )
+ val view: View =
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.keyguard_quick_affordance_enablement_dialog,
+ null,
+ )
+ KeyguardQuickAffordanceEnablementDialogBinder.bind(
+ view = view,
+ viewModel = request,
+ onDismissed = onDismissed,
+ )
+
+ return AlertDialog.Builder(context, R.style.LightDialogTheme)
+ .setView(view)
+ .setOnDismissListener { onDismissed() }
.show()
}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
index f87c099..e0e5ca8 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
@@ -167,8 +167,9 @@
) +
affordances.map { affordance ->
val isSelected = selectedAffordanceIds.contains(affordance.id)
+ val affordanceIcon = getAffordanceIcon(affordance.iconResourceId)
KeyguardQuickAffordanceViewModel(
- icon = getAffordanceIcon(affordance.iconResourceId),
+ icon = affordanceIcon,
contentDescription = affordance.name,
isSelected = isSelected,
onClicked =
@@ -191,13 +192,9 @@
} else {
{
showEnablementDialog(
- instructionHeader =
- affordance.enablementInstructions.first(),
- instructions =
- affordance.enablementInstructions.subList(
- 1,
- affordance.enablementInstructions.size
- ),
+ icon = affordanceIcon,
+ name = affordance.name,
+ instructions = affordance.enablementInstructions,
actionText = affordance.enablementActionText,
actionComponentName =
affordance.enablementActionComponentName,
@@ -249,14 +246,16 @@
}
private fun showEnablementDialog(
- instructionHeader: String,
+ icon: Drawable,
+ name: String,
instructions: List<String>,
actionText: String?,
actionComponentName: String?,
) {
_dialog.value =
DialogViewModel(
- instructionHeader = instructionHeader,
+ icon = icon,
+ name = name,
instructions = instructions,
actionText = actionText
?: applicationContext.getString(
@@ -317,8 +316,11 @@
/** Encapsulates a request to show a dialog. */
data class DialogViewModel(
- /** The header for the instructions section. */
- val instructionHeader: String,
+ /** An icon to show. */
+ val icon: Drawable,
+
+ /** Name of the affordance. */
+ val name: String,
/** The set of instructions to show below the header. */
val instructions: List<String>,
diff --git a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
index 9c3e87c..6706f17 100644
--- a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
+++ b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
@@ -233,7 +233,7 @@
val quickAffordances = collectLastValue(underTest.quickAffordances)
val dialog = collectLastValue(underTest.dialog)
- val enablementInstructions = listOf("header", "enablementInstructions")
+ val enablementInstructions = listOf("instruction1", "instruction2")
val enablementActionText = "enablementActionText"
val packageName = "packageName"
val action = "action"
@@ -244,7 +244,7 @@
KeyguardQuickAffordanceProviderClient.Affordance(
id = "disabled",
name = "disabled",
- iconResourceId = 0,
+ iconResourceId = 1,
isEnabled = false,
enablementInstructions = enablementInstructions,
enablementActionText = enablementActionText,
@@ -256,9 +256,8 @@
quickAffordances()?.get(affordanceIndex + 1)?.onClicked?.invoke()
// We expect there to be a dialog that should be shown:
- assertThat(dialog()?.instructionHeader).isEqualTo(enablementInstructions[0])
- assertThat(dialog()?.instructions)
- .isEqualTo(enablementInstructions.subList(1, enablementInstructions.size))
+ assertThat(dialog()?.icon).isEqualTo(FakeKeyguardQuickAffordanceProviderClient.ICON_1)
+ assertThat(dialog()?.instructions).isEqualTo(enablementInstructions)
assertThat(dialog()?.actionText).isEqualTo(enablementActionText)
assertThat(dialog()?.intent?.`package`).isEqualTo(packageName)
assertThat(dialog()?.intent?.action).isEqualTo(action)