Apply Dovetail 1.1 spec to AppError & ANR dialogs
1. Define a layout xml for BaseErrorDialog reflecting the UX spec.
2. Create a style for BaseErrorDialog extending AlertDialog's Style and apply the layout.
3. Apply the BaseErrorDialog style to the BaseErrorDialog theme.
4. Customize AppError & ANR dialog layouts.
screenshot: https://hsv.googleplex.com/4841930417504256
Bug: 230314100
Test: Manual test
Change-Id: Id14aa0b0c1507fd61c29bb38ab6b4a72850f0d85
(cherry picked from commit b96bf9f96547f1f7bc13d0f480285ec42c725a4f)
(cherry picked from commit e4b605add5e56a8480aef6ca699e28da7baab2eb)
diff --git a/core/res/res/layout-watch/app_anr_dialog.xml b/core/res/res/layout-watch/app_anr_dialog.xml
new file mode 100644
index 0000000..f9605af
--- /dev/null
+++ b/core/res/res/layout-watch/app_anr_dialog.xml
@@ -0,0 +1,44 @@
+<?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="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:showDividers="middle"
+ android:divider="@drawable/global_action_item_divider">
+ <Button
+ android:id="@+id/aerr_close"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_close_app"
+ android:drawableStart="@drawable/ic_close"
+ style="@style/aerr_list_item"/>
+ <Button
+ android:id="@+id/aerr_wait"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_wait"
+ android:drawableStart="@drawable/ic_schedule"
+ style="@style/aerr_list_item"/>
+ <Button
+ android:id="@+id/aerr_report"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_report"
+ android:drawableStart="@drawable/ic_feedback"
+ style="@style/aerr_list_item"/>
+</LinearLayout>
diff --git a/core/res/res/layout-watch/app_error_dialog.xml b/core/res/res/layout-watch/app_error_dialog.xml
new file mode 100644
index 0000000..8857b5f
--- /dev/null
+++ b/core/res/res/layout-watch/app_error_dialog.xml
@@ -0,0 +1,58 @@
+<?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="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:showDividers="middle"
+ android:divider="@drawable/global_action_item_divider">
+ <Button
+ android:id="@+id/aerr_restart"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_restart"
+ android:drawableStart="@drawable/ic_refresh"
+ style="@style/aerr_list_item" />
+ <Button
+ android:id="@+id/aerr_app_info"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/app_info"
+ android:drawableStart="@drawable/ic_info_outline_24"
+ style="@style/aerr_list_item" />
+ <Button
+ android:id="@+id/aerr_close"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_close_app"
+ android:drawableStart="@drawable/ic_close"
+ style="@style/aerr_list_item" />
+ <Button
+ android:id="@+id/aerr_report"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_report"
+ android:drawableStart="@drawable/ic_feedback"
+ style="@style/aerr_list_item" />
+ <Button
+ android:id="@+id/aerr_mute"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/aerr_mute"
+ android:drawableStart="@drawable/ic_eject_24dp"
+ style="@style/aerr_list_item" />
+</LinearLayout>
diff --git a/core/res/res/layout-watch/watch_base_error_dialog.xml b/core/res/res/layout-watch/watch_base_error_dialog.xml
new file mode 100644
index 0000000..0f3fb42
--- /dev/null
+++ b/core/res/res/layout-watch/watch_base_error_dialog.xml
@@ -0,0 +1,114 @@
+<?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.
+ -->
+<com.android.internal.widget.WatchListDecorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/parentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ScrollView
+ android:id="@+id/scrollView"
+ android:fillViewport="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="?dialogPreferredPadding"
+ android:paddingRight="?dialogPreferredPadding"
+ android:paddingTop="@dimen/base_error_dialog_top_padding"
+ android:paddingBottom="@dimen/base_error_dialog_bottom_padding"
+ android:orientation="vertical" >
+ <!-- Top Panel -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/topPanel">
+ <include android:id="@+id/title_template"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ layout="@layout/watch_base_error_dialog_title"/>
+ </FrameLayout>
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="16dp">
+ </FrameLayout>
+ <!-- Content Panel -->
+ <FrameLayout
+ android:id="@+id/contentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false">
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal|top"
+ android:textAppearance="@style/TextAppearance.DeviceDefault.Body1"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"/>
+ </FrameLayout>
+ <!-- Custom Panel, to replace content panel if needed -->
+ <FrameLayout
+ android:id="@+id/customPanel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:minHeight="64dp">
+ <FrameLayout
+ android:id="@+android:id/custom"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </FrameLayout>
+
+ <!-- Button Panel -->
+ <FrameLayout
+ android:id="@+id/buttonPanel"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:orientation="vertical"
+ style="?android:attr/buttonBarStyle"
+ android:measureWithLargestChild="true">
+ <Button
+ android:id="@+id/button1"
+ android:layout_gravity="start"
+ android:layout_weight="1"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <Button
+ android:id="@+id/button3"
+ android:layout_gravity="start"
+ android:layout_weight="1"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <Button
+ android:id="@+id/button2"
+ android:layout_gravity="start"
+ android:layout_weight="1"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+ </FrameLayout>
+ </LinearLayout>
+ </ScrollView>
+</com.android.internal.widget.WatchListDecorLayout>
diff --git a/core/res/res/layout-watch/watch_base_error_dialog_title.xml b/core/res/res/layout-watch/watch_base_error_dialog_title.xml
new file mode 100644
index 0000000..aa14c08
--- /dev/null
+++ b/core/res/res/layout-watch/watch_base_error_dialog_title.xml
@@ -0,0 +1,47 @@
+<?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="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/base_error_dialog_contents_padding"
+ android:paddingRight="@dimen/base_error_dialog_contents_padding"
+ android:orientation="vertical"
+ android:gravity="top|center_horizontal">
+ <FrameLayout
+ android:adjustViewBounds="true"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <ImageView
+ android:id="@+id/icon"
+ android:adjustViewBounds="true"
+ android:maxHeight="24dp"
+ android:maxWidth="24dp"
+ android:layout_marginTop="@dimen/screen_percentage_10"
+ android:layout_gravity="center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@null"/>
+ </FrameLayout>
+ <TextView
+ android:id="@+id/alertTitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="38dp"
+ android:textAppearance="@style/TextAppearance.Watch.BaseErrorDialog.Title"
+ android:maxLines="3"
+ android:gravity="center_horizontal|top"/>
+</LinearLayout>
diff --git a/core/res/res/values-w180dp-notround-watch/dimens.xml b/core/res/res/values-w180dp-notround-watch/dimens.xml
new file mode 100644
index 0000000..5887661
--- /dev/null
+++ b/core/res/res/values-w180dp-notround-watch/dimens.xml
@@ -0,0 +1,24 @@
+<?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.
+ -->
+<resources>
+ <!-- 14.4% of display size -->
+ <dimen name="base_error_dialog_top_padding">26dp</dimen>
+ <!-- 2.8% of display size -->
+ <dimen name="base_error_dialog_padding">5dp</dimen>
+ <!-- 35.56% of display size -->
+ <dimen name="base_error_dialog_bottom_padding">64dp</dimen>
+</resources>
diff --git a/core/res/res/values-w192dp-round-watch/dimens.xml b/core/res/res/values-w192dp-round-watch/dimens.xml
new file mode 100644
index 0000000..5aed20e
--- /dev/null
+++ b/core/res/res/values-w192dp-round-watch/dimens.xml
@@ -0,0 +1,24 @@
+<?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.
+ -->
+<resources>
+ <!-- 16.7% of display size -->
+ <dimen name="base_error_dialog_top_padding">32dp</dimen>
+ <!-- 5.2% of display size -->
+ <dimen name="base_error_dialog_padding">10dp</dimen>
+ <!-- 20.83% of display size -->
+ <dimen name="base_error_dialog_bottom_padding">40dp</dimen>
+</resources>
diff --git a/core/res/res/values-w213dp-round-watch/dimens.xml b/core/res/res/values-w213dp-round-watch/dimens.xml
new file mode 100644
index 0000000..27fff75
--- /dev/null
+++ b/core/res/res/values-w213dp-round-watch/dimens.xml
@@ -0,0 +1,24 @@
+<?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.
+ -->
+<resources>
+ <!-- 16.7% of display size -->
+ <dimen name="base_error_dialog_top_padding">36dp</dimen>
+ <!-- 5.2% of display size -->
+ <dimen name="base_error_dialog_padding">11dp</dimen>
+ <!-- 36.46% of display size -->
+ <dimen name="base_error_dialog_bottom_padding">78dp</dimen>
+</resources>
diff --git a/core/res/res/values-watch/dimens.xml b/core/res/res/values-watch/dimens.xml
index 5472316..c7caa39 100644
--- a/core/res/res/values-watch/dimens.xml
+++ b/core/res/res/values-watch/dimens.xml
@@ -20,4 +20,9 @@
<dimen name="alert_dialog_button_bar_height">0dp</dimen>
<dimen name="toast_y_offset">0dip</dimen>
+
+ <!-- AppErrorDialog's list item height -->
+ <dimen name="aerr_list_item_height">52dp</dimen>
+ <!-- Padding for contents in a view of BaseErrorDialog such as a title and buttons -->
+ <dimen name="base_error_dialog_contents_padding">14dp</dimen>
</resources>
diff --git a/core/res/res/values-watch/styles.xml b/core/res/res/values-watch/styles.xml
index 3172f73..6e84f39 100644
--- a/core/res/res/values-watch/styles.xml
+++ b/core/res/res/values-watch/styles.xml
@@ -19,4 +19,43 @@
<item name="fontFamily">sans-serif-regular</item>
<item name="textSize">13sp</item>
</style>
+
+ <!-- @hide -->
+ <style name="TextAppearance.Watch"/>
+
+ <!-- @hide -->
+ <style name="TextAppearance.Watch.BaseErrorDialog">
+ <item name="fontFamily">google-sans-text-medium</item>
+ <item name="textColor">@android:color/white</item>
+ <item name="textAllCaps">false</item>
+ </style>
+
+ <!-- @hide -->
+ <style name="TextAppearance.Watch.BaseErrorDialog.Title">
+ <item name="textSize">16sp</item>
+ <item name="letterSpacing">0.024</item>
+ </style>
+
+ <!-- @hide -->
+ <style name="TextAppearance.Watch.AppErrorDialog"
+ parent="TextAppearance.Watch.BaseErrorDialog"/>
+
+ <!-- @hide -->
+ <style name="TextAppearance.Watch.AppErrorDialog.Item">
+ <item name="textSize">15sp</item>
+ <item name="letterSpacing">0.01</item>
+ </style>
+
+ <!-- @hide -->
+ <style name="aerr_list_item">
+ <item name="minHeight">@dimen/aerr_list_item_height</item>
+ <item name="textAppearance">@style/TextAppearance.Watch.AppErrorDialog.Item</item>
+ <item name="gravity">center_vertical</item>
+ <item name="paddingStart">@dimen/base_error_dialog_contents_padding</item>
+ <item name="paddingEnd">@dimen/base_error_dialog_contents_padding</item>
+ <item name="background">@drawable/global_actions_item_grey_background</item>
+ <item name="drawablePadding">6dp</item>
+ <item name="drawableTint">@android:color/white</item>
+ <item name="drawableTintMode">src_atop</item>
+ </style>
</resources>
diff --git a/core/res/res/values-watch/styles_device_default.xml b/core/res/res/values-watch/styles_device_default.xml
index e2261af..8a2ce5d 100644
--- a/core/res/res/values-watch/styles_device_default.xml
+++ b/core/res/res/values-watch/styles_device_default.xml
@@ -34,4 +34,7 @@
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">google-sans-medium</item>
</style>
+ <style name="BaseErrorDialog.DeviceDefault" parent="AlertDialog.DeviceDefault">
+ <item name="layout">@layout/watch_base_error_dialog</item>
+ </style>
</resources>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index 1db006f..c4c1ed9 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -427,6 +427,8 @@
<!-- Theme for the dialog shown when an app crashes or ANRs. Override to make it dark. -->
<style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert">
+ <item name="alertDialogStyle">@style/BaseErrorDialog.DeviceDefault</item>
+ <item name="dialogPreferredPadding">@dimen/base_error_dialog_padding</item>
<item name="windowContentTransitions">false</item>
<item name="windowActivityTransitions">false</item>
<item name="windowCloseOnTouchOutside">false</item>