Merge "Show "Done" button to prevent user from getting stuck"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 787c559..fd0fc6c 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -2,18 +2,6 @@
<issues format="4">
<issue
- id="LintError"
- severity="Error"
- message="No `.class` files were found in project ".", so none of the classfile based checks could be run. Does the project need to be built first?"
- category="Lint"
- priority="10"
- summary="Lint Failure"
- explanation="This issue type represents a problem running lint itself. Examples include failure to find bytecode for source files (which means certain detectors could not be run), parsing errors in lint configuration files, etc.
These errors are not errors in your own code, but they are shown to make it clear that some checks were not completed.">
- <location
- file="."/>
- </issue>
-
- <issue
id="HardCodedColor"
severity="Error"
message="Avoid using hardcoded color"
@@ -1301,6 +1289,54 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <color name="qr_corner_line_color">#ffdadce0</color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="133"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <color name="qr_focused_corner_line_color">#ff1a73e8</color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="134"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <color name="qr_background_color">#b3ffffff</color> <!-- 70% white transparency -->"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="135"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:background="@color/lock_pattern_background" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -2441,7 +2477,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/strings.xml"
- line="5805"
+ line="5883"
column="36"/>
</issue>
@@ -2473,7 +2509,7 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="425"
+ line="415"
column="44"/>
</issue>
@@ -2489,7 +2525,7 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="431"
+ line="421"
column="44"/>
</issue>
@@ -2505,7 +2541,7 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="432"
+ line="422"
column="44"/>
</issue>
@@ -2521,23 +2557,7 @@
errorLine2=" ^">
<location
file="res/values/styles.xml"
- line="467"
- column="34"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" <item name="strokeColor">@color/homepage_card_stroke_color</item>"
- errorLine2=" ^">
- <location
- file="res/values/styles.xml"
- line="474"
+ line="457"
column="34"/>
</issue>
@@ -2553,7 +2573,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="54"
+ line="57"
column="39"/>
</issue>
@@ -2569,7 +2589,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="55"
+ line="58"
column="40"/>
</issue>
@@ -2585,7 +2605,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="56"
+ line="59"
column="38"/>
</issue>
@@ -2601,7 +2621,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="90"
+ line="97"
column="47"/>
</issue>
@@ -2617,7 +2637,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="90"
+ line="97"
column="47"/>
</issue>
@@ -2633,7 +2653,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="96"
+ line="103"
column="40"/>
</issue>
@@ -2649,7 +2669,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="96"
+ line="103"
column="40"/>
</issue>
@@ -2665,7 +2685,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="159"
+ line="166"
column="45"/>
</issue>
@@ -2681,7 +2701,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="160"
+ line="167"
column="49"/>
</issue>
@@ -2697,7 +2717,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="168"
+ line="175"
column="45"/>
</issue>
@@ -2713,7 +2733,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="169"
+ line="176"
column="49"/>
</issue>
@@ -2729,7 +2749,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="185"
+ line="192"
column="39"/>
</issue>
@@ -2745,7 +2765,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="186"
+ line="193"
column="40"/>
</issue>
@@ -2761,7 +2781,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="187"
+ line="194"
column="38"/>
</issue>
diff --git a/res/layout-land/choose_lock_pattern.xml b/res/layout-land/choose_lock_pattern.xml
index 25230cb..d2d436f 100644
--- a/res/layout-land/choose_lock_pattern.xml
+++ b/res/layout-land/choose_lock_pattern.xml
@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
- android:layout="@layout/suw_glif_blank_template"
+ android:layout="@layout/sud_glif_blank_template"
settings:suwHeaderText="@string/lock_settings_picker_title">
<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
diff --git a/res/layout-land/confirm_lock_password.xml b/res/layout-land/confirm_lock_password.xml
index a6a85d3..d140bad 100644
--- a/res/layout-land/confirm_lock_password.xml
+++ b/res/layout-land/confirm_lock_password.xml
@@ -28,7 +28,7 @@
android:layout_height="match_parent">
<TextView
- style="@android:style/TextAppearance.Material.Title"
+ style="@*android:style/TextAppearance.DeviceDefault.Title"
android:id="@+id/headerText"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
@@ -38,7 +38,7 @@
android:textColor="?android:attr/colorAccent"/>
<TextView
- style="@android:style/TextAppearance.Material.Body1"
+ style="@*android:style/TextAppearance.DeviceDefault.Body1"
android:id="@+id/detailsText"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
@@ -78,7 +78,7 @@
android:gravity="center"
style="@style/TextAppearance.PasswordEntry"/>
- <TextView style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
+ <TextView style="@style/TextAppearance.ErrorText"
android:accessibilityLiveRegion="polite"
android:id="@+id/errorText"
android:layout_width="wrap_content"
diff --git a/res/layout-land/confirm_lock_pattern.xml b/res/layout-land/confirm_lock_pattern.xml
index b0a0a96..bcfd907 100644
--- a/res/layout-land/confirm_lock_pattern.xml
+++ b/res/layout-land/confirm_lock_pattern.xml
@@ -37,7 +37,7 @@
android:orientation="vertical">
<TextView
- style="@android:style/TextAppearance.Material.Headline"
+ style="@*android:style/TextAppearance.DeviceDefault.Headline"
android:id="@+id/headerText"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
@@ -46,7 +46,7 @@
android:textColor="?android:attr/colorAccent"/>
<TextView
- style="@android:style/TextAppearance.Material.Body1"
+ style="@*android:style/TextAppearance.DeviceDefault.Body1"
android:id="@+id/detailsText"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
@@ -94,7 +94,7 @@
android:layout_gravity="center_vertical"/>
<TextView
- style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
+ style="@style/TextAppearance.ErrorText"
android:accessibilityLiveRegion="polite"
android:id="@+id/errorText"
android:layout_width="wrap_content"
@@ -111,4 +111,4 @@
</LinearLayout>
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
diff --git a/res/layout-land/confirm_lock_pattern_normal.xml b/res/layout-land/confirm_lock_pattern_normal.xml
index 23e5d66..993a84e 100644
--- a/res/layout-land/confirm_lock_pattern_normal.xml
+++ b/res/layout-land/confirm_lock_pattern_normal.xml
@@ -19,7 +19,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
- android:layout="@layout/suw_glif_blank_template">
+ android:layout="@layout/sud_glif_blank_template">
<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
android:id="@+id/topLayout"
@@ -76,7 +76,7 @@
android:layout_weight="1" />
<TextView
- style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
+ style="@style/TextAppearance.ErrorText"
android:accessibilityLiveRegion="polite"
android:id="@+id/errorText"
android:layout_width="wrap_content"
diff --git a/res/layout-land/fingerprint_enroll_enrolling.xml b/res/layout-land/fingerprint_enroll_enrolling.xml
index eb32602..e71725e 100644
--- a/res/layout-land/fingerprint_enroll_enrolling.xml
+++ b/res/layout-land/fingerprint_enroll_enrolling.xml
@@ -20,7 +20,7 @@
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout="@layout/suw_glif_blank_template"
+ android:layout="@layout/sud_glif_blank_template"
style="?attr/fingerprint_layout_theme">
<ScrollView
@@ -123,7 +123,7 @@
</com.google.android.setupdesign.view.FillContentLayout>
<TextView
- style="@style/TextAppearance.FingerprintErrorText"
+ style="@style/TextAppearance.ErrorText"
android:id="@+id/error_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout-land/fingerprint_enroll_find_sensor.xml b/res/layout-land/fingerprint_enroll_find_sensor.xml
index e6a2e66..0decbf2 100644
--- a/res/layout-land/fingerprint_enroll_find_sensor.xml
+++ b/res/layout-land/fingerprint_enroll_find_sensor.xml
@@ -20,7 +20,7 @@
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout="@layout/suw_glif_blank_template"
+ android:layout="@layout/sud_glif_blank_template"
style="?attr/fingerprint_layout_theme">
<LinearLayout
diff --git a/res/layout-land/fingerprint_enroll_finish.xml b/res/layout-land/fingerprint_enroll_finish.xml
index 97a4de2..53e430e 100644
--- a/res/layout-land/fingerprint_enroll_finish.xml
+++ b/res/layout-land/fingerprint_enroll_finish.xml
@@ -20,7 +20,7 @@
android:id="@+id/setup_wizard_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout="@layout/suw_glif_blank_template"
+ android:layout="@layout/sud_glif_blank_template"
style="?attr/fingerprint_layout_theme">
<ScrollView
diff --git a/res/layout-land/storage_summary_donut.xml b/res/layout-land/storage_summary_donut.xml
index 5fe4cc8..f43737a 100644
--- a/res/layout-land/storage_summary_donut.xml
+++ b/res/layout-land/storage_summary_donut.xml
@@ -42,7 +42,7 @@
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Display1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1"
android:textSize="36sp" />
<TextView
@@ -54,7 +54,7 @@
android:maxLines="10"
android:paddingBottom="20dp"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" />
<Button
android:id="@+id/deletion_helper_button"
diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
index 4217867..21df686 100644
--- a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
@@ -25,8 +25,8 @@
<include layout="@layout/wifi_dpp_fragment_header"/>
<com.android.settings.wifi.qrcode.QrPreviewLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_width="@dimen/qrcode_preview_size"
+ android:layout_height="@dimen/qrcode_preview_size"
android:layout_gravity="center">
<TextureView
android:id="@+id/preview_view"
diff --git a/res/layout-sw300dp-land/font_size_activity.xml b/res/layout-sw300dp-land/font_size_activity.xml
index 69abac1..6664704 100644
--- a/res/layout-sw300dp-land/font_size_activity.xml
+++ b/res/layout-sw300dp-land/font_size_activity.xml
@@ -56,7 +56,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="6dp"
- android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView"
android:elevation="2dp" />
<com.android.settings.widget.LabeledSeekBar
@@ -102,7 +102,7 @@
android:layout_height="wrap_content"
android:text="@string/font_size_summary"
android:layout_marginBottom="16dp"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
</LinearLayout>
</ScrollView>
</LinearLayout>
diff --git a/res/layout-sw300dp-land/screen_zoom_activity.xml b/res/layout-sw300dp-land/screen_zoom_activity.xml
index 8d6e735..cd7c67c 100644
--- a/res/layout-sw300dp-land/screen_zoom_activity.xml
+++ b/res/layout-sw300dp-land/screen_zoom_activity.xml
@@ -56,7 +56,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="6dp"
- android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView"
android:elevation="2dp" />
<com.android.settings.widget.LabeledSeekBar
@@ -102,7 +102,7 @@
android:layout_height="wrap_content"
android:text="@string/screen_zoom_summary"
android:layout_marginBottom="16dp"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
</LinearLayout>
</ScrollView>
</LinearLayout>
diff --git a/res/layout-sw360dp/homepage_condition_full_tile.xml b/res/layout-sw360dp/homepage_condition_full_tile.xml
new file mode 100644
index 0000000..4a8ad0a
--- /dev/null
+++ b/res/layout-sw360dp/homepage_condition_full_tile.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 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.google.android.material.card.MaterialCardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/ContextualCardStyle">
+
+ <LinearLayout
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="@dimen/homepage_card_padding_start"
+ android:paddingEnd="@dimen/homepage_card_padding_end"
+ android:paddingTop="@dimen/homepage_condition_full_card_padding_top"
+ android:paddingBottom="@dimen/homepage_condition_full_card_padding_bottom"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="@dimen/homepage_card_icon_size"
+ android:layout_height="@dimen/homepage_card_icon_size"
+ android:tint="?android:attr/colorAccent"/>
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingStart="@dimen/homepage_condition_full_card_padding_start"
+ android:paddingEnd="@dimen/homepage_condition_full_card_padding_end"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
+ android:textAppearance="@style/TextAppearance.ConditionCardTitle"/>
+
+ <TextView
+ android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/TextAppearance.ConditionCardSummary"/>
+
+ </LinearLayout>
+
+ <include layout="@layout/vertical_divider"/>
+
+ <Button
+ android:id="@+id/first_action"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/ConditionFullCardBorderlessButton"/>
+
+ </LinearLayout>
+
+</com.google.android.material.card.MaterialCardView>
diff --git a/res/layout-sw360dp/storage_summary_donut.xml b/res/layout-sw360dp/storage_summary_donut.xml
index 5fe4cc8..f43737a 100644
--- a/res/layout-sw360dp/storage_summary_donut.xml
+++ b/res/layout-sw360dp/storage_summary_donut.xml
@@ -42,7 +42,7 @@
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Display1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1"
android:textSize="36sp" />
<TextView
@@ -54,7 +54,7 @@
android:maxLines="10"
android:paddingBottom="20dp"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" />
<Button
android:id="@+id/deletion_helper_button"
diff --git a/res/layout/admin_support_details_dialog.xml b/res/layout/admin_support_details_dialog.xml
index 922451f..66eaf0d 100644
--- a/res/layout/admin_support_details_dialog.xml
+++ b/res/layout/admin_support_details_dialog.xml
@@ -34,7 +34,7 @@
android:layout_height="wrap_content"
android:paddingStart="@dimen/admin_details_dialog_padding"
android:text="@string/disabled_by_policy_title"
- android:textAppearance="@android:style/TextAppearance.Material.Title" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Title" />
</LinearLayout>
<ScrollView
@@ -48,7 +48,7 @@
<TextView android:id="@+id/admin_support_msg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:text="@string/default_admin_support_msg"
android:maxLength="200"
android:autoLink="email|phone|web"
diff --git a/res/layout/battery_header.xml b/res/layout/battery_header.xml
index 9f5bde9..d6ecafa 100644
--- a/res/layout/battery_header.xml
+++ b/res/layout/battery_header.xml
@@ -40,7 +40,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:fontFamily="@*android:string/config_headlineFontFamily"
- android:textAppearance="@android:style/TextAppearance.Material.Display1"/>
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1"/>
<TextView
android:id="@+id/summary1"
@@ -48,13 +48,13 @@
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:minLines="2"
- android:textAppearance="@android:style/TextAppearance.Material.Small"/>
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"/>
<TextView
android:id="@+id/summary2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Small"/>
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"/>
</LinearLayout>
diff --git a/res/layout/bluetooth_pin_confirm.xml b/res/layout/bluetooth_pin_confirm.xml
index 33140d9..c55c9ff 100644
--- a/res/layout/bluetooth_pin_confirm.xml
+++ b/res/layout/bluetooth_pin_confirm.xml
@@ -40,7 +40,7 @@
android:gravity="center_vertical"
android:text="@string/bluetooth_pairing_key_msg"
android:visibility="gone"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="@color/bluetooth_dialog_text_color" />
<TextView
@@ -52,7 +52,7 @@
android:layout_marginBottom="@dimen/bluetooth_dialog_padding"
android:gravity="center_vertical"
android:visibility="gone"
- android:textAppearance="@android:style/TextAppearance.Material.Headline" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Headline" />
<TextView
android:id="@+id/pairing_code_message"
@@ -63,7 +63,7 @@
android:layout_marginBottom="@dimen/bluetooth_dialog_padding"
android:gravity="center_vertical"
android:text="@string/bluetooth_enter_passkey_msg"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="@color/bluetooth_dialog_text_color"
android:visibility="gone" />
@@ -73,7 +73,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/bluetooth_dialog_padding"
android:layout_marginEnd="@dimen/bluetooth_dialog_padding"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="@color/bluetooth_dialog_text_color" />
</LinearLayout>
diff --git a/res/layout/bluetooth_pin_entry.xml b/res/layout/bluetooth_pin_entry.xml
index c309a24..0c6861c 100644
--- a/res/layout/bluetooth_pin_entry.xml
+++ b/res/layout/bluetooth_pin_entry.xml
@@ -60,7 +60,7 @@
android:layout_marginBottom="16dp"
android:gravity="center"
android:paddingStart="@dimen/bluetooth_checkbox_padding"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"/>
<TextView
@@ -71,7 +71,7 @@
android:layout_marginEnd="@dimen/bluetooth_pairing_padding"
android:layout_marginBottom="12dp"
android:gravity="center_vertical"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorSecondary"/>
<CheckBox
@@ -84,7 +84,7 @@
android:gravity="center_vertical"
android:paddingStart="@dimen/bluetooth_checkbox_padding"
android:text="@string/bluetooth_pairing_shares_phonebook"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
diff --git a/res/layout/choose_lock_dialog_item.xml b/res/layout/choose_lock_dialog_item.xml
index 46ad539..f87b7c4 100644
--- a/res/layout/choose_lock_dialog_item.xml
+++ b/res/layout/choose_lock_dialog_item.xml
@@ -26,5 +26,5 @@
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorAlertDialogListItem" />
diff --git a/res/layout/choose_lock_pattern_common.xml b/res/layout/choose_lock_pattern_common.xml
index df7fd8c..6d64b88 100644
--- a/res/layout/choose_lock_pattern_common.xml
+++ b/res/layout/choose_lock_pattern_common.xml
@@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
- android:layout="@layout/suw_glif_blank_template"
+ android:layout="@layout/sud_glif_blank_template"
settings:sucFooter="@layout/choose_lock_pattern_common_footer"
settings:suwHeaderText="@string/lockpassword_choose_your_screen_lock_header">
diff --git a/res/layout/confirm_lock_password_base.xml b/res/layout/confirm_lock_password_base.xml
index 1e42fbe..22934ba 100644
--- a/res/layout/confirm_lock_password_base.xml
+++ b/res/layout/confirm_lock_password_base.xml
@@ -31,7 +31,7 @@
android:paddingTop="@dimen/confirm_credentials_top_padding">
<TextView
- style="@android:style/TextAppearance.Material.Headline"
+ style="@*android:style/TextAppearance.DeviceDefault.Headline"
android:id="@+id/headerText"
android:layout_marginStart="?attr/confirmDeviceCredentialsSideMargin"
android:layout_marginEnd="?attr/confirmDeviceCredentialsSideMargin"
@@ -41,7 +41,7 @@
android:textColor="?android:attr/colorAccent"/>
<TextView
- style="@android:style/TextAppearance.Material.Body1"
+ style="@*android:style/TextAppearance.DeviceDefault.Body1"
android:id="@+id/detailsText"
android:layout_marginStart="?attr/confirmDeviceCredentialsSideMargin"
android:layout_marginEnd="?attr/confirmDeviceCredentialsSideMargin"
@@ -79,7 +79,7 @@
style="@style/TextAppearance.PasswordEntry"/>
<TextView
- style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
+ style="@style/TextAppearance.ErrorText"
android:accessibilityLiveRegion="polite"
android:id="@+id/errorText"
android:layout_width="wrap_content"
diff --git a/res/layout/confirm_lock_password_normal.xml b/res/layout/confirm_lock_password_normal.xml
index 4b92a4a..44d96e0 100644
--- a/res/layout/confirm_lock_password_normal.xml
+++ b/res/layout/confirm_lock_password_normal.xml
@@ -58,7 +58,7 @@
<TextView
android:id="@+id/errorText"
- style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
+ style="@style/TextAppearance.ErrorText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:accessibilityLiveRegion="polite"/>
diff --git a/res/layout/confirm_lock_pattern_base.xml b/res/layout/confirm_lock_pattern_base.xml
index f841391..25fa08f 100644
--- a/res/layout/confirm_lock_pattern_base.xml
+++ b/res/layout/confirm_lock_pattern_base.xml
@@ -40,7 +40,7 @@
android:orientation="vertical">
<TextView
- style="@android:style/TextAppearance.Material.Headline"
+ style="@*android:style/TextAppearance.DeviceDefault.Headline"
android:id="@+id/headerText"
android:layout_marginStart="?attr/confirmDeviceCredentialsSideMargin"
android:layout_marginEnd="?attr/confirmDeviceCredentialsSideMargin"
@@ -50,7 +50,7 @@
android:textColor="?android:attr/colorAccent"/>
<TextView
- style="@android:style/TextAppearance.Material.Body1"
+ style="@*android:style/TextAppearance.DeviceDefault.Body1"
android:id="@+id/detailsText"
android:layout_marginStart="?attr/confirmDeviceCredentialsSideMargin"
android:layout_marginEnd="?attr/confirmDeviceCredentialsSideMargin"
@@ -85,7 +85,7 @@
android:orientation="vertical">
<TextView
- style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
+ style="@style/TextAppearance.ErrorText"
android:accessibilityLiveRegion="polite"
android:id="@+id/errorText"
android:layout_width="wrap_content"
diff --git a/res/layout/confirm_lock_pattern_normal_base.xml b/res/layout/confirm_lock_pattern_normal_base.xml
index 14798df..8cf8f87 100644
--- a/res/layout/confirm_lock_pattern_normal_base.xml
+++ b/res/layout/confirm_lock_pattern_normal_base.xml
@@ -19,7 +19,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_lock"
- android:layout="@layout/suw_glif_blank_template">
+ android:layout="@layout/sud_glif_blank_template">
<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
android:id="@+id/topLayout"
@@ -80,7 +80,7 @@
</com.google.android.setupdesign.view.FillContentLayout>
<TextView
- style="@style/TextAppearance.ConfirmDeviceCredentialsErrorText"
+ style="@style/TextAppearance.ErrorText"
android:accessibilityLiveRegion="polite"
android:id="@+id/errorText"
android:layout_width="wrap_content"
diff --git a/res/layout/data_usage_detail.xml b/res/layout/data_usage_detail.xml
index 5113139..8079fe1 100644
--- a/res/layout/data_usage_detail.xml
+++ b/res/layout/data_usage_detail.xml
@@ -64,14 +64,14 @@
android:singleLine="true"
android:ellipsize="marquee"
android:text="@string/data_usage_label_foreground"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:textAlignment="viewStart" />
<TextView
android:id="@+id/app_foreground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:textAlignment="viewEnd" />
</LinearLayout>
@@ -87,14 +87,14 @@
android:singleLine="true"
android:ellipsize="marquee"
android:text="@string/data_usage_label_background"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:textAlignment="viewStart" />
<TextView
android:id="@+id/app_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:textAlignment="viewEnd" />
</LinearLayout>
diff --git a/res/layout/encryption_interstitial.xml b/res/layout/encryption_interstitial.xml
index ff56a7c..5acc7b1 100644
--- a/res/layout/encryption_interstitial.xml
+++ b/res/layout/encryption_interstitial.xml
@@ -20,8 +20,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:icon="@drawable/ic_lock"
- app:sucFooter="@layout/encryption_interstitial_footer">
+ android:icon="@drawable/ic_lock">
<LinearLayout
style="@style/SuwContentFrame"
diff --git a/res/layout/encryption_interstitial_footer.xml b/res/layout/encryption_interstitial_footer.xml
deleted file mode 100644
index 2f876f3..0000000
--- a/res/layout/encryption_interstitial_footer.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 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.
--->
-
-<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SuwGlifButtonBar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <Button
- android:id="@+id/encrypt_dont_require_password"
- style="@style/SuwGlifButton.Secondary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/encryption_interstitial_no" />
-
- <Space
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1" />
-
- <Button
- android:id="@+id/encrypt_require_password"
- style="@style/SuwGlifButton.Primary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/encryption_interstitial_yes" />
-
-</LinearLayout>
diff --git a/res/layout/face_enroll_enrolling.xml b/res/layout/face_enroll_enrolling.xml
index 7aef9b6..38a26a2 100644
--- a/res/layout/face_enroll_enrolling.xml
+++ b/res/layout/face_enroll_enrolling.xml
@@ -57,7 +57,7 @@
</com.android.settings.biometrics.face.FaceSquareFrameLayout>
<TextView
- style="@style/TextAppearance.FaceErrorText"
+ style="@style/TextAppearance.ErrorText"
android:id="@+id/error_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout/filter_spinner_item.xml b/res/layout/filter_spinner_item.xml
deleted file mode 100644
index ffdd623..0000000
--- a/res/layout/filter_spinner_item.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@android:id/text1"
- style="?android:attr/spinnerItemStyle"
- android:maxLines="1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:ellipsize="marquee"
- android:textColor="?android:attr/colorForegroundInverse"
- android:textAppearance="@style/TextAppearance.Switch"
- android:textAlignment="inherit" />
diff --git a/res/layout/fingerprint_enroll_enrolling_base.xml b/res/layout/fingerprint_enroll_enrolling_base.xml
index 6ca3fdc..4439b08 100644
--- a/res/layout/fingerprint_enroll_enrolling_base.xml
+++ b/res/layout/fingerprint_enroll_enrolling_base.xml
@@ -77,7 +77,7 @@
</com.google.android.setupdesign.view.FillContentLayout>
<TextView
- style="@style/TextAppearance.FingerprintErrorText"
+ style="@style/TextAppearance.ErrorText"
android:id="@+id/error_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout/fingerprint_enroll_finish_base.xml b/res/layout/fingerprint_enroll_finish_base.xml
index 7120d90..1849f51 100644
--- a/res/layout/fingerprint_enroll_finish_base.xml
+++ b/res/layout/fingerprint_enroll_finish_base.xml
@@ -67,7 +67,7 @@
<!-- Added to align elements with fingerprint_enroll_enrolling_base -->
<TextView
- style="@style/TextAppearance.FingerprintErrorText"
+ style="@style/TextAppearance.ErrorText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
diff --git a/res/layout/font_size_activity.xml b/res/layout/font_size_activity.xml
index aa3930c..3e84336 100644
--- a/res/layout/font_size_activity.xml
+++ b/res/layout/font_size_activity.xml
@@ -48,7 +48,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="6dp"
- android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView"
android:elevation="2dp" />
<LinearLayout
@@ -94,7 +94,7 @@
android:layout_height="wrap_content"
android:text="@string/font_size_summary"
android:layout_marginBottom="16dp"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
</LinearLayout>
</LinearLayout>
</ScrollView>
diff --git a/res/layout/font_size_preview.xml b/res/layout/font_size_preview.xml
index d84bb39..669ece0 100644
--- a/res/layout/font_size_preview.xml
+++ b/res/layout/font_size_preview.xml
@@ -36,25 +36,25 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/font_size_preview_text_headline"
- android:textAppearance="@android:style/TextAppearance.Material.Headline"/>
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Headline"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/font_size_preview_text_title"
- android:textAppearance="@android:style/TextAppearance.Material.Title"/>
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Title"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/font_size_preview_text_subtitle"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"/>
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/font_size_preview_text_body"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"/>
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"/>
</LinearLayout>
</view>
</ScrollView>
diff --git a/res/layout/homepage_condition_full_tile.xml b/res/layout/homepage_condition_full_tile.xml
index 4b12625..2de1464 100644
--- a/res/layout/homepage_condition_full_tile.xml
+++ b/res/layout/homepage_condition_full_tile.xml
@@ -25,49 +25,50 @@
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="@dimen/homepage_card_padding_start"
- android:paddingEnd="@dimen/homepage_card_padding_end"
- android:paddingTop="@dimen/homepage_condition_full_card_padding_top"
- android:paddingBottom="@dimen/homepage_condition_full_card_padding_bottom"
- android:orientation="horizontal"
- android:gravity="center_vertical">
-
- <ImageView
- android:id="@android:id/icon"
- android:layout_width="@dimen/homepage_card_icon_size"
- android:layout_height="@dimen/homepage_card_icon_size"
- android:tint="?android:attr/colorAccent"/>
+ android:paddingTop="@dimen/homepage_condition_half_card_padding_top"
+ android:orientation="vertical">
<LinearLayout
- android:layout_width="0dp"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingStart="@dimen/homepage_condition_full_card_padding_start"
- android:paddingEnd="@dimen/homepage_condition_full_card_padding_end"
+ android:paddingStart="@dimen/homepage_card_padding_start"
+ android:paddingEnd="@dimen/homepage_card_padding_end"
android:orientation="vertical">
+ <ImageView
+ android:id="@android:id/icon"
+ android:layout_width="@dimen/homepage_card_icon_size"
+ android:layout_height="@dimen/homepage_card_icon_size"
+ android:tint="?android:attr/colorAccent"/>
+
<TextView
android:id="@android:id/title"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:layout_marginTop="@dimen/homepage_condition_half_card_title_margin_top"
android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
- style="@style/TextAppearance.ConditionCardTitle"/>
+ android:textAppearance="@style/TextAppearance.ConditionCardTitle"/>
<TextView
android:id="@android:id/summary"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/TextAppearance.ConditionCardSummary"/>
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:layout_marginBottom="@dimen/homepage_condition_half_card_summary_margin_bottom"
+ android:textAppearance="@style/TextAppearance.ConditionCardSummary"/>
+
+ <include layout="@layout/horizontal_divider"/>
</LinearLayout>
-
- <include layout="@layout/vertical_divider"/>
-
<Button
android:id="@+id/first_action"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="@style/ConditionFullCardBorderlessButton"/>
+ android:scrollbars="none"
+ style="@style/ConditionHalfCardBorderlessButton"/>
</LinearLayout>
diff --git a/res/layout/homepage_condition_half_tile.xml b/res/layout/homepage_condition_half_tile.xml
index 895183f..8f5af02 100644
--- a/res/layout/homepage_condition_half_tile.xml
+++ b/res/layout/homepage_condition_half_tile.xml
@@ -18,7 +18,7 @@
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="@dimen/homepage_condition_half_card_height"
+ android:layout_height="wrap_content"
style="@style/ContextualCardStyle">
<LinearLayout
@@ -49,7 +49,7 @@
android:ellipsize="end"
android:layout_marginTop="@dimen/homepage_condition_half_card_title_margin_top"
android:layout_marginBottom="@dimen/homepage_condition_card_title_margin_bottom"
- style="@style/TextAppearance.ConditionCardTitle"/>
+ android:textAppearance="@style/TextAppearance.ConditionCardTitle"/>
<TextView
android:id="@android:id/summary"
@@ -58,7 +58,7 @@
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="@dimen/homepage_condition_half_card_summary_margin_bottom"
- style="@style/TextAppearance.ConditionCardSummary"/>
+ android:textAppearance="@style/TextAppearance.ConditionCardSummary"/>
<include layout="@layout/horizontal_divider"/>
diff --git a/res/layout/preference.xml b/res/layout/preference.xml
index cf85e5d..195671b 100644
--- a/res/layout/preference.xml
+++ b/res/layout/preference.xml
@@ -35,7 +35,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
@@ -48,7 +48,7 @@
android:layout_alignStart="@android:id/title"
android:visibility="gone"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10" />
diff --git a/res/layout/preference_multiline_title.xml b/res/layout/preference_multiline_title.xml
index 16c25d5..ae93ead 100644
--- a/res/layout/preference_multiline_title.xml
+++ b/res/layout/preference_multiline_title.xml
@@ -34,7 +34,7 @@
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
@@ -47,7 +47,7 @@
android:layout_alignStart="@android:id/title"
android:visibility="gone"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10" />
diff --git a/res/layout/preference_progress_category.xml b/res/layout/preference_progress_category.xml
index 2ac3dc1..91a0312 100644
--- a/res/layout/preference_progress_category.xml
+++ b/res/layout/preference_progress_category.xml
@@ -46,7 +46,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="start|center"
- android:textAppearance="@android:style/TextAppearance.Material.Body2"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"
android:textColor="?android:attr/colorAccent"/>
<ProgressBar
diff --git a/res/layout/preference_volume_slider.xml b/res/layout/preference_volume_slider.xml
index da3a028..34c732d 100644
--- a/res/layout/preference_volume_slider.xml
+++ b/res/layout/preference_volume_slider.xml
@@ -58,7 +58,7 @@
android:layout_weight="1"
android:paddingStart="12dp"
android:singleLine="true"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary"
android:ellipsize="marquee"
android:fadingEdge="horizontal"/>
@@ -94,7 +94,7 @@
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
diff --git a/res/layout/preference_widget_seekbar_settings.xml b/res/layout/preference_widget_seekbar_settings.xml
index fb1e9c8..9893a1b 100644
--- a/res/layout/preference_widget_seekbar_settings.xml
+++ b/res/layout/preference_widget_seekbar_settings.xml
@@ -35,7 +35,7 @@
android:paddingStart="56dp"
android:paddingEnd="8dp"
android:singleLine="true"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<TextView
diff --git a/res/layout/preset_picker_item.xml b/res/layout/preset_picker_item.xml
index 405b735..47887e1 100644
--- a/res/layout/preset_picker_item.xml
+++ b/res/layout/preset_picker_item.xml
@@ -44,6 +44,6 @@
android:maxLines="2"
android:minLines="2"
android:gravity="top|center_horizontal"
- android:textAppearance="@android:style/TextAppearance.Material.Body1" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" />
</LinearLayout>
diff --git a/res/layout/preview_seek_bar_view_pager.xml b/res/layout/preview_seek_bar_view_pager.xml
index 264991a..12f2611 100644
--- a/res/layout/preview_seek_bar_view_pager.xml
+++ b/res/layout/preview_seek_bar_view_pager.xml
@@ -36,7 +36,7 @@
android:paddingStart="32dp"
android:gravity="start|center"
android:text="@string/screen_zoom_preview_title"
- android:textAppearance="@android:style/TextAppearance.Material.Widget.ActionBar.Title"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title"
android:importantForAccessibility="no" />
</LinearLayout>
diff --git a/res/layout/redaction_interstitial.xml b/res/layout/redaction_interstitial.xml
index 929ac07..ab7e0b3 100644
--- a/res/layout/redaction_interstitial.xml
+++ b/res/layout/redaction_interstitial.xml
@@ -22,7 +22,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:icon="@drawable/ic_suggested_notifications"
- settings:sucFooter="@layout/redaction_interstitial_footer"
settings:suwHeaderText="@string/lock_screen_notifications_interstitial_title">
<LinearLayout
diff --git a/res/layout/redaction_interstitial_footer.xml b/res/layout/redaction_interstitial_footer.xml
deleted file mode 100644
index 1d8758b..0000000
--- a/res/layout/redaction_interstitial_footer.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 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
--->
-
-<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/SuwGlifButtonBar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <Button
- android:id="@+id/redaction_done_button"
- style="@style/SuwGlifButton.Primary"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="end"
- android:text="@string/app_notifications_dialog_done" />
-
-</FrameLayout>
diff --git a/res/layout/running_processes_header.xml b/res/layout/running_processes_header.xml
index a696b38..b2db025 100644
--- a/res/layout/running_processes_header.xml
+++ b/res/layout/running_processes_header.xml
@@ -30,7 +30,7 @@
android:layout_height="48dp"
android:singleLine="true"
android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body2"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textAlignment="viewStart"
android:gravity="left|center_vertical"
@@ -63,7 +63,7 @@
<TextView
android:id="@+id/systemSizePrefix"
android:text="@string/running_processes_header_system_prefix"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -81,7 +81,7 @@
android:contentDescription="@null" />
<TextView
android:id="@+id/systemSize"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -108,7 +108,7 @@
<TextView
android:id="@+id/appsSizePrefix"
android:text="@string/running_processes_header_apps_prefix"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -126,7 +126,7 @@
android:contentDescription="@null" />
<TextView
android:id="@+id/appsSize"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -153,7 +153,7 @@
<TextView
android:id="@+id/freeSizePrefix"
android:text="@string/running_processes_header_free_prefix"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -171,7 +171,7 @@
android:contentDescription="@null" />
<TextView
android:id="@+id/freeSize"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
@@ -186,7 +186,7 @@
android:layout_marginTop="8dp"
android:singleLine="true"
android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body2"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"
android:textColor="?android:attr/textColorPrimary"
android:textAlignment="viewStart"
android:gravity="left|center_vertical"
diff --git a/res/layout/running_processes_item.xml b/res/layout/running_processes_item.xml
index 036a90e..45121eb 100644
--- a/res/layout/running_processes_item.xml
+++ b/res/layout/running_processes_item.xml
@@ -48,7 +48,7 @@
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textAlignment="viewStart" />
<TextView
@@ -56,7 +56,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dip"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
@@ -70,7 +70,7 @@
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:textAlignment="viewStart" />
@@ -79,7 +79,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dip"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
diff --git a/res/layout/screen_zoom_activity.xml b/res/layout/screen_zoom_activity.xml
index 0141019..4cfa7b6 100644
--- a/res/layout/screen_zoom_activity.xml
+++ b/res/layout/screen_zoom_activity.xml
@@ -48,7 +48,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="6dp"
- android:textAppearance="@android:style/TextAppearance.Material.Widget.TextView"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Widget.TextView"
android:elevation="2dp" />
<LinearLayout
@@ -93,7 +93,7 @@
android:layout_height="wrap_content"
android:text="@string/screen_zoom_summary"
android:layout_marginBottom="16dp"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead" />
</LinearLayout>
</LinearLayout>
</ScrollView>
diff --git a/res/layout/screen_zoom_preview_app_icon.xml b/res/layout/screen_zoom_preview_app_icon.xml
index 087afb8..1d56410 100644
--- a/res/layout/screen_zoom_preview_app_icon.xml
+++ b/res/layout/screen_zoom_preview_app_icon.xml
@@ -37,5 +37,5 @@
android:ellipsize="end"
android:gravity="center_horizontal|top"
android:singleLine="true"
- android:textAppearance="@android:style/TextAppearance.Material.Caption" />
-</LinearLayout>
\ No newline at end of file
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Caption" />
+</LinearLayout>
diff --git a/res/layout/screen_zoom_preview_settings.xml b/res/layout/screen_zoom_preview_settings.xml
index 9a0cc59..3401fcf 100644
--- a/res/layout/screen_zoom_preview_settings.xml
+++ b/res/layout/screen_zoom_preview_settings.xml
@@ -57,7 +57,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wifi_settings"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
@@ -65,7 +65,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/wifi_display_status_not_available"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>
@@ -96,14 +96,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/data_usage_summary_title"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_data_usage"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>
@@ -134,14 +134,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/display_settings_title"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/display_summary_example"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>
@@ -172,14 +172,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sound_settings"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sound_settings_example_summary"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>
@@ -210,14 +210,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/applications_settings"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/apps_summary_example"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>
diff --git a/res/layout/settings_summary_preference.xml b/res/layout/settings_summary_preference.xml
index ae3b70d..e76190f 100644
--- a/res/layout/settings_summary_preference.xml
+++ b/res/layout/settings_summary_preference.xml
@@ -31,7 +31,7 @@
android:fontFamily="@*android:string/config_headlineFontFamily"
android:paddingTop="0dp"
android:textColor="?android:attr/colorAccent"
- android:textAppearance="@android:style/TextAppearance.Material.Display1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1"
/>
<TextView android:id="@android:id/summary"
diff --git a/res/layout/storage_internal_forget.xml b/res/layout/storage_internal_forget.xml
index cb47d3b..5ff232a 100644
--- a/res/layout/storage_internal_forget.xml
+++ b/res/layout/storage_internal_forget.xml
@@ -33,7 +33,7 @@
android:paddingStart="@dimen/suw_layout_margin_sides"
android:paddingEnd="@dimen/suw_layout_margin_sides"
android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorPrimary" />
</ScrollView>
diff --git a/res/layout/storage_internal_format.xml b/res/layout/storage_internal_format.xml
index 8aec28f..500592f 100644
--- a/res/layout/storage_internal_format.xml
+++ b/res/layout/storage_internal_format.xml
@@ -33,7 +33,7 @@
android:paddingStart="@dimen/suw_layout_margin_sides"
android:paddingEnd="@dimen/suw_layout_margin_sides"
android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorPrimary" />
</ScrollView>
diff --git a/res/layout/storage_internal_unmount.xml b/res/layout/storage_internal_unmount.xml
index 7e728c8..2e394df 100644
--- a/res/layout/storage_internal_unmount.xml
+++ b/res/layout/storage_internal_unmount.xml
@@ -33,7 +33,7 @@
android:paddingStart="@dimen/suw_layout_margin_sides"
android:paddingEnd="@dimen/suw_layout_margin_sides"
android:lineSpacingExtra="@dimen/suw_description_line_spacing_extra"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorPrimary" />
</ScrollView>
diff --git a/res/layout/storage_item.xml b/res/layout/storage_item.xml
index aa2b4f8..cefb399 100644
--- a/res/layout/storage_item.xml
+++ b/res/layout/storage_item.xml
@@ -61,7 +61,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textAlignment="viewStart"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
@@ -71,7 +71,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10"
android:layout_alignParentEnd="true"/>
diff --git a/res/layout/storage_summary.xml b/res/layout/storage_summary.xml
index d48d62d..ce03b54 100644
--- a/res/layout/storage_summary.xml
+++ b/res/layout/storage_summary.xml
@@ -35,7 +35,7 @@
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/colorAccent"
android:textSize="36sp"/>
@@ -44,7 +44,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:maxLines="10" />
<ProgressBar
diff --git a/res/layout/storage_summary_donut.xml b/res/layout/storage_summary_donut.xml
index 7a10fe7..1637189 100644
--- a/res/layout/storage_summary_donut.xml
+++ b/res/layout/storage_summary_donut.xml
@@ -32,7 +32,7 @@
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
android:textAlignment="center"
- android:textAppearance="@android:style/TextAppearance.Material.Display1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1"
android:textSize="36sp" />
<TextView
@@ -43,7 +43,7 @@
android:layout_marginEnd="4dp"
android:maxLines="10"
android:textAlignment="center"
- android:textAppearance="@android:style/TextAppearance.Material.Body1" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1" />
<com.android.settings.widget.DonutView
android:id="@+id/donut"
diff --git a/res/layout/storage_wizard_init.xml b/res/layout/storage_wizard_init.xml
index 73af8da..bca2676 100644
--- a/res/layout/storage_wizard_init.xml
+++ b/res/layout/storage_wizard_init.xml
@@ -48,7 +48,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/suw_description_margin_bottom"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:text="@string/storage_wizard_init_v2_internal_title" />
<TextView
android:layout_width="match_parent"
@@ -115,7 +115,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/suw_description_margin_bottom"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:text="@string/storage_wizard_init_v2_external_title" />
<TextView
android:layout_width="match_parent"
diff --git a/res/layout/tall_preference_category.xml b/res/layout/tall_preference_category.xml
index f0630f8..7eefdab 100644
--- a/res/layout/tall_preference_category.xml
+++ b/res/layout/tall_preference_category.xml
@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dip"
- android:textAppearance="@android:style/TextAppearance.Material.Body2"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"
android:textColor="?android:attr/colorAccent"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
diff --git a/res/layout/text_description_preference.xml b/res/layout/text_description_preference.xml
index 6b8594b..70385aa 100644
--- a/res/layout/text_description_preference.xml
+++ b/res/layout/text_description_preference.xml
@@ -18,5 +18,5 @@
android:id="@android:id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:padding="16dip" />
diff --git a/res/layout/widget_text_views.xml b/res/layout/widget_text_views.xml
index d95599d..9f0506e 100644
--- a/res/layout/widget_text_views.xml
+++ b/res/layout/widget_text_views.xml
@@ -26,7 +26,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="fill_horizontal|top"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:textAlignment="viewStart"
android:singleLine="true"
@@ -40,7 +40,7 @@
android:layout_weight="1"
android:layout_marginStart="8dip"
android:layout_gravity="fill_horizontal|top"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:textAlignment="viewEnd"
android:singleLine="true"
diff --git a/res/layout/wifi_dpp_activity.xml b/res/layout/wifi_dpp_activity.xml
index cb82f66..48f2b65 100644
--- a/res/layout/wifi_dpp_activity.xml
+++ b/res/layout/wifi_dpp_activity.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<LinearLayout
+<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
@@ -27,4 +27,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
-</LinearLayout>
+</ScrollView>
diff --git a/res/layout/wifi_dpp_fragment_header.xml b/res/layout/wifi_dpp_fragment_header.xml
index 266a3e8..20bcd7d 100644
--- a/res/layout/wifi_dpp_fragment_header.xml
+++ b/res/layout/wifi_dpp_fragment_header.xml
@@ -27,13 +27,13 @@
android:paddingEnd="16dp">
<ImageView
- android:id="@+id/header_icon"
+ android:id="@android:id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="fitCenter"/>
<TextView
- android:id="@+id/title"
+ android:id="@android:id/title"
style="@style/TextAppearance.EntityHeaderTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -44,7 +44,7 @@
android:paddingEnd="32dp"/>
<TextView
- android:id="@+id/description"
+ android:id="@android:id/summary"
style="@style/TextAppearance.EntityHeaderSummary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/layout/wifi_dpp_qrcode_generator_fragment.xml b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
index 789b3a3..c7c258b 100644
--- a/res/layout/wifi_dpp_qrcode_generator_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
@@ -25,9 +25,10 @@
<include layout="@layout/wifi_dpp_fragment_header"/>
<ImageView
- android:id="@+id/barcode_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:id="@+id/qrcode_view"
+ android:layout_width="@dimen/qrcode_size"
+ android:layout_height="@dimen/qrcode_size"
+ android:src="@android:color/transparent"
android:layout_gravity="center"/>
</LinearLayout>
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index 913998f..f09fc69 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -39,10 +39,15 @@
android:layout_gravity="center"/>
</com.android.settings.wifi.qrcode.QrPreviewLayout>
- <TextView android:id="@+id/error_message"
+ <TextView
+ android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"/>
+ android:layout_gravity="center"
+ android:layout_marginTop="8dp"
+ android:text="@string/wifi_dpp_could_not_detect_valid_qr_code"
+ android:visibility="invisible"
+ android:textColor="?android:attr/colorError"/>
</LinearLayout>
diff --git a/res/layout/zen_custom_settings_dialog.xml b/res/layout/zen_custom_settings_dialog.xml
new file mode 100644
index 0000000..f44b2f7
--- /dev/null
+++ b/res/layout/zen_custom_settings_dialog.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fadeScrollbars="false"
+ android:scrollIndicators="top|bottom">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingStart="24dp">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_calls"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_mode_calls" />
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_calls_allow"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_messages"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_mode_messages" />
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_messages_allow"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_alarms"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_mode_alarms" />
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_alarms_allow"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_media"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_mode_media" />
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_media_allow"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_system"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_mode_system" />
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_system_allow"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_reminders"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_mode_reminders"/>
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_reminders_allow"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_events"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_mode_events"/>
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_events_allow"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginTop="14dp">
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_notifications"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/zen_custom_settings_notifications_header" />
+
+ <TextView
+ android:id="@+id/zen_custom_settings_dialog_show_notifications"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem" />
+ </LinearLayout>
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/res/layout/zen_onboarding.xml b/res/layout/zen_onboarding.xml
index 35b992d..27922c6 100644
--- a/res/layout/zen_onboarding.xml
+++ b/res/layout/zen_onboarding.xml
@@ -32,7 +32,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/zen_onboarding_dnd_visual_disturbances_header"
- android:textAppearance="@android:style/TextAppearance.Material.DialogWindowTitle" />
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
<LinearLayout
android:id="@+id/zen_onboarding_new_setting"
diff --git a/res/layout/zen_rule_type.xml b/res/layout/zen_rule_type.xml
index dea39ed..bd50273 100644
--- a/res/layout/zen_rule_type.xml
+++ b/res/layout/zen_rule_type.xml
@@ -42,7 +42,7 @@
android:singleLine="true"
android:textSize="16sp"
android:ellipsize="marquee"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:fadingEdge="horizontal" />
<TextView android:id="@+id/subtitle"
@@ -52,7 +52,7 @@
android:layout_alignStart="@id/title"
android:textSize="14sp"
android:textColor="?android:attr/textColorSecondary"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:maxLines="2"
android:visibility="gone" />
diff --git a/res/layout/zen_rule_widget.xml b/res/layout/zen_rule_widget.xml
index c6214e7..3d75469 100644
--- a/res/layout/zen_rule_widget.xml
+++ b/res/layout/zen_rule_widget.xml
@@ -19,14 +19,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
- <ImageView
- android:id="@+id/zen_automatic_rule_widget"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:paddingStart="16dip"
- android:paddingEnd="16dip"
- android:src="@drawable/ic_settings"
- android:contentDescription="zen_mode_rule_settings"
- android:layout_gravity="center"
- android:background="?android:attr/selectableItemBackground" />
+
+ <include layout="@layout/preference_widget_gear"
+ android:id="@+id/zen_automatic_rule_widget" />
</LinearLayout>
diff --git a/res/values/aliases.xml b/res/values/aliases.xml
index 060ba1d..881d3ca 100644
--- a/res/values/aliases.xml
+++ b/res/values/aliases.xml
@@ -15,7 +15,6 @@
-->
<resources>
- <item name="notification_app_section" type="layout">@*android:layout/preference_category_material</item>
<item name="confirm_lock_pattern" type="layout">@layout/confirm_lock_pattern_base</item>
<item name="confirm_lock_pattern_normal" type="layout">@layout/confirm_lock_pattern_normal_base</item>
<item name="confirm_lock_password" type="layout">@layout/confirm_lock_password_base</item>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index eb5b99a..6f336eb 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1081,14 +1081,14 @@
<item>@string/zen_mode_from_anyone</item>
<item>@string/zen_mode_from_contacts</item>
<item>@string/zen_mode_from_starred</item>
- <item>@string/zen_mode_from_none_calls</item>
+ <item>@string/zen_mode_from_none_messages</item>
</string-array>
<string-array name="zen_mode_contacts_calls_entries" translatable="false">
<item>@string/zen_mode_from_anyone</item>
<item>@string/zen_mode_from_contacts</item>
<item>@string/zen_mode_from_starred</item>
- <item>@string/zen_mode_from_none_messages</item>
+ <item>@string/zen_mode_from_none_calls</item>
</string-array>
<string-array name="zen_mode_contacts_values" translatable="false">
@@ -1105,8 +1105,8 @@
</string-array>
<string-array name="wifi_privacy_entries">
- <item>Default (use randomized MAC)</item>
- <item>Trusted</item>
+ <item>Use device MAC</item>
+ <item>Use randomized MAC (default)</item>
</string-array>
<string-array name="wifi_hidden_entries">
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 587184b..2103649 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -128,5 +128,10 @@
<!-- launcher icon color -->
<color name="icon_launcher_setting_color">@*android:color/accent_device_default_light</color>
-</resources>
+ <!-- QR code scanner colors -->
+ <color name="qr_corner_line_color">#ffdadce0</color>
+ <color name="qr_focused_corner_line_color">#ff1a73e8</color>
+ <color name="qr_background_color">#b3ffffff</color> <!-- 70% white transparency -->
+ <!-- End of QR code scanner colors -->
+</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a109d57..383f564 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -346,7 +346,6 @@
<!-- Condition cards size and padding -->
<dimen name="homepage_condition_card_title_margin_bottom">2dp</dimen>
- <dimen name="homepage_condition_half_card_height">150dp</dimen>
<dimen name="homepage_condition_half_card_padding_top">12dp</dimen>
<dimen name="homepage_condition_half_card_title_margin_top">12dp</dimen>
<dimen name="homepage_condition_half_card_summary_margin_bottom">12dp</dimen>
@@ -366,4 +365,8 @@
<dimen name="homepage_condition_header_icon_width_height">24dp</dimen>
<dimen name="homepage_condition_header_icon_margin_end">24dp</dimen>
+ <!-- QR code picture size -->
+ <dimen name="qrcode_size">264dp</dimen>
+ <dimen name="qrcode_preview_size">360dp</dimen>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 126a835..a45be06 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2090,6 +2090,8 @@
<string name="wifi_dpp_share_wifi">Share Wi\u2011Fi</string>
<!-- Hint for the user to use another device to scan QR code on screen to join Wi-Fi [CHAR LIMIT=NONE] -->
<string name="wifi_dpp_scan_qr_code_with_another_device">Scan this QR code with another device to join \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
+ <!-- Hint for QR code detection [CHAR LIMIT=NONE] -->
+ <string name="wifi_dpp_could_not_detect_valid_qr_code">Could not detect valid QR code</string>
<!-- Label for the check box to share a network with other users on the same device -->
<string name="wifi_shared">Share with other device users</string>
<!-- Hint for unchanged fields -->
@@ -7336,8 +7338,8 @@
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing length of DND -->
<string name="zen_mode_settings_dnd_manual_indefinite">Do Not Disturb will stay on until you turn it off</string>
- <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND rule -->
- <string name="zen_mode_settings_dnd_automatic_rule">Do Not Disturb was automatically turned on by a rule (<xliff:g id="rule_name" example="Weeknights">%s</xliff:g>)</string>
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND schedule -->
+ <string name="zen_mode_settings_dnd_automatic_rule">Do Not Disturb was automatically turned on by a schedule (<xliff:g id="rule_name" example="Weeknights">%s</xliff:g>)</string>
<!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by an app -->
<string name="zen_mode_settings_dnd_automatic_rule_app">Do Not Disturb was automatically turned on by an app (<xliff:g id="app_name" example="Android Services">%s</xliff:g>)</string>
@@ -7345,6 +7347,9 @@
<!-- [CHAR LIMIT=120] Zen mode settings footer: Footer informing user DND has custom settings. -->
<string name="zen_mode_settings_dnd_custom_settings_footer">Do Not Disturb is on for <xliff:g id="rule_names" example="Sleeping and Work">%s</xliff:g> with custom settings.</string>
+ <!-- [CHAR LIMIT=120] Zen mode settings footer: Link following zen_mode_settings_dnd_custom_settings_footer to see the currently applied custom dnd settings. -->
+ <string name="zen_mode_settings_dnd_custom_settings_footer_link"><annotation id="link"> View custom settings</annotation></string>
+
<!--[CHAR LIMIT=40] Zen Interruption level: Priority. -->
<string name="zen_interruption_level_priority">Priority only</string>
@@ -7408,6 +7413,17 @@
<!-- Do not disturb settings, sound and vibrations summary [CHAR LIMIT=100]-->
<string name="zen_sound_three_allowed">Muted, but allow <xliff:g id="sound_type" example="alarms">%1$s</xliff:g>, <xliff:g id="sound_type" example="alarms">%2$s</xliff:g>, and <xliff:g id="sound_type" example="media">%3$s</xliff:g></string>
+ <!-- Do not disturb custom settings dialog title [CHAR LIMIT=40]-->
+ <string name="zen_custom_settings_dialog_title">Custom settings</string>
+ <!-- Do not disturb custom settings dialog button label [CHAR LIMIT=40]-->
+ <string name="zen_custom_settings_dialog_review_schedule">Review schedule</string>
+ <!-- Do not disturb custom settings dialog button label [CHAR LIMIT=40]-->
+ <string name="zen_custom_settings_dialog_ok">Got it</string>
+ <!-- Do not disturb custom settings notifications header [CHAR LIMIT=40]-->
+ <string name="zen_custom_settings_notifications_header">Notifications</string>
+ <!-- Do not disturb custom settings duration header [CHAR LIMIT=40]-->
+ <string name="zen_custom_settings_duration_header">Duration</string>
+
<!-- Do not disturb settings, messages, events and reminders title [CHAR LIMIT=100]-->
<string name="zen_msg_event_reminder_title">Messages, events & reminders</string>
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
@@ -7949,6 +7965,9 @@
<!-- [CHAR LIMIT=120] Zen mode settings: Summay text indicating the currenty dnd schedule is using custom behavior -->
<string name="zen_mode_custom_behavior_summary">Create custom settings for this schedule</string>
+ <!-- [CHAR LIMIT=100] Zen mode settings: Category text indicating the schedule this custom behavior will be configured for-->
+ <string name="zen_mode_custom_behavior_category_title">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019</string>
+
<!-- [CHAR LIMIT=40] General divider text when concatenating multiple items in a text summary -->
<string name="summary_divider_text">,\u0020</string>
@@ -7964,9 +7983,12 @@
<!-- [CHAR LIMIT=40] Zen mode settings: Allow calls toggle title -->
<string name="zen_mode_calls_title">Calls</string>
- <!-- [CHAR LIMIT=20] Zen mode settings: Calls screen footer -->
+ <!-- [CHAR LIMIT=NONE] Zen mode settings: Calls screen footer -->
<string name="zen_mode_calls_footer">When Do Not Disturb is on, incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
+ <!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Calls screen footer -->
+ <string name="zen_mode_custom_calls_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming calls are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
+
<!-- [CHAR LIMIT=50] Zen mode settings: Starred contacts preference title -->
<string name="zen_mode_starred_contacts_title">Starred contacts</string>
@@ -7982,6 +8004,9 @@
<!-- Do not disturb settings, messages, events and reminders footer [CHAR LIMIT=NONE]-->
<string name="zen_mode_messages_footer">When Do Not Disturb is on, incoming text messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
+ <!-- [CHAR LIMIT=NONE] Zen mode custom rule settings: Messages screen footer -->
+ <string name="zen_mode_custom_messages_footer">For \u2018<xliff:g id="schedule_name" example="Schedule 1">%1$s</xliff:g>\u2019 incoming text messages are blocked. You can adjust settings to allow your friends, family, or other contacts to reach you.</string>
+
<!-- [CHAR LIMIT=40] Zen mode settings: Allow messages to bypass DND title -->
<string name="zen_mode_messages_title">Text messages</string>
@@ -8045,11 +8070,11 @@
<!-- [CHAR LIMIT=100] Zen mode settings: Allow apps to bypass DND title-->
<string name="zen_mode_bypassing_apps_title">App exceptions</string>
- <!-- [CHAR LIMIT=80] Zen mode settings: Allow apps to bypass DND -->
+ <!-- [CHAR LIMIT=120] Zen mode settings: Allow apps to bypass DND -->
<plurals name="zen_mode_bypassing_apps_subtext">
<item quantity="zero">No apps can override Do Not Disturb</item>
- <item quantity="one">1 app can override Do Not Disturb</item>
- <item quantity="other"><xliff:g id="number" example="2">%1$d</xliff:g> apps can override Do Not Disturb</item>
+ <item quantity="one">Notifications from 1 app can override Do Not Disturb</item>
+ <item quantity="other">Notifications from <xliff:g id="number" example="2">%1$d</xliff:g> apps can override Do Not Disturb</item>
</plurals>
<!-- [CHAR LIMIT=50] Zen mode settings: Events (ie: calendar events) -->
@@ -8269,8 +8294,6 @@
<!-- Summary describing external storage for applications [CHAR LIMIT=25] -->
<string name="storage_type_external">External storage</string>
- <!-- Title for data usage screen when entered from app info [CHAR LIMIT=30] -->
- <string name="app_data_usage">App data usage</string>
<!-- Summary for data usage preference [CHAR LIMIT=15] -->
<string name="data_summary_format"><xliff:g id="size" example="30.00MB">%1$s</xliff:g> used since <xliff:g id="date" example="Jan 12">%2$s</xliff:g></string>
@@ -10317,9 +10340,9 @@
<string name="see_less">See less</string>
<!-- Title for Network connection request Dialog [CHAR LIMIT=30] -->
- <string name="network_connection_request_dialog_title">Choose device</string>
+ <string name="network_connection_request_dialog_title">Choose a device</string>
<!-- Message for Network connection timeout Dialog [CHAR LIMIT=NONE] -->
- <string name="network_connection_timeout_dialog_message">No devices found. Make sure the device is turned on and available to connect.</string>
+ <string name="network_connection_timeout_dialog_message">No devices found. Make sure devices are turned on and available to connect.</string>
<!-- OK button for Network connection timeout Dialog [CHAR LIMIT=30] -->
<string name="network_connection_timeout_dialog_ok">Try again</string>
<!-- Message for Network connection error state Dialog [CHAR LIMIT=NONE] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 15ec46d..98b6283 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -121,7 +121,7 @@
<item name="android:paddingStart">8dip</item>
<item name="android:textSize">14sp</item>
<item name="android:textAlignment">viewStart</item>
- <item name="android:textAppearance">@android:style/TextAppearance.Material.Body1</item>
+ <item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Body1</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
@@ -129,13 +129,13 @@
<item name="android:paddingStart">8dip</item>
<item name="android:textSize">12sp</item>
<item name="android:textAlignment">viewStart</item>
- <item name="android:textAppearance">@android:style/TextAppearance.Material.Body1</item>
+ <item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Body1</item>
<item name="android:textColor">?android:attr/colorError</item>
</style>
<style name="wifi_item_content">
<item name="android:textAlignment">viewStart</item>
- <item name="android:textAppearance">@android:style/TextAppearance.Material.Subhead</item>
+ <item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Subhead</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:minHeight">@dimen/min_tap_target_size</item>
</style>
@@ -174,23 +174,6 @@
<item name="android:background">#ff000000</item>
</style>
- <style name="SecurityPreferenceButtonContainer"
- parent="@android:style/Widget.Material.Light.SegmentedButton">
- <item name="android:layout_width">match_parent</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:weightSum">2</item>
- <item name="android:dividerPadding">8dip</item>
- </style>
-
- <style name="SecurityPreferenceButton"
- parent="@android:style/Widget.Material.Light.Button.Borderless">
- <item name="android:layout_width">0dip</item>
- <item name="android:layout_weight">1</item>
- <item name="android:layout_height">wrap_content</item>
- <item name="android:ellipsize">marquee</item>
- <item name="android:singleLine">true</item>
- </style>
-
<style name="SetupWizardButton.Negative" parent="@style/SuwGlifButton.Secondary">
<!-- Negative margin to offset for padding of the button itself. We want the label to be
aligned with the text above it -->
@@ -206,13 +189,13 @@
<style name="vpn_label">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
- <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Small</item>
</style>
<style name="vpn_value">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
- <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
<item name="android:singleLine">true</item>
<item name="android:textAlignment">viewStart</item>
<item name="android:minHeight">@dimen/min_tap_target_size</item>
@@ -222,10 +205,10 @@
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingStart">8dip</item>
- <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Small</item>
</style>
- <style name="TextAppearance" parent="android:TextAppearance.Material"/>
+ <style name="TextAppearance" parent="android:TextAppearance.DeviceDefault"/>
<style name="TextAppearance.info_label">
<item name="android:textSize">14sp</item>
@@ -242,14 +225,14 @@
<item name="android:textStyle">normal</item>
</style>
- <style name="TextAppearance.PasswordEntry" parent="android:TextAppearance.Material">
+ <style name="TextAppearance.PasswordEntry" parent="android:TextAppearance.DeviceDefault">
<item name="android:gravity">center</item>
<item name="android:singleLine">true</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">24sp</item>
</style>
- <style name="TextAppearance.CryptKeeper_PasswordEntry" parent="android:TextAppearance.Material">
+ <style name="TextAppearance.CryptKeeper_PasswordEntry" parent="android:TextAppearance.DeviceDefault">
<item name="android:gravity">center_horizontal</item>
<item name="android:background">@null</item>
<item name="android:textCursorDrawable">@null</item>
@@ -257,22 +240,22 @@
<item name="android:imeOptions">flagForceAscii|actionDone</item>
</style>
- <style name="TextAppearance.Medium" parent="@android:style/TextAppearance.Material.Medium"/>
- <style name="TextAppearance.Small" parent="@android:style/TextAppearance.Material.Small"/>
+ <style name="TextAppearance.Medium" parent="@android:style/TextAppearance.DeviceDefault.Medium"/>
+ <style name="TextAppearance.Small" parent="@android:style/TextAppearance.DeviceDefault.Small"/>
<style name="TextAppearance.Switch"
parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
<item name="android:textSize">16sp</item>
</style>
<style name="TextAppearance.CategoryTitle"
- parent="@android:style/TextAppearance.Material.Body2">
+ parent="@*android:style/TextAppearance.DeviceDefault.Body2">
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
- <style name="TextAppearance.TileTitle" parent="@android:style/TextAppearance.Material.Subhead"/>
+ <style name="TextAppearance.TileTitle" parent="@*android:style/TextAppearance.DeviceDefault.Subhead"/>
<style name="TextAppearance.SuggestionTitle"
- parent="@android:style/TextAppearance.Material.Subhead">
+ parent="@*android:style/TextAppearance.DeviceDefault.Subhead">
<item name="android:textSize">16sp</item>
</style>
@@ -280,18 +263,8 @@
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
- <style name="TextAppearance.FingerprintErrorText"
- parent="android:TextAppearance.Material.Body1">
- <item name="android:textColor">?android:attr/colorError</item>
- </style>
-
- <style name="TextAppearance.FaceErrorText"
- parent="android:TextAppearance.Material.Body1">
- <item name="android:textColor">?android:attr/colorError</item>
- </style>
-
- <style name="TextAppearance.ConfirmDeviceCredentialsErrorText"
- parent="android:TextAppearance.Material.Body1">
+ <style name="TextAppearance.ErrorText"
+ parent="@*android:TextAppearance.DeviceDefault.Body1">
<item name="android:textColor">?android:attr/colorError</item>
</style>
@@ -301,29 +274,29 @@
</style>
<style name="TextAppearance.RemoveDialogContent"
- parent="@android:style/TextAppearance.Material">
+ parent="@android:style/TextAppearance.DeviceDefault">
<item name="android:textSize">16sp</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<style name="TextAppearance.SearchBar"
- parent="@android:style/TextAppearance.Material.Widget.Toolbar.Subtitle">
+ parent="@*android:style/TextAppearance.DeviceDefault.Widget.Toolbar.Subtitle">
<item name="android:textSize">@dimen/search_bar_text_size</item>
</style>
<style name="TextAppearance.SuggestionHeader"
- parent="@android:style/TextAppearance.Material.Subhead">
+ parent="@*android:style/TextAppearance.DeviceDefault.Subhead">
<item name="android:textSize">14sp</item>
<item name="android:textColor">?android:attr/colorAccent</item>
</style>
<style name="TextAppearance.ConditionCardTitle"
- parent="@android:style/TextAppearance.Material.Body2">
+ parent="@*android:style/TextAppearance.DeviceDefault.Body2">
<item name="android:textSize">16sp</item>
</style>
<style name="TextAppearance.ConditionCardSummary"
- parent="@android:style/TextAppearance.Material.Body1">
+ parent="@*android:style/TextAppearance.DeviceDefault.Body1">
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
@@ -338,7 +311,7 @@
</style>
<style name="TextAppearance.ContextualCardDismissalText"
- parent="@android:style/TextAppearance.Material.Body1">
+ parent="@*android:style/TextAppearance.DeviceDefault.Body1">
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
<item name="android:textSize">16sp</item>
</style>
@@ -377,13 +350,13 @@
<item name="android:gravity">center_vertical</item>
</style>
- <style name="FingerprintHeaderStyle" parent="android:style/TextAppearance.Material.Subhead">
+ <style name="FingerprintHeaderStyle" parent="@*android:style/TextAppearance.DeviceDefault.Subhead">
<item name="android:paddingTop">16dp</item>
<item name="android:textColor">@color/primary_dark_material_light</item>
<item name="android:lineSpacingMultiplier">1.2</item>
</style>
- <style name="FaceHeaderStyle" parent="android:style/TextAppearance.Material.Subhead">
+ <style name="FaceHeaderStyle" parent="@*android:style/TextAppearance.DeviceDefault.Subhead">
<item name="android:paddingTop">16dp</item>
<item name="android:textColor">@color/primary_dark_material_light</item>
<item name="android:lineSpacingMultiplier">1.2</item>
@@ -438,13 +411,13 @@
<style name="device_info_dialog_label">
<item name="android:textAlignment">viewStart</item>
- <item name="android:textAppearance">@android:style/TextAppearance.Material.Body1</item>
+ <item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Body1</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
<style name="device_info_dialog_value">
<item name="android:textAlignment">viewStart</item>
- <item name="android:textAppearance">@android:style/TextAppearance.Material.Body2</item>
+ <item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Body2</item>
<item name="android:paddingBottom">24dp</item>
</style>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 6b05a7c..6041ef8 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -180,7 +180,7 @@
<item name="android:windowNoTitle">true</item>
</style>
- <style name="Theme.Settings.HomeBase" parent="Theme.AppCompat.DayNight.NoActionBar">
+ <style name="Theme.Settings.HomeBase" parent="Theme.Settings.NoActionBar">
<item name="colorPrimary">@*android:color/primary_device_default_settings_light</item>
<item name="colorAccent">@*android:color/accent_device_default_light</item>
<item name="preferenceTheme">@style/PreferenceTheme</item>
diff --git a/res/xml/zen_mode_custom_rule_configuration.xml b/res/xml/zen_mode_custom_rule_configuration.xml
new file mode 100644
index 0000000..c1732a3
--- /dev/null
+++ b/res/xml/zen_mode_custom_rule_configuration.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_custom_rule_configuration_page"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:title="@string/zen_mode_settings_title">
+
+ <PreferenceCategory
+ android:key="zen_custom_rule_configuration_category">
+ <!-- Calls -->
+ <Preference
+ android:key="zen_rule_calls_settings"
+ android:title="@string/zen_mode_calls" />
+
+ <!-- Messages -->
+ <Preference
+ android:key="zen_rule_messages_settings"
+ android:title="@string/zen_mode_messages" />
+
+ <!-- Alarms -->
+ <SwitchPreference
+ android:key="zen_rule_alarms"
+ android:title="@string/zen_mode_alarms"/>
+
+ <!-- Media -->
+ <SwitchPreference
+ android:key="zen_rule_media"
+ android:title="@string/zen_mode_media"/>
+
+ <!-- System -->
+ <SwitchPreference
+ android:key="zen_rule_system"
+ android:title="@string/zen_mode_system"/>
+
+ <!-- Reminders -->
+ <SwitchPreference
+ android:key="zen_rule_reminders"
+ android:title="@string/zen_mode_reminders"/>
+
+ <!-- Events -->
+ <SwitchPreference
+ android:key="zen_rule_events"
+ android:title="@string/zen_mode_events"/>
+ </PreferenceCategory>
+
+ <Preference
+ android:key="zen_rule_notifications"
+ android:title="@string/zen_mode_restrict_notifications_title"
+ settings:allowDividerAbove="true"/>
+</PreferenceScreen>
diff --git a/res/xml/zen_mode_custom_rule_settings.xml b/res/xml/zen_mode_custom_rule_settings.xml
new file mode 100644
index 0000000..7aedd2c
--- /dev/null
+++ b/res/xml/zen_mode_custom_rule_settings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 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.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_custom_rule_settings_page"
+ android:title="@string/zen_mode_custom_behavior_title">
+
+ <PreferenceCategory
+ android:key="zen_custom_rule_category">
+ <com.android.settings.notification.ZenCustomRadioButtonPreference
+ android:key="zen_custom_rule_setting_default"
+ android:title="@string/zen_mode_custom_behavior_summary_default"/>
+
+ <com.android.settings.notification.ZenCustomRadioButtonPreference
+ android:key="zen_custom_rule_setting"
+ android:title="@string/zen_mode_custom_behavior_summary" />
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/zen_mode_event_rule_settings.xml b/res/xml/zen_mode_event_rule_settings.xml
index a70b46c..841fc06 100644
--- a/res/xml/zen_mode_event_rule_settings.xml
+++ b/res/xml/zen_mode_event_rule_settings.xml
@@ -45,4 +45,10 @@
android:title="@string/zen_mode_event_rule_reply"
android:summary="%s" />
+ <!-- Custom Do Not Disturb Setting-->
+ <Preference
+ android:key="zen_custom_setting"
+ android:title="@string/zen_mode_custom_behavior_title"
+ android:order="100" />
+
</PreferenceScreen>
diff --git a/res/xml/zen_mode_schedule_rule_settings.xml b/res/xml/zen_mode_schedule_rule_settings.xml
index 7de10b3..8484854 100644
--- a/res/xml/zen_mode_schedule_rule_settings.xml
+++ b/res/xml/zen_mode_schedule_rule_settings.xml
@@ -50,7 +50,7 @@
<!-- Custom Do Not Disturb Setting-->
<Preference
- android:key="zen_schedule_custom_setting"
+ android:key="zen_custom_setting"
android:title="@string/zen_mode_custom_behavior_title"
android:order="100" />
diff --git a/src/com/android/settings/EncryptionInterstitial.java b/src/com/android/settings/EncryptionInterstitial.java
index 8cae26b..656b18c 100644
--- a/src/com/android/settings/EncryptionInterstitial.java
+++ b/src/com/android/settings/EncryptionInterstitial.java
@@ -40,6 +40,8 @@
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockSettingsHelper;
+import com.google.android.setupcompat.item.FooterButton;
+import com.google.android.setupcompat.template.ButtonFooterMixin;
import com.google.android.setupdesign.GlifLayout;
import java.util.List;
@@ -86,11 +88,8 @@
layout.setFitsSystemWindows(false);
}
- public static class EncryptionInterstitialFragment extends InstrumentedFragment
- implements View.OnClickListener {
+ public static class EncryptionInterstitialFragment extends InstrumentedFragment {
- private View mRequirePasswordToDecrypt;
- private View mDontRequirePasswordToDecrypt;
private boolean mPasswordRequired;
private Intent mUnlockMethodIntent;
private int mRequestedPasswordQuality;
@@ -110,8 +109,6 @@
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- mRequirePasswordToDecrypt = view.findViewById(R.id.encrypt_require_password);
- mDontRequirePasswordToDecrypt = view.findViewById(R.id.encrypt_dont_require_password);
final boolean forFingerprint = getActivity().getIntent().getBooleanExtra(
ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
final boolean forFace = getActivity().getIntent()
@@ -147,14 +144,30 @@
TextView message = (TextView) getActivity().findViewById(R.id.encryption_message);
message.setText(msgId);
- mRequirePasswordToDecrypt.setOnClickListener(this);
- mDontRequirePasswordToDecrypt.setOnClickListener(this);
-
setRequirePasswordState(getActivity().getIntent().getBooleanExtra(
EXTRA_REQUIRE_PASSWORD, true));
GlifLayout layout = (GlifLayout) view;
layout.setHeaderText(getActivity().getTitle());
+
+ final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
+ buttonFooterMixin.setSecondaryButton(
+ new FooterButton.Builder(getContext())
+ .setText(R.string.encryption_interstitial_no)
+ .setListener(this::onNoButtonClicked)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
+ );
+
+ buttonFooterMixin.setPrimaryButton(
+ new FooterButton.Builder(getContext())
+ .setText(R.string.encryption_interstitial_yes)
+ .setListener(this::onYesButtonClicked)
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
+ );
}
protected void startLockIntent() {
@@ -176,26 +189,25 @@
}
}
- @Override
- public void onClick(View view) {
- if (view == mRequirePasswordToDecrypt) {
- final boolean accEn = AccessibilityManager.getInstance(getActivity()).isEnabled();
- if (accEn && !mPasswordRequired) {
- setRequirePasswordState(false); // clear the UI state
- AccessibilityWarningDialogFragment.newInstance(mRequestedPasswordQuality)
- .show(
- getChildFragmentManager(),
- AccessibilityWarningDialogFragment.TAG);
- } else {
- setRequirePasswordState(true);
- startLockIntent();
- }
+ private void onYesButtonClicked(View view) {
+ final boolean accEn = AccessibilityManager.getInstance(getActivity()).isEnabled();
+ if (accEn && !mPasswordRequired) {
+ setRequirePasswordState(false); // clear the UI state
+ AccessibilityWarningDialogFragment.newInstance(mRequestedPasswordQuality)
+ .show(
+ getChildFragmentManager(),
+ AccessibilityWarningDialogFragment.TAG);
} else {
- setRequirePasswordState(false);
+ setRequirePasswordState(true);
startLockIntent();
}
}
+ private void onNoButtonClicked(View view) {
+ setRequirePasswordState(false);
+ startLockIntent();
+ }
+
private void setRequirePasswordState(boolean required) {
mPasswordRequired = required;
}
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 61a247d..e4ce6443 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -419,12 +419,12 @@
final TemplateLayout layout = mContentView.findViewById(R.id.setup_wizard_layout);
final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
buttonFooterMixin.setPrimaryButton(
- new FooterButton(
- getActivity(),
- R.string.master_clear_button_text,
- mInitiateListener,
- ButtonType.OTHER,
- R.style.SuwGlifButton_Primary)
+ new FooterButton.Builder(getActivity())
+ .setText(R.string.master_clear_button_text)
+ .setListener(mInitiateListener)
+ .setButtonType(ButtonType.OTHER)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
);
mInitiateButton = buttonFooterMixin.getPrimaryButton();
}
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index b2bf838..0750cb1 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -156,12 +156,12 @@
final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
buttonFooterMixin.setPrimaryButton(
- new FooterButton(
- getActivity(),
- R.string.master_clear_button_text,
- mFinalClickListener,
- ButtonType.OTHER,
- R.style.SuwGlifButton_Primary)
+ new FooterButton.Builder(getActivity())
+ .setText(R.string.master_clear_button_text)
+ .setListener(mFinalClickListener)
+ .setButtonType(ButtonType.OTHER)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
);
}
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java
index 8cc7133..ec75266 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollEnrolling.java
@@ -93,12 +93,12 @@
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
- new FooterButton(
- this,
- R.string.security_settings_face_enroll_enrolling_skip,
- this::onSkipButtonClick,
- FooterButton.ButtonType.SKIP,
- R.style.SuwGlifButton_Secondary)
+ new FooterButton.Builder(this)
+ .setText(R.string.security_settings_face_enroll_enrolling_skip)
+ .setListener(this::onSkipButtonClick)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
);
if (!getIntent().getBooleanExtra(BiometricEnrollBase.EXTRA_KEY_REQUIRE_DIVERSITY, true)) {
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollFinish.java b/src/com/android/settings/biometrics/face/FaceEnrollFinish.java
index f0ff523..afd6f55 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollFinish.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollFinish.java
@@ -39,12 +39,12 @@
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setPrimaryButton(
- new FooterButton(
- this,
- R.string.security_settings_face_enroll_done,
- this::onNextButtonClick,
- FooterButton.ButtonType.NEXT,
- R.style.SuwGlifButton_Primary)
+ new FooterButton.Builder(this)
+ .setText(R.string.security_settings_face_enroll_done)
+ .setListener(this::onNextButtonClick)
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
);
}
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
index a90cf5d..9311810 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollIntroduction.java
@@ -62,21 +62,21 @@
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
- new FooterButton(
- this,
- R.string.security_settings_face_enroll_introduction_cancel,
- this::onCancelButtonClick,
- FooterButton.ButtonType.SKIP,
- R.style.SuwGlifButton_Secondary)
+ new FooterButton.Builder(this)
+ .setText(R.string.security_settings_face_enroll_introduction_cancel)
+ .setListener(this::onCancelButtonClick)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
);
mButtonFooterMixin.setPrimaryButton(
- new FooterButton(
- this,
- R.string.wizard_next,
- this::onNextButtonClick,
- FooterButton.ButtonType.NEXT,
- R.style.SuwGlifButton_Primary)
+ new FooterButton.Builder(this)
+ .setText(R.string.wizard_next)
+ .setListener(this::onNextButtonClick)
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
);
}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
index 5953c10..88e1c6a 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java
@@ -139,12 +139,12 @@
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
- new FooterButton(
- this,
- R.string.security_settings_fingerprint_enroll_enrolling_skip,
- this::onSkipButtonClick,
- FooterButton.ButtonType.SKIP,
- R.style.SuwGlifButton_Secondary)
+ new FooterButton.Builder(this)
+ .setText(R.string.security_settings_fingerprint_enroll_enrolling_skip)
+ .setListener(this::onSkipButtonClick)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
);
final LayerDrawable fingerprintDrawable = (LayerDrawable) mProgressBar.getBackground();
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
index b8a0f40..1b97d19 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFindSensor.java
@@ -49,12 +49,12 @@
setContentView(getContentView());
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
- new FooterButton(
- this,
- R.string.skip_label,
- this::onSkipButtonClick,
- FooterButton.ButtonType.SKIP,
- R.style.SuwGlifButton_Secondary)
+ new FooterButton.Builder(this)
+ .setText(R.string.skip_label)
+ .setListener(this::onSkipButtonClick)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
);
setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
index 76f1d1f..db7d92e 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollFinish.java
@@ -44,21 +44,20 @@
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
- new FooterButton(
- this,
- R.string.fingerprint_enroll_button_add,
- null,
- FooterButton.ButtonType.SKIP,
- R.style.SuwGlifButton_Secondary)
+ new FooterButton.Builder(this)
+ .setText(R.string.fingerprint_enroll_button_add)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
);
mButtonFooterMixin.setPrimaryButton(
- new FooterButton(
- this,
- R.string.security_settings_fingerprint_enroll_done,
- this::onNextButtonClick,
- FooterButton.ButtonType.NEXT,
- R.style.SuwGlifButton_Primary)
+ new FooterButton.Builder(this)
+ .setText(R.string.security_settings_fingerprint_enroll_done)
+ .setListener(this::onNextButtonClick)
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
);
}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
index 4eca87d..1ad11e3 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroduction.java
@@ -49,21 +49,21 @@
mButtonFooterMixin = getLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
- new FooterButton(
- this,
- R.string.security_settings_face_enroll_introduction_cancel,
- this::onCancelButtonClick,
- FooterButton.ButtonType.SKIP,
- R.style.SuwGlifButton_Secondary)
+ new FooterButton.Builder(this)
+ .setText(R.string.security_settings_face_enroll_introduction_cancel)
+ .setListener(this::onCancelButtonClick)
+ .setButtonType(FooterButton.ButtonType.SKIP)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
);
mButtonFooterMixin.setPrimaryButton(
- new FooterButton(
- this,
- R.string.wizard_next,
- this::onNextButtonClick,
- FooterButton.ButtonType.NEXT,
- R.style.SuwGlifButton_Primary)
+ new FooterButton.Builder(this)
+ .setText(R.string.wizard_next)
+ .setListener(this::onNextButtonClick)
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
);
}
diff --git a/src/com/android/settings/datausage/AppDataUsageActivity.java b/src/com/android/settings/datausage/AppDataUsageActivity.java
index 2b8e42d..82a3a45 100644
--- a/src/com/android/settings/datausage/AppDataUsageActivity.java
+++ b/src/com/android/settings/datausage/AppDataUsageActivity.java
@@ -62,7 +62,7 @@
args.putParcelable(AppDataUsage.ARG_APP_ITEM, appItem);
intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
intent.putExtra(EXTRA_SHOW_FRAGMENT, AppDataUsage.class.getName());
- intent.putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.app_data_usage);
+ intent.putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, R.string.data_usage_app_summary_title);
super.onCreate(savedInstanceState);
}
diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java
index 326b0d4..3369e5e 100644
--- a/src/com/android/settings/datausage/DataUsageList.java
+++ b/src/com/android/settings/datausage/DataUsageList.java
@@ -419,7 +419,7 @@
new SubSettingLauncher(getContext())
.setDestination(AppDataUsage.class.getName())
- .setTitleRes(R.string.app_data_usage)
+ .setTitleRes(R.string.data_usage_app_summary_title)
.setArguments(args)
.setSourceMetricsCategory(getMetricsCategory())
.launch();
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
index 824c102..97ed5ac 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
@@ -82,7 +82,7 @@
if (mDataUsageState.isDataSaverBlacklisted) {
// app is blacklisted, launch App Data Usage screen
AppInfoDashboardFragment.startAppInfoFragment(AppDataUsage.class,
- R.string.app_data_usage,
+ R.string.data_usage_app_summary_title,
null /* arguments */,
mParentFragment,
mEntry);
diff --git a/src/com/android/settings/deviceinfo/StorageWizardBase.java b/src/com/android/settings/deviceinfo/StorageWizardBase.java
index 9950d3f..4d6ded1 100644
--- a/src/com/android/settings/deviceinfo/StorageWizardBase.java
+++ b/src/com/android/settings/deviceinfo/StorageWizardBase.java
@@ -96,20 +96,20 @@
mButtonFooterMixin = getGlifLayout().getMixin(ButtonFooterMixin.class);
mButtonFooterMixin.setSecondaryButton(
- new FooterButton(
- this,
- R.string.wizard_back,
- this::onNavigateBack,
- FooterButton.ButtonType.OTHER,
- R.style.SuwGlifButton_Secondary)
+ new FooterButton.Builder(this)
+ .setText(R.string.wizard_back)
+ .setListener(this::onNavigateBack)
+ .setButtonType(FooterButton.ButtonType.OTHER)
+ .setTheme(R.style.SuwGlifButton_Secondary)
+ .build()
);
mButtonFooterMixin.setPrimaryButton(
- new FooterButton(
- this,
- R.string.wizard_next,
- this::onNavigateNext,
- FooterButton.ButtonType.NEXT,
- R.style.SuwGlifButton_Primary)
+ new FooterButton.Builder(this)
+ .setText(R.string.wizard_next)
+ .setListener(this::onNavigateNext)
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
);
mBack = mButtonFooterMixin.getSecondaryButton();
mNext = mButtonFooterMixin.getPrimaryButton();
diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceController.java
index 7d12d43..b7b67b7 100644
--- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceController.java
@@ -23,9 +23,12 @@
import androidx.fragment.app.Fragment;
import androidx.preference.Preference;
+import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.slices.Copyable;
-public class FirmwareVersionPreferenceController extends BasePreferenceController {
+public class FirmwareVersionPreferenceController extends BasePreferenceController implements
+ Copyable {
private Fragment mFragment;
@@ -61,4 +64,10 @@
public boolean isSliceable() {
return true;
}
+
+ @Override
+ public void copy() {
+ Copyable.setCopyContent(mContext, getSummary(),
+ mContext.getText(R.string.firmware_version));
+ }
}
diff --git a/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceController.java b/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceController.java
index 1f1630e..2b61ec8 100644
--- a/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceController.java
@@ -53,7 +53,7 @@
@Override
public int getAvailabilityStatus() {
// No hardware support for this Gesture
- if (!getAmbientConfig().wakeLockScreenGestureAvailable()) {
+ if (!getAmbientConfig().wakeScreenGestureAvailable()) {
return UNSUPPORTED_ON_DEVICE;
}
diff --git a/src/com/android/settings/location/TopLevelLocationPreferenceController.java b/src/com/android/settings/location/TopLevelLocationPreferenceController.java
index d0bd9a9..455af21 100644
--- a/src/com/android/settings/location/TopLevelLocationPreferenceController.java
+++ b/src/com/android/settings/location/TopLevelLocationPreferenceController.java
@@ -1,6 +1,5 @@
package com.android.settings.location;
-import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
@@ -11,6 +10,7 @@
import android.location.LocationManager;
import android.permission.RuntimePermissionPresenter;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
@@ -20,7 +20,6 @@
import com.android.settingslib.core.lifecycle.events.OnStop;
import java.util.Arrays;
-import java.util.Collections;
public class TopLevelLocationPreferenceController extends BasePreferenceController implements
LifecycleObserver, OnStart, OnStop {
@@ -56,6 +55,12 @@
}
}
+ @VisibleForTesting
+ void setLocationAppCount(int numApps) {
+ mNumTotal = numApps;
+ refreshSummary(mPreference);
+ }
+
@Override
public void updateState(Preference preference) {
super.updateState(preference);
@@ -68,8 +73,7 @@
RuntimePermissionPresenter.getInstance(mContext).countPermissionApps(
Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), false, false,
(numApps) -> {
- mNumTotal = numApps;
- refreshSummary(preference);
+ setLocationAppCount(numApps);
}, null);
}
diff --git a/src/com/android/settings/network/ApnSettings.java b/src/com/android/settings/network/ApnSettings.java
index 2b47c70..ac3b1f6 100755
--- a/src/com/android/settings/network/ApnSettings.java
+++ b/src/com/android/settings/network/ApnSettings.java
@@ -61,7 +61,8 @@
import java.util.ArrayList;
-public class ApnSettings extends RestrictedSettingsFragment {
+public class ApnSettings extends RestrictedSettingsFragment
+ implements Preference.OnPreferenceChangeListener {
static final String TAG = "ApnSettings";
public static final String EXTRA_POSITION = "position";
@@ -313,6 +314,7 @@
pref.setKey(key);
pref.setTitle(name);
pref.setPersistent(false);
+ pref.setOnPreferenceChangeListener(this);
pref.setSubId(subId);
if (mHidePresetApnDetails && edited == Telephony.Carriers.UNEDITED) {
pref.setHideDetails();
@@ -386,6 +388,7 @@
startActivity(intent);
}
+ @Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.d(TAG, "onPreferenceChange(): Preference - " + preference
+ ", newValue - " + newValue + ", newValue type - "
diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
index b323f91..d2ec162 100644
--- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
+++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java
@@ -126,7 +126,6 @@
private void updatePreferenceEntries(ListPreference preference) {
final int phoneType = mTelephonyManager.getPhoneType();
- final Resources resources = mContext.getResources();
final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
final int lteForced = android.provider.Settings.Global.getInt(
@@ -216,6 +215,7 @@
}
private void updatePreferenceValueAndSummary(ListPreference preference, int networkMode) {
+ preference.setValue(Integer.toString(networkMode));
switch (networkMode) {
case TelephonyManager.NETWORK_MODE_TDSCDMA_WCDMA:
case TelephonyManager.NETWORK_MODE_TDSCDMA_GSM_WCDMA:
diff --git a/src/com/android/settings/notification/AbstractZenCustomRulePreferenceController.java b/src/com/android/settings/notification/AbstractZenCustomRulePreferenceController.java
new file mode 100644
index 0000000..409eec6
--- /dev/null
+++ b/src/com/android/settings/notification/AbstractZenCustomRulePreferenceController.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.app.AutomaticZenRule;
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+abstract class AbstractZenCustomRulePreferenceController extends
+ AbstractZenModePreferenceController implements PreferenceControllerMixin {
+
+ String mId;
+ AutomaticZenRule mRule;
+
+ AbstractZenCustomRulePreferenceController(Context context, String key,
+ Lifecycle lifecycle) {
+ super(context, key, lifecycle);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (mId != null) {
+ mRule = mBackend.getAutomaticZenRule(mId);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mRule != null;
+ }
+
+ public void onResume(AutomaticZenRule rule, String id) {
+ mId = id;
+ mRule = rule;
+ }
+
+ Bundle createBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putString(ZenCustomRuleSettings.RULE_ID, mId);
+ return bundle;
+ }
+}
diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
index 383934a..0e45e58 100644
--- a/src/com/android/settings/notification/AbstractZenModePreferenceController.java
+++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
@@ -50,7 +50,7 @@
@VisibleForTesting
protected SettingObserver mSettingObserver;
- private final String KEY;
+ final String KEY;
final private NotificationManager mNotificationManager;
protected static ZenModeConfigWrapper mZenModeConfigWrapper;
protected MetricsFeatureProvider mMetricsFeatureProvider;
diff --git a/src/com/android/settings/notification/RedactionInterstitial.java b/src/com/android/settings/notification/RedactionInterstitial.java
index 32dc52d..b2f2d25 100644
--- a/src/com/android/settings/notification/RedactionInterstitial.java
+++ b/src/com/android/settings/notification/RedactionInterstitial.java
@@ -32,7 +32,6 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
@@ -46,9 +45,12 @@
import com.android.settings.SetupRedactionInterstitial;
import com.android.settings.SetupWizardUtils;
import com.android.settings.Utils;
-import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
+import com.google.android.setupcompat.item.FooterButton;
+import com.google.android.setupcompat.template.ButtonFooterMixin;
+import com.google.android.setupdesign.GlifLayout;
+
public class RedactionInterstitial extends SettingsActivity {
@Override
@@ -91,7 +93,7 @@
}
public static class RedactionInterstitialFragment extends SettingsPreferenceFragment
- implements RadioGroup.OnCheckedChangeListener, View.OnClickListener {
+ implements RadioGroup.OnCheckedChangeListener {
private RadioGroup mRadioGroup;
private RestrictedRadioButton mShowAllButton;
@@ -130,19 +132,24 @@
((RadioButton) view.findViewById(R.id.hide_all)).setVisibility(View.GONE);
}
- final Button button = (Button) view.findViewById(R.id.redaction_done_button);
- button.setOnClickListener(this);
+ final GlifLayout layout = view.findViewById(R.id.setup_wizard_layout);
+ final ButtonFooterMixin buttonFooterMixin = layout.getMixin(ButtonFooterMixin.class);
+ buttonFooterMixin.setPrimaryButton(
+ new FooterButton.Builder(getContext())
+ .setText(R.string.app_notifications_dialog_done)
+ .setListener(this::onDoneButtonClicked)
+ .setButtonType(FooterButton.ButtonType.NEXT)
+ .setTheme(R.style.SuwGlifButton_Primary)
+ .build()
+ );
}
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.redaction_done_button) {
- SetupRedactionInterstitial.setEnabled(getContext(), false);
- final RedactionInterstitial activity = (RedactionInterstitial) getActivity();
- if (activity != null) {
- activity.setResult(RESULT_OK, null);
- finish();
- }
+ private void onDoneButtonClicked(View view) {
+ SetupRedactionInterstitial.setEnabled(getContext(), false);
+ final RedactionInterstitial activity = (RedactionInterstitial) getActivity();
+ if (activity != null) {
+ activity.setResult(RESULT_OK, null);
+ finish();
}
}
diff --git a/src/com/android/settings/notification/ZenCustomRuleBlockedEffectsSettings.java b/src/com/android/settings/notification/ZenCustomRuleBlockedEffectsSettings.java
new file mode 100644
index 0000000..3f75a20
--- /dev/null
+++ b/src/com/android/settings/notification/ZenCustomRuleBlockedEffectsSettings.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.service.notification.ZenPolicy;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenCustomRuleBlockedEffectsSettings extends ZenCustomRuleSettingsBase {
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ mFooterPreferenceMixin.createFooterPreference().setTitle(
+ R.string.zen_mode_blocked_effects_footer);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_block_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
+ "zen_effect_intent", ZenPolicy.VISUAL_EFFECT_FULL_SCREEN_INTENT,
+ MetricsEvent.ACTION_ZEN_BLOCK_FULL_SCREEN_INTENTS, null));
+ mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
+ "zen_effect_light", ZenPolicy.VISUAL_EFFECT_LIGHTS,
+ MetricsEvent.ACTION_ZEN_BLOCK_LIGHT, null));
+ mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
+ "zen_effect_peek", ZenPolicy.VISUAL_EFFECT_PEEK,
+ MetricsEvent.ACTION_ZEN_BLOCK_PEEK, null));
+ mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
+ "zen_effect_status", ZenPolicy.VISUAL_EFFECT_STATUS_BAR,
+ MetricsEvent.ACTION_ZEN_BLOCK_STATUS,
+ new int[] {ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST}));
+ mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
+ "zen_effect_badge", ZenPolicy.VISUAL_EFFECT_BADGE,
+ MetricsEvent.ACTION_ZEN_BLOCK_BADGE, null));
+ mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
+ "zen_effect_ambient", ZenPolicy.VISUAL_EFFECT_AMBIENT,
+ MetricsEvent.ACTION_ZEN_BLOCK_AMBIENT, null));
+ mControllers.add(new ZenRuleVisEffectPreferenceController(context, getSettingsLifecycle(),
+ "zen_effect_list", ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST,
+ MetricsEvent.ACTION_ZEN_BLOCK_NOTIFICATION_LIST, null));
+ return mControllers;
+ }
+
+ @Override
+ String getPreferenceCategoryKey() {
+ return null;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ZEN_CUSTOM_RULE_VIS_EFFECTS;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenCustomRuleCallsSettings.java b/src/com/android/settings/notification/ZenCustomRuleCallsSettings.java
new file mode 100644
index 0000000..808264e
--- /dev/null
+++ b/src/com/android/settings/notification/ZenCustomRuleCallsSettings.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.widget.FooterPreference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenCustomRuleCallsSettings extends ZenCustomRuleSettingsBase {
+ private static final String CALLS_KEY = "zen_mode_calls";
+ private static final String REPEAT_CALLERS_KEY = "zen_mode_repeat_callers";
+ private static final String STARRED_CONTACTS_KEY = "zen_mode_starred_contacts_callers";
+ private static final String PREFERENCE_CATEGORY_KEY = "zen_mode_settings_category_calls";
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return com.android.settings.R.xml.zen_mode_calls_settings;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_CALLS;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new ZenRuleCallsPreferenceController(context, CALLS_KEY,
+ getSettingsLifecycle()));
+ mControllers.add(new ZenRuleRepeatCallersPreferenceController(context,
+ REPEAT_CALLERS_KEY, getSettingsLifecycle(), context.getResources()
+ .getInteger(com.android.internal.R.integer.config_zen_repeat_callers_threshold)));
+ mControllers.add(new ZenRuleStarredContactsPreferenceController(context,
+ getSettingsLifecycle(), ZenPolicy.PRIORITY_CATEGORY_CALLS, STARRED_CONTACTS_KEY));
+ return mControllers;
+ }
+
+ @Override
+ String getPreferenceCategoryKey() {
+ return PREFERENCE_CATEGORY_KEY;
+ }
+
+ @Override
+ public void updatePreferences() {
+ super.updatePreferences();
+ PreferenceScreen screen = getPreferenceScreen();
+ Preference footerPreference = screen.findPreference(FooterPreference.KEY_FOOTER);
+ footerPreference.setTitle(mContext.getResources().getString(
+ R.string.zen_mode_custom_calls_footer, mRule.getName()));
+ }
+}
diff --git a/src/com/android/settings/notification/ZenCustomRuleConfigSettings.java b/src/com/android/settings/notification/ZenCustomRuleConfigSettings.java
new file mode 100644
index 0000000..fd8ce2b
--- /dev/null
+++ b/src/com/android/settings/notification/ZenCustomRuleConfigSettings.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.Bundle;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.Preference;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenCustomRuleConfigSettings extends ZenCustomRuleSettingsBase {
+ private static final String CALLS_KEY = "zen_rule_calls_settings";
+ private static final String MESSAGES_KEY = "zen_rule_messages_settings";
+ private static final String ALARMS_KEY = "zen_rule_alarms";
+ private static final String MEDIA_KEY = "zen_rule_media";
+ private static final String SYSTEM_KEY = "zen_rule_system";
+ private static final String REMINDERS_KEY = "zen_rule_reminders";
+ private static final String EVENTS_KEY = "zen_rule_events";
+ private static final String NOTIFICATIONS_KEY = "zen_rule_notifications";
+ private static final String PREFERENCE_CATEGORY_KEY = "zen_custom_rule_configuration_category";
+
+ private Preference mCallsPreference;
+ private Preference mMessagesPreference;
+ private Preference mNotificationsPreference;
+ private ZenModeSettings.SummaryBuilder mSummaryBuilder;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mSummaryBuilder = new ZenModeSettings.SummaryBuilder(mContext);
+
+ mCallsPreference = getPreferenceScreen().findPreference(CALLS_KEY);
+ mCallsPreference.setOnPreferenceClickListener(
+ new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ new SubSettingLauncher(mContext)
+ .setDestination(ZenCustomRuleCallsSettings.class.getName())
+ .setArguments(createZenRuleBundle())
+ .setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_CALLS)
+ .launch();
+ return true;
+ }
+ });
+
+ mMessagesPreference = getPreferenceScreen().findPreference(MESSAGES_KEY);
+ mMessagesPreference.setOnPreferenceClickListener(
+ new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ new SubSettingLauncher(mContext)
+ .setDestination(ZenCustomRuleMessagesSettings.class.getName())
+ .setArguments(createZenRuleBundle())
+ .setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_MESSAGES)
+ .launch();
+ return true;
+ }
+ });
+
+ mNotificationsPreference = getPreferenceScreen().findPreference(NOTIFICATIONS_KEY);
+ mNotificationsPreference.setOnPreferenceClickListener(
+ new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ new SubSettingLauncher(mContext)
+ .setDestination(ZenCustomRuleNotificationsSettings.class.getName())
+ .setArguments(createZenRuleBundle())
+ .setSourceMetricsCategory
+ (MetricsEvent.ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS)
+ .launch();
+ return true;
+ }
+ });
+
+ updateSummaries();
+ }
+
+ @Override
+ public void onZenModeConfigChanged() {
+ super.onZenModeConfigChanged();
+ updateSummaries();
+ }
+
+ /**
+ * Updates summaries of preferences without preference controllers
+ */
+ private void updateSummaries() {
+ NotificationManager.Policy noManPolicy = mBackend.toNotificationPolicy(
+ mRule.getZenPolicy());
+
+ mCallsPreference.setSummary(mSummaryBuilder.getCallsSettingSummary(noManPolicy));
+ mMessagesPreference.setSummary(mSummaryBuilder.getMessagesSettingSummary(noManPolicy));
+ mNotificationsPreference.setSummary(mSummaryBuilder.getBlockedEffectsSummary(noManPolicy));
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_custom_rule_configuration;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ZEN_CUSTOM_RULE_SOUND_SETTINGS;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
+ getSettingsLifecycle(), ALARMS_KEY, ZenPolicy.PRIORITY_CATEGORY_ALARMS,
+ MetricsEvent.ACTION_ZEN_ALLOW_ALARMS));
+ mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
+ getSettingsLifecycle(), MEDIA_KEY, ZenPolicy.PRIORITY_CATEGORY_MEDIA,
+ MetricsEvent.ACTION_ZEN_ALLOW_MEDIA));
+ mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
+ getSettingsLifecycle(), SYSTEM_KEY, ZenPolicy.PRIORITY_CATEGORY_SYSTEM,
+ MetricsEvent.ACTION_ZEN_ALLOW_SYSTEM));
+ mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
+ getSettingsLifecycle(), REMINDERS_KEY, ZenPolicy.PRIORITY_CATEGORY_REMINDERS,
+ MetricsEvent.ACTION_ZEN_ALLOW_REMINDERS));
+ mControllers.add(new ZenRuleCustomSwitchPreferenceController(context,
+ getSettingsLifecycle(), EVENTS_KEY, ZenPolicy.PRIORITY_CATEGORY_EVENTS,
+ MetricsEvent.ACTION_ZEN_ALLOW_EVENTS));
+ return mControllers;
+ }
+
+ @Override
+ String getPreferenceCategoryKey() {
+ return PREFERENCE_CATEGORY_KEY;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateSummaries();
+ }
+}
diff --git a/src/com/android/settings/notification/ZenCustomRuleMessagesSettings.java b/src/com/android/settings/notification/ZenCustomRuleMessagesSettings.java
new file mode 100644
index 0000000..8db2824
--- /dev/null
+++ b/src/com/android/settings/notification/ZenCustomRuleMessagesSettings.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.widget.FooterPreference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenCustomRuleMessagesSettings extends ZenCustomRuleSettingsBase {
+ private static final String MESSAGES_KEY = "zen_mode_messages";
+ private static final String STARRED_CONTACTS_KEY = "zen_mode_starred_contacts_messages";
+ private static final String PREFERENCE_CATEGORY_KEY = "zen_mode_settings_category_messages";
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return com.android.settings.R.xml.zen_mode_messages_settings;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_MESSAGES;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new ZenRuleMessagesPreferenceController(context, MESSAGES_KEY,
+ getSettingsLifecycle()));
+ mControllers.add(new ZenRuleStarredContactsPreferenceController(context,
+ getSettingsLifecycle(), ZenPolicy.PRIORITY_CATEGORY_MESSAGES,
+ STARRED_CONTACTS_KEY));
+ return mControllers;
+ }
+
+ @Override
+ String getPreferenceCategoryKey() {
+ return PREFERENCE_CATEGORY_KEY;
+ }
+
+ @Override
+ public void updatePreferences() {
+ super.updatePreferences();
+ PreferenceScreen screen = getPreferenceScreen();
+ Preference footerPreference = screen.findPreference(FooterPreference.KEY_FOOTER);
+ footerPreference.setTitle(mContext.getResources().getString(
+ R.string.zen_mode_custom_messages_footer, mRule.getName()));
+ }
+}
diff --git a/src/com/android/settings/notification/ZenCustomRuleNotificationsSettings.java b/src/com/android/settings/notification/ZenCustomRuleNotificationsSettings.java
new file mode 100644
index 0000000..a23bc6d
--- /dev/null
+++ b/src/com/android/settings/notification/ZenCustomRuleNotificationsSettings.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.widget.FooterPreference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenCustomRuleNotificationsSettings extends ZenCustomRuleSettingsBase {
+ private static final String VIS_EFFECTS_ALL_KEY = "zen_mute_notifications";
+ private static final String VIS_EFFECTS_NONE_KEY = "zen_hide_notifications";
+ private static final String VIS_EFFECTS_CUSTOM_KEY = "zen_custom";
+ private static final String PREFERENCE_CATEGORY_KEY = "restrict_category";
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_restrict_notifications_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new ZenRuleVisEffectsAllPreferenceController(
+ context, getSettingsLifecycle(), VIS_EFFECTS_ALL_KEY));
+ mControllers.add(new ZenRuleVisEffectsNonePreferenceController(
+ context, getSettingsLifecycle(), VIS_EFFECTS_NONE_KEY));
+ mControllers.add(new ZenRuleVisEffectsCustomPreferenceController(
+ context, getSettingsLifecycle(), VIS_EFFECTS_CUSTOM_KEY));
+ mControllers.add(new ZenRuleNotifFooterPreferenceController(context, getSettingsLifecycle(),
+ FooterPreference.KEY_FOOTER));
+ return mControllers;
+ }
+
+ @Override
+ String getPreferenceCategoryKey() {
+ return PREFERENCE_CATEGORY_KEY;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_NOTIFICATION_RESTRICTIONS;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenCustomRuleSettings.java b/src/com/android/settings/notification/ZenCustomRuleSettings.java
new file mode 100644
index 0000000..ebd6306
--- /dev/null
+++ b/src/com/android/settings/notification/ZenCustomRuleSettings.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenCustomRuleSettings extends ZenCustomRuleSettingsBase {
+ private static final String RULE_DEFAULT_POLICY_KEY = "zen_custom_rule_setting_default";
+ private static final String CUSTOM_RULE_POLICY_KEY = "zen_custom_rule_setting";
+ private static final String PREFERENCE_CATEGORY_KEY = "zen_custom_rule_category";
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_custom_rule_settings;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_SETTINGS;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ mControllers = new ArrayList<>();
+ mControllers.add(new ZenRuleDefaultPolicyPreferenceController(
+ context, getSettingsLifecycle(), RULE_DEFAULT_POLICY_KEY));
+ mControllers.add(new ZenRuleCustomPolicyPreferenceController(
+ context, getSettingsLifecycle(), CUSTOM_RULE_POLICY_KEY));
+ return mControllers;
+ }
+
+ @Override
+ String getPreferenceCategoryKey() {
+ return PREFERENCE_CATEGORY_KEY;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenCustomRuleSettingsBase.java b/src/com/android/settings/notification/ZenCustomRuleSettingsBase.java
new file mode 100644
index 0000000..94b0b7b
--- /dev/null
+++ b/src/com/android/settings/notification/ZenCustomRuleSettingsBase.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.app.AutomaticZenRule;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.ArrayList;
+import java.util.List;
+
+abstract class ZenCustomRuleSettingsBase extends ZenModeSettingsBase {
+ static final String TAG = "ZenCustomRuleSettings";
+ static final String RULE_ID = "RULE_ID";
+
+ String mId;
+ AutomaticZenRule mRule;
+ List<AbstractPreferenceController> mControllers = new ArrayList<>();
+
+ /**
+ * @return null if no preference category exists
+ */
+ abstract String getPreferenceCategoryKey();
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ Bundle bundle = getArguments();
+ if (bundle != null && bundle.containsKey(RULE_ID)) {
+ mId = bundle.getString(RULE_ID);
+ mRule = mBackend.getAutomaticZenRule(mId);
+ } else {
+ Log.d(TAG, "Rule id required to set custom dnd rule config settings");
+ this.finish();
+ }
+ }
+
+ @Override
+ public void onZenModeConfigChanged() {
+ super.onZenModeConfigChanged();
+ updatePreferences();
+ }
+
+ public void updatePreferences() {
+ mRule = mBackend.getAutomaticZenRule(mId);
+ final PreferenceScreen screen = getPreferenceScreen();
+ String categoryKey = getPreferenceCategoryKey();
+ if (categoryKey != null) {
+ Preference prefCategory = screen.findPreference(categoryKey);
+ if (prefCategory != null) {
+ prefCategory.setTitle(mContext.getResources().getString(
+ com.android.settings.R.string.zen_mode_custom_behavior_category_title,
+ mRule.getName()));
+ }
+ }
+
+ for (AbstractPreferenceController controller : mControllers) {
+ AbstractZenCustomRulePreferenceController zenRuleController =
+ (AbstractZenCustomRulePreferenceController) controller;
+ zenRuleController.onResume(mRule, mId);
+ zenRuleController.displayPreference(screen);
+ updatePreference(zenRuleController);
+ }
+ }
+
+ @Override
+ public int getHelpResource() {
+ return R.string.help_uri_interruptions;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updatePreferences();
+ }
+
+ Bundle createZenRuleBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putString(RULE_ID, mId);
+ return bundle;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java
index a75f51c..4c9cebe 100644
--- a/src/com/android/settings/notification/ZenModeBackend.java
+++ b/src/com/android/settings/notification/ZenModeBackend.java
@@ -23,15 +23,20 @@
import android.app.AutomaticZenRule;
import android.app.NotificationManager;
import android.content.Context;
+import android.database.Cursor;
+import android.icu.text.ListFormatter;
import android.net.Uri;
+import android.provider.ContactsContract;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenPolicy;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@@ -116,7 +121,7 @@
return (mPolicy.priorityCategories & categoryType) != 0;
}
- protected int getNewPriorityCategories(boolean allow, int categoryType) {
+ protected int getNewDefaultPriorityCategories(boolean allow, int categoryType) {
int priorityCategories = mPolicy.priorityCategories;
if (allow) {
priorityCategories |= categoryType;
@@ -135,7 +140,8 @@
}
protected int getPriorityMessageSenders() {
- if (isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) {
+ if (isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES)) {
return mPolicy.priorityMessageSenders;
}
return SOURCE_NONE;
@@ -151,7 +157,7 @@
}
protected void saveSoundPolicy(int category, boolean allow) {
- int priorityCategories = getNewPriorityCategories(allow, category);
+ int priorityCategories = getNewDefaultPriorityCategories(allow, category);
savePolicy(priorityCategories, mPolicy.priorityCallSenders,
mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects);
}
@@ -163,6 +169,7 @@
mNotificationManager.setNotificationPolicy(mPolicy);
}
+
private int getNewSuppressedEffects(boolean suppress, int effectType) {
int effects = mPolicy.suppressedVisualEffects;
@@ -202,7 +209,7 @@
priorityMessagesSenders = allowSendersFrom;
}
- savePolicy(getNewPriorityCategories(allowSenders, category),
+ savePolicy(getNewDefaultPriorityCategories(allowSenders, category),
priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects);
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow" +
@@ -236,6 +243,20 @@
return categorySenders;
}
+ protected static String getKeyFromZenPolicySetting(int contactType) {
+ switch (contactType) {
+ case ZenPolicy.PEOPLE_TYPE_ANYONE:
+ return ZEN_MODE_FROM_ANYONE;
+ case ZenPolicy.PEOPLE_TYPE_CONTACTS:
+ return ZEN_MODE_FROM_CONTACTS;
+ case ZenPolicy.PEOPLE_TYPE_STARRED:
+ return ZEN_MODE_FROM_STARRED;
+ case ZenPolicy.PEOPLE_TYPE_NONE:
+ default:
+ return ZEN_MODE_FROM_NONE;
+ }
+ }
+
protected static String getKeyFromSetting(int contactType) {
switch (contactType) {
case NotificationManager.Policy.PRIORITY_SENDERS_ANY:
@@ -288,6 +309,50 @@
}
}
+ protected int getContactsCallsSummary(ZenPolicy policy) {
+ int peopleType = policy.getPriorityCallSenders();
+ switch (peopleType) {
+ case ZenPolicy.PEOPLE_TYPE_ANYONE:
+ return R.string.zen_mode_from_anyone;
+ case ZenPolicy.PEOPLE_TYPE_CONTACTS:
+ return R.string.zen_mode_from_contacts;
+ case ZenPolicy.PEOPLE_TYPE_STARRED:
+ return R.string.zen_mode_from_starred;
+ case ZenPolicy.PEOPLE_TYPE_NONE:
+ default:
+ return R.string.zen_mode_from_none_calls;
+ }
+ }
+
+ protected int getContactsMessagesSummary(ZenPolicy policy) {
+ int peopleType = policy.getPriorityMessageSenders();
+ switch (peopleType) {
+ case ZenPolicy.PEOPLE_TYPE_ANYONE:
+ return R.string.zen_mode_from_anyone;
+ case ZenPolicy.PEOPLE_TYPE_CONTACTS:
+ return R.string.zen_mode_from_contacts;
+ case ZenPolicy.PEOPLE_TYPE_STARRED:
+ return R.string.zen_mode_from_starred;
+ case ZenPolicy.PEOPLE_TYPE_NONE:
+ default:
+ return R.string.zen_mode_from_none_messages;
+ }
+ }
+
+ protected static int getZenPolicySettingFromPrefKey(String key) {
+ switch (key) {
+ case ZEN_MODE_FROM_ANYONE:
+ return ZenPolicy.PEOPLE_TYPE_ANYONE;
+ case ZEN_MODE_FROM_CONTACTS:
+ return ZenPolicy.PEOPLE_TYPE_CONTACTS;
+ case ZEN_MODE_FROM_STARRED:
+ return ZenPolicy.PEOPLE_TYPE_STARRED;
+ case ZEN_MODE_FROM_NONE:
+ default:
+ return ZenPolicy.PEOPLE_TYPE_NONE;
+ }
+ }
+
protected static int getSettingFromPrefKey(String key) {
switch (key) {
case ZEN_MODE_FROM_ANYONE:
@@ -318,6 +383,40 @@
}
}
+ ZenPolicy setDefaultZenPolicy(ZenPolicy zenPolicy) {
+ int calls;
+ if (mPolicy.allowCalls()) {
+ calls = ZenModeConfig.getZenPolicySenders(mPolicy.allowCallsFrom());
+ } else {
+ calls = ZenPolicy.PEOPLE_TYPE_NONE;
+ }
+
+ int messages;
+ if (mPolicy.allowMessages()) {
+ messages = ZenModeConfig.getZenPolicySenders(mPolicy.allowMessagesFrom());
+ } else {
+ messages = ZenPolicy.PEOPLE_TYPE_NONE;
+ }
+
+ return new ZenPolicy.Builder(zenPolicy)
+ .allowAlarms(mPolicy.allowAlarms())
+ .allowCalls(calls)
+ .allowEvents(mPolicy.allowEvents())
+ .allowMedia(mPolicy.allowMedia())
+ .allowMessages(messages)
+ .allowReminders(mPolicy.allowReminders())
+ .allowRepeatCallers(mPolicy.allowRepeatCallers())
+ .allowSystem(mPolicy.allowSystem())
+ .showFullScreenIntent(mPolicy.showFullScreenIntents())
+ .showLights(mPolicy.showLights())
+ .showInAmbientDisplay(mPolicy.showAmbient())
+ .showInNotificationList(mPolicy.showInNotificationList())
+ .showBadges(mPolicy.showBadges())
+ .showPeeking(mPolicy.showPeeking())
+ .showStatusBarIcons(mPolicy.showStatusBarIcons())
+ .build();
+ }
+
protected Map.Entry<String, AutomaticZenRule>[] getAutomaticZenRules() {
Map<String, AutomaticZenRule> ruleMap =
NotificationManager.from(mContext).getAutomaticZenRules();
@@ -338,6 +437,70 @@
return mDefaultRuleIds;
}
+ NotificationManager.Policy toNotificationPolicy(ZenPolicy policy) {
+ ZenModeConfig config = new ZenModeConfig();
+ return config.toNotificationPolicy(policy);
+ }
+
+ @VisibleForTesting
+ List<String> getStarredContacts(Cursor cursor) {
+ List<String> starredContacts = new ArrayList<>();
+ if (cursor != null && cursor.moveToFirst()) {
+ do {
+ String contact = cursor.getString(0);
+ if (contact != null) {
+ starredContacts.add(contact);
+ }
+ } while (cursor.moveToNext());
+ }
+ return starredContacts;
+ }
+
+ private List<String> getStarredContacts() {
+ Cursor cursor = null;
+ try {
+ cursor = queryData();
+ return getStarredContacts(cursor);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+
+ public String getStarredContactsSummary() {
+ List<String> starredContacts = getStarredContacts();
+ int numStarredContacts = starredContacts.size();
+
+ List<String> displayContacts = new ArrayList<>();
+
+ if (numStarredContacts == 0) {
+ displayContacts.add(mContext.getString(R.string.zen_mode_from_none));
+ } else {
+ for (int i = 0; i < 2 && i < numStarredContacts; i++) {
+ displayContacts.add(starredContacts.get(i));
+ }
+
+ if (numStarredContacts == 3) {
+ displayContacts.add(starredContacts.get(2));
+ } else if (numStarredContacts > 2) {
+ displayContacts.add(mContext.getResources().getQuantityString(
+ R.plurals.zen_mode_starred_contacts_summary_additional_contacts,
+ numStarredContacts - 2, numStarredContacts - 2));
+ }
+ }
+
+ // values in displayContacts must not be null
+ return ListFormatter.getInstance().format(displayContacts);
+ }
+
+ private Cursor queryData() {
+ return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
+ new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
+ ContactsContract.Data.STARRED + "=1", null,
+ ContactsContract.Data.TIMES_CONTACTED);
+ }
+
@VisibleForTesting
public static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
new Comparator<Map.Entry<String, AutomaticZenRule>>() {
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index e573884..46162a8 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -30,13 +30,15 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settings.core.SubSettingLauncher;
public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
protected static final String TAG = ZenModeSettingsBase.TAG;
protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
+ private final String CUSTOM_BEHAVIOR_KEY = "zen_custom_setting";
+
protected Context mContext;
protected boolean mDisableListeners;
protected AutomaticZenRule mRule;
@@ -45,6 +47,7 @@
protected ZenAutomaticRuleHeaderPreferenceController mHeader;
protected ZenRuleButtonsPreferenceController mActionButtons;
protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
+ protected Preference mCustomBehaviorPreference;
abstract protected void onCreateInternal();
abstract protected boolean setRule(AutomaticZenRule rule);
@@ -75,6 +78,21 @@
}
super.onCreate(icicle);
+ mCustomBehaviorPreference = getPreferenceScreen().findPreference(CUSTOM_BEHAVIOR_KEY);
+ mCustomBehaviorPreference.setOnPreferenceClickListener(
+ new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Bundle bundle = new Bundle();
+ bundle.putString(ZenCustomRuleSettings.RULE_ID, mId);
+ new SubSettingLauncher(mContext)
+ .setDestination(ZenCustomRuleSettings.class.getName())
+ .setArguments(bundle)
+ .setSourceMetricsCategory(0) // TODO
+ .launch();
+ return true;
+ }
+ });
onCreateInternal();
}
@@ -84,7 +102,9 @@
if (isUiRestricted()) {
return;
}
- updateControls();
+ if (!refreshRuleOrFinish()) {
+ updateControls();
+ }
}
@Override
@@ -111,22 +131,6 @@
updatePreference(mActionButtons);
}
- private void updatePreference(AbstractPreferenceController controller) {
- final PreferenceScreen screen = getPreferenceScreen();
- if (!controller.isAvailable()) {
- return;
- }
- final String key = controller.getPreferenceKey();
-
- final Preference preference = screen.findPreference(key);
- if (preference == null) {
- Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
- key, controller.getClass().getSimpleName()));
- return;
- }
- controller.updateState(preference);
- }
-
protected void updateRule(Uri newConditionId) {
mRule.setConditionId(newConditionId);
mBackend.updateZenRule(mId, mRule);
@@ -165,6 +169,11 @@
mDisableListeners = true;
updateControlsInternal();
updateHeader();
+ if (mRule.getZenPolicy() == null) {
+ mCustomBehaviorPreference.setSummary(R.string.zen_mode_custom_behavior_summary_default);
+ } else {
+ mCustomBehaviorPreference.setSummary(R.string.zen_mode_custom_behavior_summary);
+ }
mDisableListeners = false;
}
}
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index a3f59c6..bdf80a6 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -90,7 +90,8 @@
controllers.add(new ZenModeDurationPreferenceController(context, lifecycle));
controllers.add(new ZenModeAutomationPreferenceController(context));
controllers.add(new ZenModeButtonPreferenceController(context, lifecycle, fragmentManager));
- controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeSettingsFooterPreferenceController(context, lifecycle,
+ fragmentManager));
return controllers;
}
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index b9a14ee..3f53879 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -26,7 +26,11 @@
import android.provider.Settings.Global;
import android.util.Log;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
abstract public class ZenModeSettingsBase extends RestrictedDashboardFragment {
protected static final String TAG = "ZenModeSettings";
@@ -121,4 +125,20 @@
}
}
}
+
+ void updatePreference(AbstractPreferenceController controller) {
+ final PreferenceScreen screen = getPreferenceScreen();
+ if (!controller.isAvailable()) {
+ return;
+ }
+ final String key = controller.getPreferenceKey();
+
+ final Preference preference = screen.findPreference(key);
+ if (preference == null) {
+ Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
+ key, controller.getClass().getSimpleName()));
+ return;
+ }
+ controller.updateState(preference);
+ }
}
diff --git a/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceController.java b/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceController.java
index f69eac7..7c2464c 100644
--- a/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceController.java
@@ -16,17 +16,29 @@
package com.android.settings.notification;
+import android.app.Dialog;
import android.app.NotificationManager;
import android.content.Context;
+import android.content.DialogInterface;
import android.icu.text.ListFormatter;
import android.net.Uri;
+import android.os.Bundle;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
-import android.util.Log;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+import androidx.appcompat.app.AlertDialog;
+import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.utils.AnnotationSpan;
import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
@@ -34,11 +46,13 @@
import java.util.Objects;
public class ZenModeSettingsFooterPreferenceController extends AbstractZenModePreferenceController {
+ static final String KEY = "footer_preference";
+ private FragmentManager mFragment;
- protected static final String KEY = "footer_preference";
-
- public ZenModeSettingsFooterPreferenceController(Context context, Lifecycle lifecycle) {
+ public ZenModeSettingsFooterPreferenceController(Context context, Lifecycle lifecycle,
+ FragmentManager fragment) {
super(context, KEY, lifecycle);
+ mFragment = fragment;
}
@Override
@@ -70,7 +84,7 @@
}
}
- protected String getFooterText() {
+ protected CharSequence getFooterText() {
ZenModeConfig config = getZenModeConfig();
NotificationManager.Policy appliedPolicy = mBackend.getConsolidatedPolicy();
@@ -88,15 +102,25 @@
if (rulesNames.size() > 0) {
String rules = ListFormatter.getInstance().format(rulesNames);
if (!rules.isEmpty()) {
- return mContext.getString(R.string.zen_mode_settings_dnd_custom_settings_footer,
- rules);
+ final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
+ AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showCustomSettingsDialog();
+ }
+ });
+ return TextUtils.concat(mContext.getResources().getString(
+ R.string.zen_mode_settings_dnd_custom_settings_footer, rules),
+ AnnotationSpan.linkify(mContext.getResources().getText(
+ R.string.zen_mode_settings_dnd_custom_settings_footer_link),
+ linkInfo));
}
}
}
- return getFooterUsingDefaultPolicy(config);
+ return getDefaultPolicyFooter(config);
}
- private String getFooterUsingDefaultPolicy(ZenModeConfig config) {
+ private String getDefaultPolicyFooter(ZenModeConfig config) {
String footerText = "";
long latestEndTime = -1;
@@ -162,4 +186,101 @@
}
return zenRules;
}
+
+ private void showCustomSettingsDialog() {
+ ZenCustomSettingsDialog dialog = new ZenCustomSettingsDialog();
+ dialog.setNotificationPolicy(mBackend.getConsolidatedPolicy());
+ dialog.show(mFragment, ZenCustomSettingsDialog.class.getName());
+ }
+
+ public static class ZenCustomSettingsDialog extends InstrumentedDialogFragment {
+ private String KEY_POLICY = "policy";
+ private NotificationManager.Policy mPolicy;
+ private ZenModeSettings.SummaryBuilder mSummaryBuilder;
+
+ public void setNotificationPolicy(NotificationManager.Policy policy) {
+ mPolicy = policy;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Context context = getActivity();
+ if (savedInstanceState != null) {
+ NotificationManager.Policy policy = savedInstanceState.getParcelable(KEY_POLICY);
+ if (policy != null) {
+ mPolicy = policy;
+ }
+ }
+
+ mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
+
+ AlertDialog customSettingsDialog = new AlertDialog.Builder(context)
+ .setTitle(R.string.zen_custom_settings_dialog_title)
+ .setNeutralButton(R.string.zen_custom_settings_dialog_review_schedule,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+ new SubSettingLauncher(context)
+ .setDestination(
+ ZenModeAutomationSettings.class.getName())
+ .setSourceMetricsCategory(
+ MetricsEvent.NOTIFICATION_ZEN_MODE_AUTOMATION)
+ .launch();
+ }
+ })
+ .setPositiveButton(R.string.zen_custom_settings_dialog_ok, null)
+ .setView(LayoutInflater.from(context).inflate(context.getResources().getLayout(
+ R.layout.zen_custom_settings_dialog), null, false))
+ .create();
+
+ customSettingsDialog.setOnShowListener(new DialogInterface.OnShowListener() {
+ @Override
+ public void onShow(DialogInterface dialog) {
+ TextView allowCallsText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_calls_allow);
+ TextView allowMessagesText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_messages_allow);
+ TextView allowAlarmsText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_alarms_allow);
+ TextView allowMediaText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_media_allow);
+ TextView allowSystemText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_system_allow);
+ TextView allowRemindersText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_reminders_allow);
+ TextView allowEventsText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_events_allow);
+ TextView notificationsText = customSettingsDialog.findViewById(
+ R.id.zen_custom_settings_dialog_show_notifications);
+
+ allowCallsText.setText(mSummaryBuilder.getCallsSettingSummary(mPolicy));
+ allowMessagesText.setText(mSummaryBuilder.getMessagesSettingSummary(mPolicy));
+ allowAlarmsText.setText(getAllowRes(mPolicy.allowAlarms()));
+ allowMediaText.setText(getAllowRes(mPolicy.allowMedia()));
+ allowSystemText.setText(getAllowRes(mPolicy.allowSystem()));
+ allowRemindersText.setText(getAllowRes(mPolicy.allowReminders()));
+ allowEventsText.setText(getAllowRes(mPolicy.allowEvents()));
+ notificationsText.setText(mSummaryBuilder.getBlockedEffectsSummary(mPolicy));
+ }
+ });
+
+ return customSettingsDialog;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.ZEN_CUSTOM_SETTINGS_DIALOG;
+ }
+
+ private int getAllowRes(boolean allow) {
+ return allow ? R.string.zen_mode_sound_summary_on : R.string.zen_mode_sound_summary_off;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putParcelable(KEY_POLICY, mPolicy);
+ }
+ }
}
diff --git a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
index 66c2ddd..e5982eb 100644
--- a/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
+++ b/src/com/android/settings/notification/ZenModeStarredContactsPreferenceController.java
@@ -23,25 +23,15 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.icu.text.ListFormatter;
import android.provider.Contacts;
-import android.provider.ContactsContract;
-import com.android.settings.R;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
public class ZenModeStarredContactsPreferenceController extends
AbstractZenModePreferenceController implements Preference.OnPreferenceClickListener {
-
- protected static String KEY;
private Preference mPreference;
private final int mPriorityCategory;
private final PackageManager mPackageManager;
@@ -52,8 +42,6 @@
public ZenModeStarredContactsPreferenceController(Context context, Lifecycle lifecycle, int
priorityCategory, String key) {
super(context, key, lifecycle);
- KEY = key;
-
mPriorityCategory = priorityCategory;
mPackageManager = mContext.getPackageManager();
@@ -96,29 +84,7 @@
@Override
public CharSequence getSummary() {
- List<String> starredContacts = getStarredContacts();
- int numStarredContacts = starredContacts.size();
-
- List<String> displayContacts = new ArrayList<>();
-
- if (numStarredContacts == 0) {
- displayContacts.add(mContext.getString(R.string.zen_mode_from_none));
- } else {
- for (int i = 0; i < 2 && i < numStarredContacts; i++) {
- displayContacts.add(starredContacts.get(i));
- }
-
- if (numStarredContacts == 3) {
- displayContacts.add(starredContacts.get(2));
- } else if (numStarredContacts > 2) {
- displayContacts.add(mContext.getResources().getQuantityString(
- R.plurals.zen_mode_starred_contacts_summary_additional_contacts,
- numStarredContacts - 2, numStarredContacts - 2));
- }
- }
-
- // values in displayContacts must not be null
- return ListFormatter.getInstance().format(displayContacts);
+ return mBackend.getStarredContactsSummary();
}
@Override
@@ -131,39 +97,6 @@
return true;
}
- @VisibleForTesting
- List<String> getStarredContacts(Cursor cursor) {
- List<String> starredContacts = new ArrayList<>();
- if (cursor.moveToFirst()) {
- do {
- String contact = cursor.getString(0);
- if (contact != null) {
- starredContacts.add(contact);
- }
- } while (cursor.moveToNext());
- }
- return starredContacts;
- }
-
- private List<String> getStarredContacts() {
- Cursor cursor = null;
- try {
- cursor = queryData();
- return getStarredContacts(cursor);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
- }
-
- private Cursor queryData() {
- return mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
- new String[]{ContactsContract.Contacts.DISPLAY_NAME_PRIMARY},
- ContactsContract.Data.STARRED + "=1", null,
- ContactsContract.Data.TIMES_CONTACTED);
- }
-
private boolean isIntentValid() {
return mStarredContactsIntent.resolveActivity(mPackageManager) != null
|| mFallbackIntent.resolveActivity(mPackageManager) != null;
diff --git a/src/com/android/settings/notification/ZenRuleCallsPreferenceController.java b/src/com/android/settings/notification/ZenRuleCallsPreferenceController.java
new file mode 100644
index 0000000..b27c5fe
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleCallsPreferenceController.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleCallsPreferenceController extends AbstractZenCustomRulePreferenceController
+ implements Preference.OnPreferenceChangeListener {
+
+ private final String[] mListValues;
+
+ public ZenRuleCallsPreferenceController(Context context, String key, Lifecycle lifecycle) {
+ super(context, key, lifecycle);
+ mListValues = context.getResources().getStringArray(
+ com.android.settings.R.array.zen_mode_contacts_values);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ updateFromContactsValue(preference);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
+ int allowCalls = ZenModeBackend.getZenPolicySettingFromPrefKey(
+ selectedContactsFrom.toString());
+ mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_CALLS,
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allowCalls),
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .allowCalls(allowCalls)
+ .build());
+ mBackend.updateZenRule(mId, mRule);
+ updateFromContactsValue(preference);
+ return true;
+ }
+
+ private void updateFromContactsValue(Preference preference) {
+ if (mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+ ListPreference listPreference = (ListPreference) preference;
+ listPreference.setSummary(mBackend.getContactsCallsSummary(mRule.getZenPolicy()));
+ final String currentVal = ZenModeBackend.getKeyFromZenPolicySetting(
+ mRule.getZenPolicy().getPriorityCallSenders());
+ listPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
+
+ }
+
+ @VisibleForTesting
+ protected int getIndexOfSendersValue(String currentVal) {
+ int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
+ for (int i = 0; i < mListValues.length; i++) {
+ if (TextUtils.equals(currentVal, mListValues[i])) {
+ return i;
+ }
+ }
+
+ return index;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenRuleCustomPolicyPreferenceController.java b/src/com/android/settings/notification/ZenRuleCustomPolicyPreferenceController.java
new file mode 100644
index 0000000..39de0eb
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleCustomPolicyPreferenceController.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleCustomPolicyPreferenceController extends
+ AbstractZenCustomRulePreferenceController {
+
+ private ZenCustomRadioButtonPreference mPreference;
+
+ public ZenRuleCustomPolicyPreferenceController(Context context, Lifecycle lifecycle,
+ String key) {
+ super(context, key, lifecycle);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
+
+ mPreference.setOnGearClickListener(p -> {
+ setCustomPolicy();
+ launchCustomSettings();
+
+ });
+
+ mPreference.setOnRadioButtonClickListener(p -> {
+ setCustomPolicy();
+ launchCustomSettings();
+ });
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mId == null || mRule == null) {
+ return;
+ }
+
+ mPreference.setChecked(mRule.getZenPolicy() != null);
+ }
+
+ private void setCustomPolicy() {
+ if (mRule.getZenPolicy() == null) {
+ mRule.setZenPolicy(mBackend.setDefaultZenPolicy(new ZenPolicy()));
+ mBackend.updateZenRule(mId, mRule);
+ }
+ }
+
+ private void launchCustomSettings() {
+ new SubSettingLauncher(mContext)
+ .setDestination(ZenCustomRuleConfigSettings.class.getName())
+ .setArguments(createBundle())
+ .setSourceMetricsCategory(MetricsProto.MetricsEvent.ZEN_CUSTOM_RULE_SOUND_SETTINGS)
+ .launch();
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenRuleCustomSwitchPreferenceController.java b/src/com/android/settings/notification/ZenRuleCustomSwitchPreferenceController.java
new file mode 100644
index 0000000..804469e
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleCustomSwitchPreferenceController.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.preference.Preference;
+import androidx.preference.SwitchPreference;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleCustomSwitchPreferenceController extends
+ AbstractZenCustomRulePreferenceController implements Preference.OnPreferenceChangeListener {
+
+ private @ZenPolicy.PriorityCategory int mCategory;
+ private int mMetricsCategory;
+
+ public ZenRuleCustomSwitchPreferenceController(Context context, Lifecycle lifecycle,
+ String key, @ZenPolicy.PriorityCategory int category, int metricsCategory) {
+ super(context, key, lifecycle);
+ mCategory = category;
+ mMetricsCategory = metricsCategory;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ pref.setChecked(mRule.getZenPolicy().isCategoryAllowed(mCategory, false));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allow = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, KEY + " onPrefChange mRule=" + mRule + " mCategory=" + mCategory
+ + " allow=" + allow);
+ }
+ mMetricsFeatureProvider.action(mContext, mMetricsCategory,
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allow ? 1 : 0),
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .allowCategory(mCategory, allow)
+ .build());
+ mBackend.updateZenRule(mId, mRule);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenRuleDefaultPolicyPreferenceController.java b/src/com/android/settings/notification/ZenRuleDefaultPolicyPreferenceController.java
new file mode 100644
index 0000000..857d853
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleDefaultPolicyPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.util.Pair;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleDefaultPolicyPreferenceController extends
+ AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
+
+ private ZenCustomRadioButtonPreference mPreference;
+
+ public ZenRuleDefaultPolicyPreferenceController(Context context, Lifecycle lifecycle,
+ String key) {
+ super(context, key, lifecycle);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
+
+ mPreference.setOnRadioButtonClickListener(p -> {
+ mRule.setZenPolicy(null);
+ mBackend.updateZenRule(mId, mRule);
+ });
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mId == null || mRule == null) {
+ return;
+ }
+ mMetricsFeatureProvider.action(mContext, MetricsEvent.ZEN_CUSTOM_RULE_DEFAULT_SETTINGS,
+ Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ mPreference.setChecked(mRule.getZenPolicy() == null);
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenRuleMessagesPreferenceController.java b/src/com/android/settings/notification/ZenRuleMessagesPreferenceController.java
new file mode 100644
index 0000000..010e152
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleMessagesPreferenceController.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleMessagesPreferenceController extends AbstractZenCustomRulePreferenceController
+ implements Preference.OnPreferenceChangeListener {
+
+ private final String[] mListValues;
+
+ public ZenRuleMessagesPreferenceController(Context context, String key, Lifecycle lifecycle) {
+ super(context, key, lifecycle);
+ mListValues = context.getResources().getStringArray(
+ com.android.settings.R.array.zen_mode_contacts_values);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ updateFromContactsValue(preference);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object selectedContactsFrom) {
+ int allowMessages = ZenModeBackend.getZenPolicySettingFromPrefKey(
+ selectedContactsFrom.toString());
+ mMetricsFeatureProvider.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_MESSAGES,
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allowMessages),
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .allowMessages(allowMessages)
+ .build());
+ mBackend.updateZenRule(mId, mRule);
+ updateFromContactsValue(preference);
+ return true;
+ }
+
+ private void updateFromContactsValue(Preference preference) {
+ if (mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+ ListPreference listPreference = (ListPreference) preference;
+ listPreference.setSummary(mBackend.getContactsMessagesSummary(mRule.getZenPolicy()));
+ final String currentVal = ZenModeBackend.getKeyFromZenPolicySetting(
+ mRule.getZenPolicy().getPriorityMessageSenders());
+ listPreference.setValue(mListValues[getIndexOfSendersValue(currentVal)]);
+
+ }
+
+ @VisibleForTesting
+ protected int getIndexOfSendersValue(String currentVal) {
+ int index = 3; // defaults to "none" based on R.array.zen_mode_contacts_values
+ for (int i = 0; i < mListValues.length; i++) {
+ if (TextUtils.equals(currentVal, mListValues[i])) {
+ return i;
+ }
+ }
+
+ return index;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenRuleNotifFooterPreferenceController.java b/src/com/android/settings/notification/ZenRuleNotifFooterPreferenceController.java
new file mode 100644
index 0000000..678bf90
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleNotifFooterPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleNotifFooterPreferenceController extends
+ AbstractZenCustomRulePreferenceController {
+
+ public ZenRuleNotifFooterPreferenceController(Context context, Lifecycle lifecycle,
+ String key) {
+ super(context, key, lifecycle);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable() || mRule.getZenPolicy() == null) {
+ return false;
+ }
+
+
+ return mRule.getZenPolicy().shouldHideAllVisualEffects()
+ || mRule.getZenPolicy().shouldShowAllVisualEffects();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+
+ if (mRule.getZenPolicy().shouldShowAllVisualEffects()) {
+ preference.setTitle(R.string.zen_mode_restrict_notifications_mute_footer);
+ } else if (mRule.getZenPolicy().shouldHideAllVisualEffects()) {
+ preference.setTitle(R.string.zen_mode_restrict_notifications_hide_footer);
+ } else {
+ preference.setTitle(null);
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenRuleRepeatCallersPreferenceController.java b/src/com/android/settings/notification/ZenRuleRepeatCallersPreferenceController.java
new file mode 100644
index 0000000..1161bec
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleRepeatCallersPreferenceController.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleRepeatCallersPreferenceController extends
+ AbstractZenCustomRulePreferenceController implements Preference.OnPreferenceChangeListener {
+
+ private final int mRepeatCallersThreshold;
+
+ public ZenRuleRepeatCallersPreferenceController(Context context,
+ String key, Lifecycle lifecycle, int repeatCallersThreshold) {
+ super(context, key, lifecycle);
+ mRepeatCallersThreshold = repeatCallersThreshold;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ setRepeatCallerSummary(screen.findPreference(KEY));
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ boolean anyCallersCanBypassDnd = mRule.getZenPolicy().getPriorityCallSenders()
+ == ZenPolicy.PEOPLE_TYPE_ANYONE;
+
+ // if any caller can bypass dnd then repeat callers preference is disabled
+ if (anyCallersCanBypassDnd) {
+ pref.setEnabled(false);
+ pref.setChecked(true);
+ } else {
+ pref.setEnabled(true);
+ pref.setChecked(mRule.getZenPolicy().getPriorityCategoryRepeatCallers()
+ == ZenPolicy.STATE_ALLOW);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allow = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, KEY + " onPrefChange mRule=" + mRule + " mCategory="
+ + ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS + " allow=" + allow);
+ }
+ mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_REPEAT_CALLS,
+ Pair.create(MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION, allow ? 1 : 0),
+ Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .allowRepeatCallers(allow)
+ .build());
+ mBackend.updateZenRule(mId, mRule);
+ return true;
+ }
+
+ private void setRepeatCallerSummary(Preference preference) {
+ preference.setSummary(mContext.getString(
+ com.android.settings.R.string.zen_mode_repeat_callers_summary,
+ mRepeatCallersThreshold));
+ }
+}
diff --git a/src/com/android/settings/notification/ZenRuleStarredContactsPreferenceController.java b/src/com/android/settings/notification/ZenRuleStarredContactsPreferenceController.java
new file mode 100644
index 0000000..8a227a1
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleStarredContactsPreferenceController.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Contacts;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleStarredContactsPreferenceController extends
+ AbstractZenCustomRulePreferenceController implements Preference.OnPreferenceClickListener {
+
+ private Preference mPreference;
+ private final @ZenPolicy.PriorityCategory int mPriorityCategory;
+ private final PackageManager mPackageManager;
+
+ private Intent mStarredContactsIntent;
+ private Intent mFallbackIntent;
+
+ public ZenRuleStarredContactsPreferenceController(Context context, Lifecycle lifecycle,
+ @ZenPolicy.PriorityCategory int priorityCategory, String key) {
+ super(context, key, lifecycle);
+ mPriorityCategory = priorityCategory;
+ mPackageManager = mContext.getPackageManager();
+
+ mStarredContactsIntent = new Intent(Contacts.Intents.UI.LIST_STARRED_ACTION);
+
+ mFallbackIntent = new Intent(Intent.ACTION_MAIN);
+ mFallbackIntent.addCategory(Intent.CATEGORY_APP_CONTACTS);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(KEY);
+
+ if (mPreference != null) {
+ mPreference.setOnPreferenceClickListener(this);
+ }
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable() || mRule.getZenPolicy() == null || !isIntentValid()) {
+ return false;
+ }
+
+ if (mPriorityCategory == ZenPolicy.PRIORITY_CATEGORY_CALLS) {
+ return mRule.getZenPolicy().getPriorityCallSenders() == ZenPolicy.PEOPLE_TYPE_STARRED;
+ } else if (mPriorityCategory == ZenPolicy.PRIORITY_CATEGORY_MESSAGES) {
+ return mRule.getZenPolicy().getPriorityMessageSenders()
+ == ZenPolicy.PEOPLE_TYPE_STARRED;
+ } else {
+ // invalid category
+ return false;
+ }
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ return mBackend.getStarredContactsSummary();
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ if (mStarredContactsIntent.resolveActivity(mPackageManager) != null) {
+ mContext.startActivity(mStarredContactsIntent);
+ } else {
+ mContext.startActivity(mFallbackIntent);
+ }
+ return true;
+ }
+
+ private boolean isIntentValid() {
+ return mStarredContactsIntent.resolveActivity(mPackageManager) != null
+ || mFallbackIntent.resolveActivity(mPackageManager) != null;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenRuleVisEffectPreferenceController.java b/src/com/android/settings/notification/ZenRuleVisEffectPreferenceController.java
new file mode 100644
index 0000000..94b8234
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleVisEffectPreferenceController.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.CheckBoxPreference;
+import androidx.preference.Preference;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.widget.DisabledCheckBoxPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleVisEffectPreferenceController extends AbstractZenCustomRulePreferenceController
+ implements Preference.OnPreferenceChangeListener {
+
+ private final int mMetricsCategory;
+
+ @VisibleForTesting protected @ZenPolicy.VisualEffect int mEffect;
+
+ // if any of these effects are suppressed, this effect must be too
+ @VisibleForTesting protected @ZenPolicy.VisualEffect int[] mParentSuppressedEffects;
+
+ public ZenRuleVisEffectPreferenceController(Context context, Lifecycle lifecycle, String key,
+ @ZenPolicy.VisualEffect int visualEffect, int metricsCategory,
+ @ZenPolicy.VisualEffect int[] parentSuppressedEffects) {
+ super(context, key, lifecycle);
+ mEffect = visualEffect;
+ mMetricsCategory = metricsCategory;
+ mParentSuppressedEffects = parentSuppressedEffects;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ if (!super.isAvailable()) {
+ return false;
+ }
+
+ if (mEffect == ZenPolicy.VISUAL_EFFECT_LIGHTS) {
+ return mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed);
+ }
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+
+ boolean suppressed = !mRule.getZenPolicy().isVisualEffectAllowed(mEffect, false);
+ boolean parentSuppressed = false;
+ if (mParentSuppressedEffects != null) {
+ for (@ZenPolicy.VisualEffect int parentEffect : mParentSuppressedEffects) {
+ if (!mRule.getZenPolicy().isVisualEffectAllowed(parentEffect, true)) {
+ parentSuppressed = true;
+ }
+ }
+ }
+ if (parentSuppressed) {
+ ((CheckBoxPreference) preference).setChecked(parentSuppressed);
+ onPreferenceChange(preference, parentSuppressed);
+ ((DisabledCheckBoxPreference) preference).enableCheckbox(false);
+ } else {
+ ((DisabledCheckBoxPreference) preference).enableCheckbox(true);
+ ((CheckBoxPreference) preference).setChecked(suppressed);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean suppressEffect = (Boolean) newValue;
+ mMetricsFeatureProvider.action(mContext, mMetricsCategory,
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_TOGGLE_EXCEPTION,
+ suppressEffect ? 1 : 0),
+ Pair.create(MetricsProto.MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .showVisualEffect(mEffect, !suppressEffect)
+ .build());
+ mBackend.updateZenRule(mId, mRule);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenRuleVisEffectsAllPreferenceController.java b/src/com/android/settings/notification/ZenRuleVisEffectsAllPreferenceController.java
new file mode 100644
index 0000000..9ddd624
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleVisEffectsAllPreferenceController.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleVisEffectsAllPreferenceController extends
+ AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
+
+ private ZenCustomRadioButtonPreference mPreference;
+
+ public ZenRuleVisEffectsAllPreferenceController(Context context, Lifecycle lifecycle,
+ String key) {
+ super(context, key, lifecycle);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
+
+ mPreference.setOnRadioButtonClickListener(p -> {
+ mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_SOUND_ONLY,
+ Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .showAllVisualEffects()
+ .build());
+ mBackend.updateZenRule(mId, mRule);
+ });
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mId == null || mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+ mPreference.setChecked(mRule.getZenPolicy().shouldShowAllVisualEffects());
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenRuleVisEffectsCustomPreferenceController.java b/src/com/android/settings/notification/ZenRuleVisEffectsCustomPreferenceController.java
new file mode 100644
index 0000000..64dd71c
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleVisEffectsCustomPreferenceController.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.util.Pair;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleVisEffectsCustomPreferenceController extends
+ AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
+
+ private ZenCustomRadioButtonPreference mPreference;
+
+ public ZenRuleVisEffectsCustomPreferenceController(Context context, Lifecycle lifecycle,
+ String key) {
+ super(context, key, lifecycle);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
+
+ mPreference.setOnGearClickListener(p -> {
+ launchCustomSettings();
+
+ });
+
+ mPreference.setOnRadioButtonClickListener(p -> {
+ launchCustomSettings();
+ });
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mId == null || mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+
+ mPreference.setChecked(!mRule.getZenPolicy().shouldHideAllVisualEffects()
+ && !mRule.getZenPolicy().shouldShowAllVisualEffects());
+ }
+
+ private void launchCustomSettings() {
+ mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_SHOW_CUSTOM,
+ Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ new SubSettingLauncher(mContext)
+ .setDestination(ZenCustomRuleBlockedEffectsSettings.class.getName())
+ .setArguments(createBundle())
+ .setSourceMetricsCategory(MetricsEvent.ZEN_CUSTOM_RULE_VIS_EFFECTS)
+ .launch();
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenRuleVisEffectsNonePreferenceController.java b/src/com/android/settings/notification/ZenRuleVisEffectsNonePreferenceController.java
new file mode 100644
index 0000000..4f98924
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRuleVisEffectsNonePreferenceController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+import android.util.Log;
+import android.util.Pair;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenRuleVisEffectsNonePreferenceController extends
+ AbstractZenCustomRulePreferenceController implements PreferenceControllerMixin {
+
+ private ZenCustomRadioButtonPreference mPreference;
+
+ public ZenRuleVisEffectsNonePreferenceController(Context context, Lifecycle lifecycle,
+ String key) {
+ super(context, key, lifecycle);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = (ZenCustomRadioButtonPreference) screen.findPreference(getPreferenceKey());
+
+ mPreference.setOnRadioButtonClickListener(p -> {
+ mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_SOUND_AND_VIS_EFFECTS,
+ Pair.create(MetricsEvent.FIELD_ZEN_RULE_ID, mId));
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .hideAllVisualEffects()
+ .build());
+ mBackend.updateZenRule(mId, mRule);
+ });
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (mId == null || mRule == null || mRule.getZenPolicy() == null) {
+ return;
+ }
+
+ mPreference.setChecked(mRule.getZenPolicy().shouldHideAllVisualEffects());
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/slices/Copyable.java b/src/com/android/settings/slices/Copyable.java
index 12159d1..a480063 100644
--- a/src/com/android/settings/slices/Copyable.java
+++ b/src/com/android/settings/slices/Copyable.java
@@ -16,6 +16,15 @@
package com.android.settings.slices;
+import static android.content.Context.CLIPBOARD_SERVICE;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
+import android.widget.Toast;
+
+import com.android.settings.R;
+
/**
* Provide the copy ability for preference controller to copy the data to the clipboard.
*/
@@ -25,4 +34,18 @@
* It is highly recommended to show the toast to notify users when implemented this function.
*/
void copy();
+
+ /**
+ * Set the copy content to the clipboard and show the toast.
+ */
+ static void setCopyContent(Context context, CharSequence copyContent,
+ CharSequence messageTitle) {
+ final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(
+ CLIPBOARD_SERVICE);
+ final ClipData clip = ClipData.newPlainText("text", copyContent);
+ clipboard.setPrimaryClip(clip);
+
+ final String toast = context.getString(R.string.copyable_slice_toast, messageTitle);
+ Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
+ }
}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 30c2cd9..7a1bdb4 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -16,6 +16,7 @@
package com.android.settings.wifi;
+import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -328,8 +329,12 @@
@Override
public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
- // Dismisses current dialog, since connection is success.
+ // Dismisses current dialog and finishes Activity, since connection is success.
dismiss();
+ final Activity activity = getActivity();
+ if (activity != null) {
+ activity.finish();
+ }
}
@Override
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index f3e8fc1..fe71991 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -549,8 +549,8 @@
* Show QR code to share the network represented by this preference.
*/
public void launchQRCodeGenerator() {
- Intent intent = WifiDppUtils.getConfiguratorQrCodeGeneratorIntent(mAccessPoint.getSsidStr(),
- mAccessPoint.getSecurityString(/* concise */ false));
+ Intent intent = WifiDppUtils.getConfiguratorQrCodeGeneratorIntent(mContext, mWifiManager,
+ mAccessPoint);
mContext.startActivity(intent);
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
index 8d6aa68..90fb850 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppAddDeviceFragment.java
@@ -17,6 +17,13 @@
package com.android.settings.wifi.dpp;
import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -26,10 +33,11 @@
* to the Wi-Fi network.
*/
public class WifiDppAddDeviceFragment extends WifiDppQrCodeBaseFragment {
- @Override
- protected int getLayout() {
- return R.layout.wifi_dpp_add_device_fragment;
- }
+ private ProgressBar mProgressBar;
+ private ImageView mWifiApPictureView;
+ private TextView mChooseDifferentNetwork;
+ private Button mButtonLeft;
+ private Button mButtonRight;
@Override
public int getMetricsCategory() {
@@ -37,7 +45,20 @@
}
@Override
- public void onActivityCreated (Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
+ public final View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.wifi_dpp_add_device_fragment, container,
+ /* attachToRoot */ false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mProgressBar = view.findViewById(R.id.progress_bar);
+ mWifiApPictureView = view.findViewById(R.id.wifi_ap_picture_view);
+ mChooseDifferentNetwork = view.findViewById(R.id.choose_different_network);
+ mButtonLeft = view.findViewById(R.id.button_left);
+ mButtonRight = view.findViewById(R.id.button_right);
}
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java b/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
index 66bc349..a3e6db3 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppChooseSavedWifiNetworkFragment.java
@@ -17,6 +17,11 @@
package com.android.settings.wifi.dpp;
import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ListView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -26,10 +31,9 @@
* {@code WifiDppConfiguratorActivity} to start with this fragment to choose a saved Wi-Fi network.
*/
public class WifiDppChooseSavedWifiNetworkFragment extends WifiDppQrCodeBaseFragment {
- @Override
- protected int getLayout() {
- return R.layout.wifi_dpp_choose_saved_wifi_network_fragment;
- }
+ private ListView mSavedWifiNetworkList;
+ private Button mButtonLeft;
+ private Button mButtonRight;
@Override
public int getMetricsCategory() {
@@ -37,7 +41,18 @@
}
@Override
- public void onActivityCreated (Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
+ public final View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.wifi_dpp_choose_saved_wifi_network_fragment, container,
+ /* attachToRoot */ false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mSavedWifiNetworkList = view.findViewById(R.id.saved_wifi_network_list);
+ mButtonLeft = view.findViewById(R.id.button_left);
+ mButtonRight = view.findViewById(R.id.button_right);
}
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
index 6c95f09..e89ebaa 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java
@@ -49,7 +49,9 @@
*/
public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
WifiNetworkConfig.Retriever,
- WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener {
+ WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener,
+ WifiDppQrCodeScannerFragment.OnScanWifiDppSuccessListener,
+ WifiDppQrCodeScannerFragment.OnScanZxingWifiFormatSuccessListener {
private static final String TAG = "WifiDppConfiguratorActivity";
public static final String ACTION_CONFIGURATOR_QR_CODE_SCANNER =
@@ -64,6 +66,12 @@
/** The Wi-Fi network which will be configured */
private WifiNetworkConfig mWifiNetworkConfig;
+ /** The public key from Wi-Fi DPP QR code */
+ private String mPublicKey;
+
+ /** The information from Wi-Fi DPP QR code */
+ private String mInformation;
+
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
@@ -127,8 +135,8 @@
return;
}
- WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
- FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+ final WifiDppQrCodeScannerFragment fragment = new WifiDppQrCodeScannerFragment();
+ final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment,
WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
@@ -145,8 +153,8 @@
return;
}
- WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
- FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+ final WifiDppQrCodeGeneratorFragment fragment = new WifiDppQrCodeGeneratorFragment();
+ final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment,
WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
@@ -160,9 +168,9 @@
return;
}
- WifiDppChooseSavedWifiNetworkFragment fragment =
+ final WifiDppChooseSavedWifiNetworkFragment fragment =
new WifiDppChooseSavedWifiNetworkFragment();
- FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+ final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment,
WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
@@ -172,11 +180,38 @@
fragmentTransaction.commit();
}
+ private void showAddDeviceFragment(boolean addToBackStack) {
+ // Avoid to replace the same fragment during configuration change
+ if (mFragmentManager.findFragmentByTag(
+ WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE) != null) {
+ return;
+ }
+
+ final WifiDppAddDeviceFragment fragment =
+ new WifiDppAddDeviceFragment();
+ final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
+
+ fragmentTransaction.replace(R.id.fragment_container, fragment,
+ WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE);
+ if (addToBackStack) {
+ fragmentTransaction.addToBackStack(/* name */ null);
+ }
+ fragmentTransaction.commit();
+ }
+
@Override
public WifiNetworkConfig getWifiNetworkConfig() {
return mWifiNetworkConfig;
}
+ public String getPublicKey() {
+ return mPublicKey;
+ }
+
+ public String getInformation() {
+ return mInformation;
+ }
+
@Override
public boolean setWifiNetworkConfig(WifiNetworkConfig config) {
if(!WifiNetworkConfig.isValidConfig(config)) {
@@ -201,7 +236,26 @@
return false;
}
- @Override public void onQrCodeGeneratorFragmentAddButtonClicked() {
+ @Override
+ public void onQrCodeGeneratorFragmentAddButtonClicked() {
showQrCodeScannerFragment(/* addToBackStack */ true);
}
+
+ @Override
+ public void onScanWifiDppSuccess(String publicKey, String information) {
+ mPublicKey = publicKey;
+ mInformation = information;
+ mWifiNetworkConfig = null;
+
+ showAddDeviceFragment(/* addToBackStack */ true);
+ }
+
+ @Override
+ public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig) {
+ mPublicKey = null;
+ mInformation = null;
+ mWifiNetworkConfig = new WifiNetworkConfig(wifiNetworkConfig);
+
+ showAddDeviceFragment(/* addToBackStack */ true);
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
index 920e736..584a819 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivity.java
@@ -16,9 +16,11 @@
package com.android.settings.wifi.dpp;
+import android.provider.Settings;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
+import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
@@ -36,7 +38,10 @@
* To use intent action {@code ACTION_ENROLLEE_QR_CODE_SCANNER}, specify the SSID string of the
* Wi-Fi network to be provisioned in {@code WifiDppUtils.EXTRA_WIFI_SSID}.
*/
-public class WifiDppEnrolleeActivity extends InstrumentedActivity {
+public class WifiDppEnrolleeActivity extends InstrumentedActivity implements
+ WifiManager.ActionListener,
+ WifiDppQrCodeScannerFragment.OnScanWifiDppSuccessListener,
+ WifiDppQrCodeScannerFragment.OnScanZxingWifiFormatSuccessListener {
private static final String TAG = "WifiDppEnrolleeActivity";
public static final String ACTION_ENROLLEE_QR_CODE_SCANNER =
@@ -101,4 +106,31 @@
finish();
return true;
}
+
+ @Override
+ public void onScanWifiDppSuccess(String publicKey, String information) {
+ // TODO(b/1023597): starts DPP enrollee handshake here
+ }
+
+ @Override
+ public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig) {
+ wifiNetworkConfig.connect(/* context */ this, /* listener */ this);
+ }
+
+ @Override
+ public void onSuccess() {
+ startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+ setResult(Activity.RESULT_OK);
+ finish();
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ Log.d(TAG, "Wi-Fi connect onFailure reason - " + reason);
+
+ final Fragment fragment = mFragmentManager.findFragmentById(R.id.fragment_container);
+ if (fragment instanceof WifiDppQrCodeScannerFragment) {
+ ((WifiDppQrCodeScannerFragment)fragment).showErrorMessage(true);
+ }
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
index 6792dee..4ac5850 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeBaseFragment.java
@@ -17,25 +17,16 @@
package com.android.settings.wifi.dpp;
import android.os.Bundle;
-import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.R;
/**
- * TODO: b/120645817 should refine code to only initiate UI component in each child fragment.
- */
-
-/**
* There are below 4 fragments for Wi-Fi DPP UI flow, to reduce redundant code of UI components,
- * this parent fragment instantiates all UI components and provides setting APIs for them.
+ * this parent fragment instantiates common UI components
*
* {@code WifiDppQrCodeScannerFragment}
* {@code WifiDppQrCodeGeneratorFragment}
@@ -43,128 +34,16 @@
* {@code WifiDppAddDeviceFragment}
*/
public abstract class WifiDppQrCodeBaseFragment extends InstrumentedFragment {
- private ImageView mHeaderIcon;
- private TextView mTitle;
- private TextView mDescription;
-
- private TextView mErrorMessage; //optional, for WifiDppQrCodeScannerFragment
- private ListView mSavedWifiNetworkList; //optional, for WifiDppChooseSavedWifiNetworkFragment
- private ProgressBar mProgressBar; //optional, for WifiDppAddDeviceFragment
- private ImageView mWifiApPictureView; //optional, for WifiDppAddDeviceFragment
- private TextView mChooseDifferentNetwork;//optional, for WifiDppAddDeviceFragment
-
- private Button mButtonLeft; //optional, for WifiDppChooseSavedWifiNetworkFragment,
- // WifiDppAddDeviceFragment
- private Button mButtonRight; //optional, for WifiDppChooseSavedWifiNetworkFragment,
- // WifiDppAddDeviceFragment
-
- abstract protected int getLayout();
+ protected ImageView mHeaderIcon;
+ protected TextView mTitle;
+ protected TextView mSummary;
@Override
- public final void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
- @Override
- public final View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = inflater.inflate(getLayout(), container, false);
- initView(view);
- return view;
- }
-
- private void initView(View view) {
- mHeaderIcon = view.findViewById(R.id.header_icon);
- mTitle = view.findViewById(R.id.title);
- mDescription = view.findViewById(R.id.description);
- mErrorMessage = view.findViewById(R.id.error_message);
-
- mSavedWifiNetworkList = view.findViewById(R.id.saved_wifi_network_list);
-
- mProgressBar = view.findViewById(R.id.progress_bar);
- mWifiApPictureView = view.findViewById(R.id.wifi_ap_picture_view);
- mChooseDifferentNetwork = view.findViewById(R.id.choose_different_network);
-
- mButtonLeft = view.findViewById(R.id.button_left);
- mButtonRight = view.findViewById(R.id.button_right);
- }
-
- protected void setHeaderIconImageResource(int resId) {
- mHeaderIcon.setImageResource(resId);
- }
-
- protected void setTitle(String title) {
- mTitle.setText(title);
- }
-
- protected void setDescription(String description) {
- mDescription.setText(description);
- }
-
- /** optional, for WifiDppQrCodeScannerFragment */
- protected void setErrorMessage(String errorMessage) {
- if (mErrorMessage != null) {
- mErrorMessage.setText(errorMessage);
- }
- }
-
- /**
- * optional, for WifiDppChooseSavedWifiNetworkFragment,
- * WifiDppAddDeviceFragment
- */
- protected void setLeftButtonText(String text) {
- if (mButtonLeft != null) {
- mButtonLeft.setText(text);
- }
- }
-
- /**
- * optional, for WifiDppChooseSavedWifiNetworkFragment,
- * WifiDppAddDeviceFragment
- */
- protected void setRightButtonText(String text) {
- if (mButtonRight != null) {
- mButtonRight.setText(text);
- }
- }
-
- /**
- * optional, for WifiDppChooseSavedWifiNetworkFragment,
- * WifiDppAddDeviceFragment
- */
- protected void hideLeftButton() {
- if (mButtonLeft != null) {
- mButtonLeft.setVisibility(View.INVISIBLE);
- }
- }
-
- /**
- * optional, for WifiDppChooseSavedWifiNetworkFragment,
- * WifiDppAddDeviceFragment
- */
- protected void hideRightButton() {
- if (mButtonRight != null) {
- mButtonRight.setVisibility(View.INVISIBLE);
- }
- }
-
- /**
- * optional, for WifiDppChooseSavedWifiNetworkFragment,
- * WifiDppAddDeviceFragment
- */
- protected void setLeftButtonOnClickListener(View.OnClickListener listener) {
- if (mButtonLeft != null) {
- mButtonLeft.setOnClickListener(listener);
- }
- }
-
- /**
- * optional, for WifiDppChooseSavedWifiNetworkFragment,
- * WifiDppAddDeviceFragment
- */
- protected void setRightButtonOnClickListener(View.OnClickListener listener) {
- if (mButtonRight != null) {
- mButtonRight.setOnClickListener(listener);
- }
+ mHeaderIcon = view.findViewById(android.R.id.icon);
+ mTitle = view.findViewById(android.R.id.title);
+ mSummary = view.findViewById(android.R.id.summary);
}
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
index 81def9b..f4bbcc1 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -18,23 +18,32 @@
import android.app.ActionBar;
import android.content.Context;
+import android.graphics.Bitmap;
import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
+import com.android.settings.wifi.qrcode.QrCodeGenerator;
+
+import com.google.zxing.WriterException;
/**
* After sharing a saved Wi-Fi network, {@code WifiDppConfiguratorActivity} start with this fragment
* to generate a Wi-Fi DPP QR code for other device to initiate as an enrollee.
*/
public class WifiDppQrCodeGeneratorFragment extends WifiDppQrCodeBaseFragment {
- @Override
- protected int getLayout() {
- return R.layout.wifi_dpp_qrcode_generator_fragment;
- }
+ private static final String TAG = "WifiDppQrCodeGeneratorFragment";
+
+ private ImageView mQrCodeView;
+ private String mQrCode;
@Override
public int getMetricsCategory() {
@@ -51,18 +60,8 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- setHeaderIconImageResource(R.drawable.ic_qrcode_24dp);
- WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
- .getWifiNetworkConfig();
- if (!WifiNetworkConfig.isValidConfig(wifiNetworkConfig)) {
- throw new IllegalArgumentException("Invalid Wi-Fi network for configuring");
- }
- setTitle(getString(R.string.wifi_dpp_share_wifi));
- setDescription(getString(R.string.wifi_dpp_scan_qr_code_with_another_device,
- wifiNetworkConfig.getSsid()));
-
setHasOptionsMenu(true);
- ActionBar actionBar = getActivity().getActionBar();
+ final ActionBar actionBar = getActivity().getActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.show();
@@ -102,4 +101,42 @@
return super.onOptionsItemSelected(menuItem);
}
}
+
+ @Override
+ public final View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.wifi_dpp_qrcode_generator_fragment, container,
+ /* attachToRoot */ false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mQrCodeView = view.findViewById(R.id.qrcode_view);
+
+ mHeaderIcon.setImageResource(R.drawable.ic_qrcode_24dp);
+ WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
+ .getWifiNetworkConfig();
+ if (!WifiNetworkConfig.isValidConfig(wifiNetworkConfig)) {
+ throw new IllegalStateException("Invalid Wi-Fi network for configuring");
+ }
+ mTitle.setText(R.string.wifi_dpp_share_wifi);
+ mSummary.setText(getString(R.string.wifi_dpp_scan_qr_code_with_another_device,
+ wifiNetworkConfig.getSsid()));
+
+ mQrCode = wifiNetworkConfig.getQrCode();
+ setQrCode();
+ }
+
+ private void setQrCode() {
+ try {
+ final int qrcodeSize = getContext().getResources().getDimensionPixelSize(
+ R.dimen.qrcode_size);
+ final Bitmap bmp = QrCodeGenerator.encodeQrCode(mQrCode, qrcodeSize);
+ mQrCodeView.setImageBitmap(bmp);
+ } catch (WriterException e) {
+ Log.e(TAG, "Error generatting QR code bitmap " + e);
+ }
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 8cd3c562..c7c1461 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -16,7 +16,6 @@
package com.android.settings.wifi.dpp;
-import android.annotation.Nullable;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
@@ -25,13 +24,18 @@
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
import android.text.TextUtils;
import android.util.Size;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
@@ -41,37 +45,69 @@
public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
SurfaceTextureListener,
QrCamera.ScannerCallback {
+ private static final String TAG = "WifiDppQrCodeScannerFragment";
+
+ /** Message sent to hide error message */
+ private static final int MESSAGE_HIDE_ERROR_MESSAGE = 1;
+
+ /** Message sent to show error message */
+ private static final int MESSAGE_SHOW_ERROR_MESSAGE = 2;
+
+ /** Message sent to manipulate Wi-Fi DPP QR code */
+ private static final int MESSAGE_SCAN_WIFI_DPP_SUCCESS = 3;
+
+ /** Message sent to manipulate ZXing Wi-Fi QR code */
+ private static final int MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS = 4;
+
+ private static final long SHOW_ERROR_MESSAGE_INTERVAL = 2000;
+ private static final long SHOW_SUCCESS_SQUARE_INTERVAL = 1000;
+
+ // Keys for Bundle usage
+ private static final String KEY_PUBLIC_KEY = "key_public_key";
+ private static final String KEY_INFORMATION = "key_information";
+
private QrCamera mCamera;
private TextureView mTextureView;
private QrDecorateView mDecorateView;
+ private TextView mErrorMessage;
/** true if the fragment working for configurator, false enrollee*/
- private final boolean mConfiguratorMode;
+ private final boolean mIsConfiguratorMode;
/** The SSID of the Wi-Fi network which the user specify to enroll */
private String mSsid;
- @Override
- protected int getLayout() {
- return R.layout.wifi_dpp_qrcode_scanner_fragment;
- }
+ /** QR code data scanned by camera */
+ private WifiQrCode mWifiQrCode;
@Override
public int getMetricsCategory() {
- if (mConfiguratorMode) {
+ if (mIsConfiguratorMode) {
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_CONFIGURATOR;
} else {
return MetricsProto.MetricsEvent.SETTINGS_WIFI_DPP_ENROLLEE;
}
}
+ // Container Activity must implement this interface
+ public interface OnScanWifiDppSuccessListener {
+ public void onScanWifiDppSuccess(String publicKey, String information);
+ }
+ OnScanWifiDppSuccessListener mScanWifiDppSuccessListener;
+
+ // Container Activity must implement this interface
+ public interface OnScanZxingWifiFormatSuccessListener {
+ public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig);
+ }
+ OnScanZxingWifiFormatSuccessListener mScanScanZxingWifiFormatSuccessListener;
+
/**
* Configurator container activity of the fragment should create instance with this constructor.
*/
public WifiDppQrCodeScannerFragment() {
super();
- mConfiguratorMode = true;
+ mIsConfiguratorMode = true;
}
/**
@@ -81,7 +117,7 @@
public WifiDppQrCodeScannerFragment(String ssid) {
super();
- mConfiguratorMode = false;
+ mIsConfiguratorMode = false;
mSsid = ssid;
}
@@ -89,30 +125,7 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- setHeaderIconImageResource(R.drawable.ic_scan_24dp);
-
- if (mConfiguratorMode) {
- setTitle(getString(R.string.wifi_dpp_add_device_to_network));
-
- WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
- .getWifiNetworkConfig();
- if (!WifiNetworkConfig.isValidConfig(wifiNetworkConfig)) {
- throw new IllegalArgumentException("Invalid Wi-Fi network for configuring");
- }
- setDescription(getString(R.string.wifi_dpp_center_qr_code, wifiNetworkConfig.getSsid()));
- } else {
- setTitle(getString(R.string.wifi_dpp_scan_qr_code));
-
- String description;
- if (TextUtils.isEmpty(mSsid)) {
- description = getString(R.string.wifi_dpp_scan_qr_code_join_unknown_network, mSsid);
- } else {
- description = getString(R.string.wifi_dpp_scan_qr_code_join_network, mSsid);
- }
- setDescription(description);
- }
-
- ActionBar actionBar = getActivity().getActionBar();
+ final ActionBar actionBar = getActivity().getActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.show();
@@ -120,13 +133,61 @@
}
@Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ mScanWifiDppSuccessListener = (OnScanWifiDppSuccessListener) context;
+ mScanScanZxingWifiFormatSuccessListener = (OnScanZxingWifiFormatSuccessListener) context;
+ }
+
+ @Override
+ public void onDetach() {
+ mScanWifiDppSuccessListener = null;
+ mScanScanZxingWifiFormatSuccessListener = null;
+
+ super.onDetach();
+ }
+
+ @Override
+ public final View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.wifi_dpp_qrcode_scanner_fragment, container,
+ /* attachToRoot */ false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mTextureView = (TextureView) view.findViewById(R.id.preview_view);
mTextureView.setSurfaceTextureListener(this);
mDecorateView = (QrDecorateView) view.findViewById(R.id.decorate_view);
+
+ mHeaderIcon.setImageResource(R.drawable.ic_scan_24dp);
+ if (mIsConfiguratorMode) {
+ mTitle.setText(R.string.wifi_dpp_add_device_to_network);
+
+ WifiNetworkConfig wifiNetworkConfig = ((WifiNetworkConfig.Retriever) getActivity())
+ .getWifiNetworkConfig();
+ if (!WifiNetworkConfig.isValidConfig(wifiNetworkConfig)) {
+ throw new IllegalStateException("Invalid Wi-Fi network for configuring");
+ }
+ mSummary.setText(getString(R.string.wifi_dpp_center_qr_code,
+ wifiNetworkConfig.getSsid()));
+ } else {
+ mTitle.setText(R.string.wifi_dpp_scan_qr_code);
+
+ String description;
+ if (TextUtils.isEmpty(mSsid)) {
+ description = getString(R.string.wifi_dpp_scan_qr_code_join_unknown_network, mSsid);
+ } else {
+ description = getString(R.string.wifi_dpp_scan_qr_code_join_network, mSsid);
+ }
+ mSummary.setText(description);
+ }
+
+ mErrorMessage = view.findViewById(R.id.error_message);
}
@Override
@@ -173,10 +234,75 @@
}
@Override
+ public boolean isValid(String qrCode) {
+ try {
+ mWifiQrCode = new WifiQrCode(qrCode);
+ } catch (IllegalArgumentException e) {
+ mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ return false;
+ }
+
+ final String scheme = mWifiQrCode.getScheme();
+
+ // When SSID is specified for enrollee, avoid to connect to the Wi-Fi of different SSID
+ if (!mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
+ final String ssidQrCode = mWifiQrCode.getWifiNetworkConfig().getSsid();
+ if (!TextUtils.isEmpty(mSsid) && !mSsid.equals(ssidQrCode)) {
+ mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ return false;
+ }
+ }
+
+ // It's impossible to provision other device with ZXing Wi-Fi Network config format
+ if (mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
+ mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * This method is only called when QrCamera.ScannerCallback.isValid returns true;
+ */
+ @Override
public void handleSuccessfulResult(String qrCode) {
+ switch (mWifiQrCode.getScheme()) {
+ case WifiQrCode.SCHEME_DPP:
+ handleWifiDpp(mWifiQrCode.getPublicKey(), mWifiQrCode.getInformation());
+ break;
+
+ case WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG:
+ handleZxingWifiFormat(mWifiQrCode.getWifiNetworkConfig());
+ break;
+
+ default:
+ // continue below
+ }
+ }
+
+ private void handleWifiDpp(String publicKey, String information) {
destroyCamera();
mDecorateView.setFocused(true);
- // TODO(b/120243131): Add a network by Wi-Fi Network config shared via QR code.
+
+ final Bundle bundle = new Bundle();
+ bundle.putString(KEY_PUBLIC_KEY, publicKey);
+ bundle.putString(KEY_INFORMATION, information);
+
+ Message message = mHandler.obtainMessage(MESSAGE_SCAN_WIFI_DPP_SUCCESS);
+ message.setData(bundle);
+
+ mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
+ }
+
+ private void handleZxingWifiFormat(WifiNetworkConfig wifiNetworkConfig) {
+ destroyCamera();
+ mDecorateView.setFocused(true);
+
+ Message message = mHandler.obtainMessage(MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS);
+ message.obj = wifiNetworkConfig;
+
+ mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL);
}
@Override
@@ -198,4 +324,51 @@
mCamera = null;
}
}
+
+ public void showErrorMessage(boolean show) {
+ mErrorMessage.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+
+ if (show) {
+ mHandler.removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
+ mHandler.sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
+ SHOW_ERROR_MESSAGE_INTERVAL);
+ }
+ }
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_HIDE_ERROR_MESSAGE:
+ showErrorMessage(false);
+ break;
+
+ case MESSAGE_SHOW_ERROR_MESSAGE:
+ showErrorMessage(true);
+ break;
+
+ case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
+ if (mScanWifiDppSuccessListener == null) {
+ return;
+ }
+ final Bundle bundle = msg.getData();
+ final String publicKey = bundle.getString(KEY_PUBLIC_KEY);
+ final String information = bundle.getString(KEY_INFORMATION);
+
+ mScanWifiDppSuccessListener.onScanWifiDppSuccess(publicKey, information);
+ break;
+
+ case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
+ if (mScanScanZxingWifiFormatSuccessListener == null) {
+ return;
+ }
+ mScanScanZxingWifiFormatSuccessListener.onScanZxingWifiFormatSuccess(
+ (WifiNetworkConfig)msg.obj);
+ break;
+
+ default:
+ return;
+ }
+ }
+ };
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index cc75d44..3a40e25 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -18,9 +18,15 @@
import android.content.Context;
import android.content.Intent;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
+import com.android.settingslib.wifi.AccessPoint;
+
+import java.util.List;
+
/**
* Here are the items shared by both WifiDppConfiguratorActivity & WifiDppEnrolleeActivity
*/
@@ -84,23 +90,81 @@
return intent;
}
+ private static String getPresharedKey(WifiManager wifiManager, WifiConfiguration config) {
+ String preSharedKey = config.preSharedKey;
+
+ final List<WifiConfiguration> wifiConfigs = wifiManager.getPrivilegedConfiguredNetworks();
+ for (WifiConfiguration wifiConfig : wifiConfigs) {
+ if (wifiConfig.networkId == config.networkId) {
+ preSharedKey = wifiConfig.preSharedKey;
+ break;
+ }
+ }
+
+ return preSharedKey;
+ }
+
+ private static String removeFirstAndLastDoubleQuotes(String str) {
+ if (TextUtils.isEmpty(str)) {
+ return str;
+ }
+
+ int begin = 0;
+ int end = str.length() - 1;
+ if (str.charAt(begin) == '\"') {
+ begin++;
+ }
+ if (str.charAt(end) == '\"') {
+ end--;
+ }
+ return str.substring(begin, end+1);
+ }
+
+ private static String getSecurityString(AccessPoint accessPoint) {
+ switch(accessPoint.getSecurity()) {
+ case AccessPoint.SECURITY_WEP:
+ return "WEP";
+ case AccessPoint.SECURITY_PSK:
+ return "WPA";
+ default:
+ return "nopass";
+ }
+ }
+
/**
* Returns an intent to launch QR code generator.
*
- * @param ssid The data corresponding to {@code WifiConfiguration} SSID
- * @param Security The data is from {@code AccessPoint.securityToString}
+ * @param context The context to use for the content resolver
+ * @param wifiManager An instance of {@link WifiManager}
+ * @param accessPoint An instance of {@link AccessPoint}
* @return Intent for launching QR code generator
*/
- public static Intent getConfiguratorQrCodeGeneratorIntent(String ssid, String Security) {
- //TODO: b/118794858#comment6 should put password & hideSsid in intent extra
- final Intent intent = new Intent(
- WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+ public static Intent getConfiguratorQrCodeGeneratorIntent(Context context,
+ WifiManager wifiManager, AccessPoint accessPoint) {
+ final Intent intent = new Intent(context, WifiDppConfiguratorActivity.class);
+ intent.setAction(WifiDppConfiguratorActivity.ACTION_CONFIGURATOR_QR_CODE_GENERATOR);
+
+ final WifiConfiguration wifiConfig = accessPoint.getConfig();
+ final String ssid = removeFirstAndLastDoubleQuotes(wifiConfig.SSID);
+ final String security = getSecurityString(accessPoint);
+ String preSharedKey = wifiConfig.preSharedKey;
+
+ if (preSharedKey != null) {
+ // When the value of this key is read, the actual key is not returned, just a "*".
+ // Call privileged system API to obtain actual key.
+ preSharedKey = removeFirstAndLastDoubleQuotes(getPresharedKey(wifiManager, wifiConfig));
+ }
+
if (!TextUtils.isEmpty(ssid)) {
intent.putExtra(EXTRA_WIFI_SSID, ssid);
}
- if (!TextUtils.isEmpty(Security)) {
- intent.putExtra(EXTRA_WIFI_SECURITY, Security);
+ if (!TextUtils.isEmpty(security)) {
+ intent.putExtra(EXTRA_WIFI_SECURITY, security);
}
+ if (!TextUtils.isEmpty(preSharedKey)) {
+ intent.putExtra(EXTRA_WIFI_PRE_SHARED_KEY, preSharedKey);
+ }
+
return intent;
}
}
diff --git a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
index bb64e05..c9bfbd6 100644
--- a/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
+++ b/src/com/android/settings/wifi/dpp/WifiNetworkConfig.java
@@ -16,8 +16,18 @@
package com.android.settings.wifi.dpp;
+import static com.android.settings.wifi.dpp.WifiQrCode.SECURITY_NO_PASSWORD;
+import static com.android.settings.wifi.dpp.WifiQrCode.SECURITY_WEP;
+import static com.android.settings.wifi.dpp.WifiQrCode.SECURITY_WPA;
+
+import android.content.Context;
import android.content.Intent;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.AuthAlgorithm;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiManager;
import android.text.TextUtils;
+import android.util.Log;
import androidx.annotation.Keep;
@@ -30,8 +40,7 @@
* EXTRA_QR_CODE
*/
public class WifiNetworkConfig {
- // Ignores password if security is NO_PASSWORD or absent
- public static final String NO_PASSWORD = "nopass";
+ private static final String TAG = "WifiNetworkConfig";
private String mSecurity;
private String mSsid;
@@ -47,18 +56,9 @@
}
public WifiNetworkConfig(WifiNetworkConfig config) {
- if (config.mSecurity != null) {
- mSecurity = new String(config.mSecurity);
- }
-
- if (config.mSsid != null) {
- mSsid = new String(config.mSsid);
- }
-
- if (config.mPreSharedKey != null) {
- mPreSharedKey = new String(config.mPreSharedKey);
- }
-
+ mSecurity = config.mSecurity;
+ mSsid = config.mSsid;
+ mPreSharedKey = config.mPreSharedKey;
mHiddenSsid = config.mHiddenSsid;
}
@@ -106,7 +106,7 @@
public static boolean isValidConfig(String security, String ssid, String preSharedKey,
boolean hiddenSsid) {
- if (!TextUtils.isEmpty(security) && !NO_PASSWORD.equals(security)) {
+ if (!TextUtils.isEmpty(security) && !SECURITY_NO_PASSWORD.equals(security)) {
if (TextUtils.isEmpty(preSharedKey)) {
return false;
}
@@ -119,6 +119,51 @@
return true;
}
+ /**
+ * Escaped special characters "\", ";", ":", "," with a backslash
+ * See https://github.com/zxing/zxing/wiki/Barcode-Contents
+ */
+ private String escapeSpecialCharacters(String str) {
+ if (TextUtils.isEmpty(str)) {
+ return str;
+ }
+
+ StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < str.length(); i++) {
+ char ch = str.charAt(i);
+ if (ch =='\\' || ch == ',' || ch == ';' || ch == ':') {
+ buf.append('\\');
+ }
+ buf.append(ch);
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Construct a barcode string for WiFi network login.
+ * See https://en.wikipedia.org/wiki/QR_code#WiFi_network_login
+ */
+ public String getQrCode() {
+ final String empty = "";
+ String barcode = new StringBuilder("WIFI:")
+ .append("S:")
+ .append(escapeSpecialCharacters(mSsid))
+ .append(";")
+ .append("T:")
+ .append(TextUtils.isEmpty(mSecurity) ? empty : mSecurity)
+ .append(";")
+ .append("P:")
+ .append(TextUtils.isEmpty(mPreSharedKey) ? empty
+ : escapeSpecialCharacters(mPreSharedKey))
+ .append(";")
+ .append("H:")
+ .append(mHiddenSsid)
+ .append(";;")
+ .toString();
+ return barcode;
+ }
+
@Keep
public String getSecurity() {
return mSecurity;
@@ -138,4 +183,77 @@
public boolean getHiddenSsid() {
return mHiddenSsid;
}
+
+ public void connect(Context context, WifiManager.ActionListener listener) {
+ WifiConfiguration wifiConfiguration = getWifiConfigurationOrNull();
+ if (wifiConfiguration == null) {
+ if (listener != null) {
+ listener.onFailure(WifiManager.ERROR);
+ }
+ return;
+ }
+
+ WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
+ wifiManager.connect(wifiConfiguration, listener);
+ }
+
+ /**
+ * This is a simplified method from {@code WifiConfigController.getConfig()}
+ */
+ private WifiConfiguration getWifiConfigurationOrNull() {
+ if (!isValidConfig(this)) {
+ return null;
+ }
+
+ final WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.SSID = addQuotationIfNeeded(mSsid);
+ wifiConfiguration.hiddenSSID = mHiddenSsid;
+
+ if (TextUtils.isEmpty(mSecurity) || SECURITY_NO_PASSWORD.equals(mSecurity)) {
+ wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE);
+ return wifiConfiguration;
+ }
+
+ if (mSecurity.startsWith(SECURITY_WEP)) {
+ wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE);
+ wifiConfiguration.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
+ wifiConfiguration.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
+
+ // WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
+ final int length = mPreSharedKey.length();
+ if ((length == 10 || length == 26 || length == 58)
+ && mPreSharedKey.matches("[0-9A-Fa-f]*")) {
+ wifiConfiguration.wepKeys[0] = mPreSharedKey;
+ } else {
+ wifiConfiguration.wepKeys[0] = addQuotationIfNeeded(mPreSharedKey);
+ }
+ } else if (mSecurity.startsWith(SECURITY_WPA)) {
+ wifiConfiguration.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
+
+ if (mPreSharedKey.matches("[0-9A-Fa-f]{64}")) {
+ wifiConfiguration.preSharedKey = mPreSharedKey;
+ } else {
+ wifiConfiguration.preSharedKey = addQuotationIfNeeded(mPreSharedKey);
+ }
+ } else {
+ Log.w(TAG, "Unsupported security");
+ return null;
+ }
+
+ return wifiConfiguration;
+ }
+
+ private String addQuotationIfNeeded(String input) {
+ if (TextUtils.isEmpty(input)) {
+ return "";
+ }
+
+ if (input.length() >= 2 && input.startsWith("\"") && input.endsWith("\"")) {
+ return input;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("\"").append(input).append("\"");
+ return sb.toString();
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiQrCode.java b/src/com/android/settings/wifi/dpp/WifiQrCode.java
index ebc39c3..a8562bb 100644
--- a/src/com/android/settings/wifi/dpp/WifiQrCode.java
+++ b/src/com/android/settings/wifi/dpp/WifiQrCode.java
@@ -22,7 +22,8 @@
import androidx.annotation.Keep;
import androidx.annotation.VisibleForTesting;
-import java.util.regex.Matcher;
+import java.util.Arrays;
+import java.util.List;
import java.util.regex.Pattern;
/**
@@ -62,7 +63,12 @@
public static final String PREFIX_ZXING_PASSWORD = "P:";
public static final String PREFIX_ZXING_HIDDEN_SSID = "H:";
- public static final String SUFFIX_QR_CODE = ";";
+ public static final String DELIMITER_QR_CODE = ";";
+
+ // Ignores password if security is SECURITY_NO_PASSWORD or absent
+ public static final String SECURITY_NO_PASSWORD = "nopass";
+ public static final String SECURITY_WEP = "WEP";
+ public static final String SECURITY_WPA = "WPA";
private String mQrCode;
@@ -100,22 +106,27 @@
/** Parses Wi-Fi DPP QR code string */
private void parseWifiDppQrCode(String qrCode) throws IllegalArgumentException {
- String publicKey = getSubStringOrNull(qrCode, PREFIX_DPP_PUBLIC_KEY, SUFFIX_QR_CODE);
+ List keyValueList = getKeyValueList(qrCode, PREFIX_DPP, DELIMITER_QR_CODE);
+
+ String publicKey = getValueOrNull(keyValueList, PREFIX_DPP_PUBLIC_KEY);
if (TextUtils.isEmpty(publicKey)) {
throw new IllegalArgumentException("Invalid format");
}
mPublicKey = publicKey;
- mInformation = getSubStringOrNull(qrCode, PREFIX_DPP_INFORMATION, SUFFIX_QR_CODE);
+ mInformation = getValueOrNull(keyValueList, PREFIX_DPP_INFORMATION);
}
/** Parses ZXing reader library's Wi-Fi Network config format */
private void parseZxingWifiQrCode(String qrCode) throws IllegalArgumentException {
- String security = getSubStringOrNull(qrCode, PREFIX_ZXING_SECURITY, SUFFIX_QR_CODE);
- String ssid = getSubStringOrNull(qrCode, PREFIX_ZXING_SSID, SUFFIX_QR_CODE);
- String password = getSubStringOrNull(qrCode, PREFIX_ZXING_PASSWORD, SUFFIX_QR_CODE);
- String hiddenSsidString = getSubStringOrNull(qrCode, PREFIX_ZXING_HIDDEN_SSID,
- SUFFIX_QR_CODE);
+ List keyValueList = getKeyValueList(qrCode, PREFIX_ZXING_WIFI_NETWORK_CONFIG,
+ DELIMITER_QR_CODE);
+
+ String security = getValueOrNull(keyValueList, PREFIX_ZXING_SECURITY);
+ String ssid = getValueOrNull(keyValueList, PREFIX_ZXING_SSID);
+ String password = getValueOrNull(keyValueList, PREFIX_ZXING_PASSWORD);
+ String hiddenSsidString = getValueOrNull(keyValueList, PREFIX_ZXING_HIDDEN_SSID);
+
boolean hiddenSsid = "true".equalsIgnoreCase(hiddenSsidString);
//"\", ";", "," and ":" are escaped with a backslash "\", should remove at first
@@ -132,33 +143,37 @@
}
/**
- * Gets the substring between prefix & suffix from input.
+ * Splits key/value pairs from qrCode
*
- * @param prefix the string before the returned substring
- * @param suffix the string after the returned substring
- * @return null if not exists, non-null otherwise
+ * @param qrCode the QR code raw string
+ * @param prefixQrCode the string before all key/value pairs in qrCode
+ * @param delimiter the string to split key/value pairs, can't contain a backslash
+ * @return a list contains string of key/value (e.g. K:key1)
*/
- private static String getSubStringOrNull(String input, String prefix, String suffix) {
- StringBuilder sb = new StringBuilder();
- String regex = sb.append(prefix).append("(.*?)").append(suffix).toString();
- Pattern pattern = Pattern.compile(regex);
- Matcher matcher = pattern.matcher(input);
+ private List<String> getKeyValueList(String qrCode, String prefixQrCode,
+ String delimiter) {
+ String keyValueString = qrCode.substring(prefixQrCode.length());
- if (!matcher.find()) {
- return null;
+ // Should not treat \delimiter as a delimiter
+ String regex = "(?<!\\\\)" + Pattern.quote(delimiter);
+
+ List<String> result = Arrays.asList(keyValueString.split(regex));
+ return result;
+ }
+
+ private String getValueOrNull(List<String> keyValueList, String prefix) {
+ for (String keyValue : keyValueList) {
+ if (keyValue.startsWith(prefix)) {
+ return keyValue.substring(prefix.length());
+ }
}
- String target = matcher.group(1);
- if (TextUtils.isEmpty(target)) {
- return null;
- }
-
- return target;
+ return null;
}
@Keep
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
- protected static String removeBackSlash(String input) {
+ protected String removeBackSlash(String input) {
if (input == null) {
return null;
}
diff --git a/src/com/android/settings/wifi/qrcode/QrCamera.java b/src/com/android/settings/wifi/qrcode/QrCamera.java
index c60c30e..af366bc 100644
--- a/src/com/android/settings/wifi/qrcode/QrCamera.java
+++ b/src/com/android/settings/wifi/qrcode/QrCamera.java
@@ -152,6 +152,15 @@
* @param transform The transform to apply to the content of preview
*/
void setTransform(Matrix transform);
+
+ /**
+ * Verify QR code is valid or not. The camera will stop scanning if this callback returns
+ * true.
+ *
+ * @param qrCode The result QR code after decoding.
+ * @return Returns true if qrCode hold valid information.
+ */
+ boolean isValid(String qrCode);
}
private void setCameraParameter() {
@@ -245,7 +254,9 @@
mReader.reset();
}
if (qrCode != null) {
- return qrCode.getText();
+ if (mScannerCallback.isValid(qrCode.getText())) {
+ return qrCode.getText();
+ }
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
diff --git a/src/com/android/settings/wifi/qrcode/QrDecorateView.java b/src/com/android/settings/wifi/qrcode/QrDecorateView.java
index 253bdb8..6952a63 100644
--- a/src/com/android/settings/wifi/qrcode/QrDecorateView.java
+++ b/src/com/android/settings/wifi/qrcode/QrDecorateView.java
@@ -17,10 +17,13 @@
package com.android.settings.wifi.qrcode;
import android.content.Context;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
@@ -33,11 +36,26 @@
* Draws the lines at the corner of the inner frame.
*/
public class QrDecorateView extends View {
- private static final float CORNER_STROKE_WIDTH = 3f; // 3dp
- private static final float CORNER_LINE_LENGTH = 20f; // 20dp
+ private static final float CORNER_STROKE_WIDTH = 4f; // 4dp
+ private static final float CORNER_LINE_LENGTH = 264f; // 264dp
+ private static final float CORNER_RADIUS = 16f; // 16dp
- final private Paint mPaint;
- private RectF mFrame;
+ final private int mCornerColor;
+ final private int mFocusedCornerColor;
+ final private int mBackgroundColor;
+
+ final private Paint mStrokePaint;
+ final private Paint mTransparentPaint;
+ final private Paint mBackgroundPaint;
+
+ final private float mRadius;
+
+ private Bitmap mMaskBitmap;
+ private Canvas mMaskCanvas;
+
+ private RectF mOuterFrame;
+ private RectF mInnerFrame;
+
private boolean mFocused;
public QrDecorateView(Context context) {
@@ -54,78 +72,66 @@
public QrDecorateView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- final float strokeWidth = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- CORNER_STROKE_WIDTH,
- getResources().getDisplayMetrics()
- );
- mPaint = new Paint();
- mPaint.setStrokeWidth(strokeWidth);
+
mFocused = false;
+ mRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS,
+ getResources().getDisplayMetrics());
+
+ mCornerColor = context.getResources().getColor(R.color.qr_corner_line_color);
+ mFocusedCornerColor = context.getResources().getColor(R.color.qr_focused_corner_line_color);
+ mBackgroundColor = context.getResources().getColor(R.color.qr_background_color);
+
+ mStrokePaint = new Paint();
+ mStrokePaint.setAntiAlias(true);
+
+ mTransparentPaint = new Paint();
+ mTransparentPaint.setAntiAlias(true);
+ mTransparentPaint.setColor(getResources().getColor(android.R.color.transparent));
+ mTransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+
+ mBackgroundPaint = new Paint();
+ mBackgroundPaint.setColor(mBackgroundColor);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ if(mMaskBitmap == null) {
+ mMaskBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
+ mMaskCanvas = new Canvas(mMaskBitmap);
+ }
+
+ calculateFramePos();
}
@Override
protected void onDraw(Canvas canvas) {
- calculateFramePos();
- final float cornerLineLength = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- CORNER_LINE_LENGTH,
- getResources().getDisplayMetrics()
- );
- mPaint.setColor(mFocused ? Color.GREEN : Color.WHITE);
- drawCorner(mFrame, cornerLineLength, canvas);
- super.onDraw(canvas);
- }
+ // Set frame line color.
+ mStrokePaint.setColor(mFocused ? mFocusedCornerColor : mCornerColor);
+ // Draw background color.
+ mMaskCanvas.drawColor(mBackgroundColor);
+ // Draw outer corner.
+ mMaskCanvas.drawRoundRect(mOuterFrame, mRadius, mRadius, mStrokePaint);
+ // Draw inner transparent corner.
+ mMaskCanvas.drawRoundRect(mInnerFrame, mRadius, mRadius, mTransparentPaint);
- private void drawCorner(RectF frame, float lineLength, Canvas canvas) {
- final float strokeWidth = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_DIP,
- CORNER_STROKE_WIDTH,
- getResources().getDisplayMetrics()
- );
- // Draw top-left corner.
- canvas.drawLine(
- frame.left - strokeWidth / 2,
- frame.top,
- frame.left + lineLength,
- frame.top,
- mPaint);
- canvas.drawLine(frame.left, frame.top, frame.left, frame.top + lineLength, mPaint);
- // Draw top-right corner.
- canvas.drawLine(
- frame.right + strokeWidth / 2,
- frame.top,
- frame.right - lineLength,
- frame.top,
- mPaint);
- canvas.drawLine(frame.right, frame.top, frame.right, frame.top + lineLength, mPaint);
- // Draw bottom-left corner.
- canvas.drawLine(
- frame.left - strokeWidth / 2,
- frame.bottom,
- frame.left + lineLength,
- frame.bottom,
- mPaint);
- canvas.drawLine(frame.left, frame.bottom, frame.left, frame.bottom - lineLength, mPaint);
- // Draw bottom-right corner.
- canvas.drawLine(
- frame.right + strokeWidth / 2,
- frame.bottom,
- frame.right - lineLength,
- frame.bottom,
- mPaint);
- canvas.drawLine(frame.right, frame.bottom, frame.right, frame.bottom - lineLength, mPaint);
+ canvas.drawBitmap(mMaskBitmap, 0, 0, mBackgroundPaint);
+ super.onDraw(canvas);
}
private void calculateFramePos() {
final int centralX = getWidth() / 2;
final int centralY = getHeight() / 2;
- final float halfFrameWidth = getWidth() / 3;
- mFrame = new RectF(
- centralX - halfFrameWidth,
- centralY - halfFrameWidth,
- centralX + halfFrameWidth,
- centralY + halfFrameWidth);
+ final float cornerLineLength = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ CORNER_LINE_LENGTH, getResources().getDisplayMetrics()) / 2;
+ final float strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ CORNER_STROKE_WIDTH, getResources().getDisplayMetrics()) / 2;
+
+ mOuterFrame = new RectF(centralX - cornerLineLength, centralY - cornerLineLength,
+ centralX + cornerLineLength, centralY + cornerLineLength);
+ mInnerFrame = new RectF(mOuterFrame.left + strokeWidth, mOuterFrame.top + strokeWidth,
+ mOuterFrame.right - strokeWidth, mOuterFrame.bottom - strokeWidth);
}
// Draws green lines if focued. Otherwise, draws white lines.
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index c98fbdb..5f23f0c 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -178,6 +178,8 @@
controllers.add(new WifiTetherSecurityPreferenceController(context, listener));
controllers.add(new WifiTetherPasswordPreferenceController(context, listener));
controllers.add(new WifiTetherApBandPreferenceController(context, listener));
+ controllers.add(
+ new WifiTetherAutoOffPreferenceController(context, KEY_WIFI_TETHER_AUTO_OFF));
return controllers;
}
diff --git a/tests/robotests/assets/grandfather_not_implementing_index_provider b/tests/robotests/assets/grandfather_not_implementing_index_provider
index ab06f75..447de00 100644
--- a/tests/robotests/assets/grandfather_not_implementing_index_provider
+++ b/tests/robotests/assets/grandfather_not_implementing_index_provider
@@ -54,6 +54,12 @@
com.android.settings.notification.RedactionInterstitial$RedactionInterstitialFragment
com.android.settings.notification.ZenModeEventRuleSettings
com.android.settings.notification.ZenModeScheduleRuleSettings
+com.android.settings.notification.ZenCustomRuleNotificationsSettings
+com.android.settings.notification.ZenCustomRuleCallsSettings
+com.android.settings.notification.ZenCustomRuleConfigSettings
+com.android.settings.notification.ZenCustomRuleSettings
+com.android.settings.notification.ZenCustomRuleBlockedEffectsSettings
+com.android.settings.notification.ZenCustomRuleMessagesSettings
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
com.android.settings.password.SetupChooseLockGeneric$InternalActivity$InternalSetupChooseLockGenericFragment
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
diff --git a/tests/robotests/res/layout/preference.xml b/tests/robotests/res/layout/preference.xml
index 3f73161..7ac733f 100644
--- a/tests/robotests/res/layout/preference.xml
+++ b/tests/robotests/res/layout/preference.xml
@@ -30,7 +30,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
android:textColor="?android:attr/textColorPrimary"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
@@ -43,7 +43,7 @@
android:layout_alignStart="@android:id/title"
android:visibility="gone"
android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10" />
diff --git a/tests/robotests/src/com/android/settings/MasterClearTest.java b/tests/robotests/src/com/android/settings/MasterClearTest.java
index 388440e..749373b 100644
--- a/tests/robotests/src/com/android/settings/MasterClearTest.java
+++ b/tests/robotests/src/com/android/settings/MasterClearTest.java
@@ -43,7 +43,6 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
-import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ScrollView;
@@ -51,7 +50,6 @@
import androidx.fragment.app.FragmentActivity;
import com.android.settings.testutils.shadow.ShadowUtils;
-import com.google.android.setupcompat.item.FooterButton;
import org.junit.Before;
import org.junit.Test;
@@ -387,7 +385,7 @@
public void testOnGlobalLayout_shouldNotRemoveListener() {
final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
mMasterClear.mScrollView = mScrollView;
- mMasterClear.mInitiateButton = mock(FooterButton.class);
+ doNothing().when(mMasterClear).onGlobalLayout();
doReturn(true).when(mMasterClear).hasReachedBottom(any());
when(mScrollView.getViewTreeObserver()).thenReturn(viewTreeObserver);
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
index dd7cde2..529c0ee 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/DefaultAppShortcutPreferenceControllerBaseTest.java
@@ -18,13 +18,13 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.content.Context;
+import android.content.Intent;
import android.os.UserManager;
import androidx.preference.Preference;
@@ -40,12 +40,15 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowActivity;
+import org.robolectric.shadows.ShadowUserManager;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowUserManager.class)
public class DefaultAppShortcutPreferenceControllerBaseTest {
- @Mock
- private UserManager mUserManager;
+ private ShadowUserManager mShadowUserManager;
@Mock
private AppInfoDashboardFragment mFragment;
@Mock
@@ -57,8 +60,8 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mActivity = spy(Robolectric.setupActivity(Activity.class));
- when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ mActivity = Robolectric.setupActivity(Activity.class);
+ mShadowUserManager = shadowOf(mActivity.getSystemService(UserManager.class));
mController = new TestPreferenceController(mActivity, mFragment);
final String key = mController.getPreferenceKey();
when(mPreference.getKey()).thenReturn(key);
@@ -66,28 +69,28 @@
@Test
public void getAvailabilityStatus_managedProfile_shouldReturnDisabled() {
- when(mUserManager.isManagedProfile()).thenReturn(true);
+ mShadowUserManager.setManagedProfile(true);
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(DefaultAppShortcutPreferenceControllerBase.DISABLED_FOR_USER);
+ .isEqualTo(DefaultAppShortcutPreferenceControllerBase.DISABLED_FOR_USER);
}
@Test
public void getAvailabilityStatus_hasAppCapability_shouldReturnAvailable() {
mController.capable = true;
- when(mUserManager.isManagedProfile()).thenReturn(false);
+ mShadowUserManager.setManagedProfile(false);
assertThat(mController.getAvailabilityStatus())
- .isEqualTo(DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
+ .isEqualTo(DefaultAppShortcutPreferenceControllerBase.AVAILABLE);
}
@Test
public void getAvailabilityStatus_noAppCapability_shouldReturnDisabled() {
mController.capable = false;
- when(mUserManager.isManagedProfile()).thenReturn(false);
+ mShadowUserManager.setManagedProfile(false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
- DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
+ DefaultAppShortcutPreferenceControllerBase.UNSUPPORTED_ON_DEVICE);
}
@Test
@@ -111,13 +114,17 @@
@Test
public void handlePreferenceTreeClick_shouldStartDefaultAppSettings() {
+ final ShadowActivity shadowActivity = shadowOf(mActivity);
+
mController.handlePreferenceTreeClick(mPreference);
- verify(mActivity).startActivity(argThat(intent -> intent != null
- && intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT).equals(
- DefaultAppSettings.class.getName())
- && intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)
- .getString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY).equals("TestKey")));
+ final Intent nextIntent = shadowActivity.getNextStartedActivity();
+ assertThat(nextIntent).isNotNull();
+ assertThat(nextIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)).isEqualTo(
+ DefaultAppSettings.class.getName());
+ assertThat(
+ nextIntent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS).getString(
+ SettingsActivity.EXTRA_FRAGMENT_ARG_KEY)).isEqualTo("TestKey");
}
private class TestPreferenceController extends DefaultAppShortcutPreferenceControllerBase {
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
index 7bfd299..03b3867 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultBrowserPreferenceControllerTest.java
@@ -109,10 +109,16 @@
doReturn(null).when(spyController).getDefaultAppIcon();
final List<ResolveInfo> resolveInfos = new ArrayList<>();
final CharSequence PACKAGE_NAME = "com.test.package";
- final ResolveInfo info1 = spy(createResolveInfo(PACKAGE_NAME.toString()));
- when(info1.loadLabel(mPackageManager)).thenReturn(PACKAGE_NAME);
+
+ // This ResolveInfo will return a non-null label from loadLabel.
+ final ResolveInfo info1 = createResolveInfo(PACKAGE_NAME.toString());
+ info1.nonLocalizedLabel = PACKAGE_NAME;
resolveInfos.add(info1);
- resolveInfos.add(createResolveInfo(PACKAGE_NAME.toString()));
+
+ // This ResolveInfo will return a null label from loadLabel.
+ final ResolveInfo info2 = createResolveInfo(PACKAGE_NAME.toString());
+ resolveInfos.add(info2);
+
when(mPackageManager.getDefaultBrowserPackageNameAsUser(anyInt())).thenReturn(null);
when(mPackageManager.queryIntentActivitiesAsUser(any(Intent.class), anyInt(), anyInt()))
.thenReturn(resolveInfos);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java
index 4deec56..4504d84 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothSliceBuilderTest.java
@@ -25,14 +25,12 @@
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import org.junit.Before;
import org.junit.Test;
@@ -60,7 +58,10 @@
@Test
public void getBluetoothSlice_correctSliceContent() {
final Slice BluetoothSlice = BluetoothSliceBuilder.getSlice(mContext);
+
final SliceMetadata metadata = SliceMetadata.from(mContext, BluetoothSlice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.bluetooth_settings_title));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).hasSize(1);
@@ -69,9 +70,6 @@
final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_settings_bluetooth);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString());
-
- final List<SliceItem> sliceItems = BluetoothSlice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.bluetooth_settings_title));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
index bd7f79e..c8467b2 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
@@ -38,7 +38,6 @@
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -80,7 +79,6 @@
return (AlertDialog) ShadowDialog.getLatestDialog();
}
- @Ignore("b/119592320")
@Test
public void deviceNameDisplayIsCorrect() {
String deviceName = "ABC Corp Headphones";
@@ -96,7 +94,6 @@
assertThat(negativeButton.isEnabled()).isTrue();
}
- @Ignore("b/119592320")
@Test
public void deviceNameEditSucceeds() {
String deviceNameInitial = "ABC Corp Headphones";
@@ -119,7 +116,6 @@
verify(mCachedDevice).setName(deviceNameModified);
}
- @Ignore("b/119592320")
@Test
public void deviceNameEditThenCancelDoesntRename() {
String deviceNameInitial = "ABC Corp Headphones";
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerTest.java
index fc674f0b..0c74525 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionPreferenceControllerTest.java
@@ -16,8 +16,11 @@
package com.android.settings.deviceinfo.firmwareversion;
+import static android.content.Context.CLIPBOARD_SERVICE;
+
import static com.google.common.truth.Truth.assertThat;
+import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
@@ -108,6 +111,17 @@
assertThat(mController.isSliceable()).isTrue();
}
+ @Test
+ public void copy_shouldCopyVersionNumberToClipboard() {
+ mController.copy();
+
+ final Context context = RuntimeEnvironment.application;
+ final ClipboardManager clipboard = (ClipboardManager) context.getSystemService(
+ CLIPBOARD_SERVICE);
+ final CharSequence data = clipboard.getPrimaryClip().getItemAt(0).getText();
+ assertThat(data.toString()).isEqualTo(Build.VERSION.RELEASE);
+ }
+
@Implements(FirmwareVersionDialogFragment.class)
public static class ShadowFirmwareVersionDialogFragment {
diff --git a/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceTest.java b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceTest.java
index fe7a685..224d2ee 100644
--- a/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceTest.java
+++ b/tests/robotests/src/com/android/settings/flashlight/FlashlightSliceTest.java
@@ -23,14 +23,12 @@
import android.provider.Settings;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import org.junit.Before;
import org.junit.Test;
@@ -57,13 +55,13 @@
public void getFlashlightSlice_correctData() {
Settings.Secure.putInt(
mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
+
final Slice slice = new FlashlightSlice(mContext).getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.power_flashlight));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).hasSize(1);
-
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.power_flashlight));
}
}
diff --git a/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceControllerTest.java
index 10a3d90..cd21351 100644
--- a/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/WakeLockScreenGesturePreferenceControllerTest.java
@@ -71,7 +71,7 @@
@Test
public void getAvailabilityStatus_gestureNotSupported_UNSUPPORTED_ON_DEVICE() {
- when(mAmbientDisplayConfiguration.wakeLockScreenGestureAvailable()).thenReturn(false);
+ when(mAmbientDisplayConfiguration.wakeScreenGestureAvailable()).thenReturn(false);
final int availabilityStatus = mController.getAvailabilityStatus();
assertThat(availabilityStatus).isEqualTo(UNSUPPORTED_ON_DEVICE);
@@ -79,7 +79,7 @@
@Test
public void getAvailabilityStatus_gestureSupported_AVAILABLE() {
- when(mAmbientDisplayConfiguration.wakeLockScreenGestureAvailable()).thenReturn(true);
+ when(mAmbientDisplayConfiguration.wakeScreenGestureAvailable()).thenReturn(true);
final int availabilityStatus = mController.getAvailabilityStatus();
assertThat(availabilityStatus).isEqualTo(AVAILABLE);
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySliceTest.java
index 4699587..289a57d 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/BatterySliceTest.java
@@ -26,14 +26,12 @@
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import org.junit.Before;
import org.junit.Test;
@@ -41,8 +39,6 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import java.util.List;
-
@RunWith(RobolectricTestRunner.class)
public class BatterySliceTest {
@@ -64,14 +60,16 @@
doNothing().when(mBatterySlice).loadBatteryInfo();
doReturn("10%").when(mBatterySlice).getBatteryPercentString();
doReturn("test").when(mBatterySlice).getSummary();
+
final Slice slice = mBatterySlice.getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.power_usage_summary_title));
+
final SliceAction primaryAction = metadata.getPrimaryAction();
final IconCompat expectedIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_settings_battery);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedIcon.toString());
-
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.power_usage_summary_title));
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSliceTest.java
index 1a3be6c..588b7aa 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DataUsageSliceTest.java
@@ -69,24 +69,31 @@
ShadowDataUsageUtils.HAS_SIM = true;
doReturn(DATA_USAGE_TITLE).when(mDataUsageSlice).getDataUsageText(any());
doReturn(DATA_USAGE_SUMMARY).when(mDataUsageSlice).getCycleTime(any());
+
final Slice slice = mDataUsageSlice.getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.data_usage_summary_title));
+
final SliceAction primaryAction = metadata.getPrimaryAction();
final IconCompat expectedIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_settings_data_usage);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedIcon.toString());
-
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.data_usage_summary_title));
}
@Test
public void getSlice_hasNoSim_shouldShowNoSimCard() {
ShadowDataUsageUtils.HAS_SIM = false;
- final Slice slice = mDataUsageSlice.getSlice();
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.data_usage_summary_title));
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.no_sim_card));
+ final Slice slice = mDataUsageSlice.getSlice();
+
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.data_usage_summary_title));
+
+ final List<SliceItem> sliceItems = slice.getItems();
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems,
+ mContext.getString(R.string.no_sim_card));
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSliceTest.java
index c1d7329..ddc7218 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/DeviceInfoSliceTest.java
@@ -70,24 +70,30 @@
final String phoneNumber = "1111111111";
doReturn(mSubscriptionInfo).when(mDeviceInfoSlice).getFirstSubscriptionInfo();
doReturn(phoneNumber).when(mDeviceInfoSlice).getPhoneNumber();
+
final Slice slice = mDeviceInfoSlice.getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.device_info_label));
+
final SliceAction primaryAction = metadata.getPrimaryAction();
final IconCompat expectedIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_info_outline_24dp);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedIcon.toString());
final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.device_info_label));
- SliceTester.assertTitle(sliceItems, phoneNumber);
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, phoneNumber);
}
@Test
public void getSlice_hasNoSubscriptionInfo_shouldShowUnknown() {
final Slice slice = mDeviceInfoSlice.getSlice();
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.device_info_label));
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.device_info_default));
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.device_info_label));
+
+ final List<SliceItem> sliceItems = slice.getItems();
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems,
+ mContext.getString(R.string.device_info_default));
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSliceTest.java
index dc125e2..a758a94 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/deviceinfo/StorageSliceTest.java
@@ -26,14 +26,12 @@
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import org.junit.Before;
@@ -42,8 +40,6 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import java.util.List;
-
@RunWith(RobolectricTestRunner.class)
public class StorageSliceTest {
private static final String USED_BYTES_TEXT = "test used bytes";
@@ -68,14 +64,15 @@
doReturn(info).when(mStorageSlice).getPrivateStorageInfo();
doReturn(USED_BYTES_TEXT).when(mStorageSlice).getStorageUsedText(any());
doReturn(SUMMARY_TEXT).when(mStorageSlice).getStorageSummaryText(any());
+
final Slice slice = mStorageSlice.getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.storage_label));
+
final SliceAction primaryAction = metadata.getPrimaryAction();
final IconCompat expectedIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_homepage_storage);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedIcon.toString());
-
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.storage_label));
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java
index 12ae707..bc34fd5 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSliceTest.java
@@ -106,8 +106,8 @@
final Slice slice = mBluetoothDevicesSlice.getSlice();
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.bluetooth_devices));
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.bluetooth_devices));
}
@Test
@@ -118,7 +118,7 @@
final Slice slice = mBluetoothDevicesSlice.getSlice();
final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, BLUETOOTH_MOCK_TITLE);
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems, BLUETOOTH_MOCK_TITLE);
}
@Test
@@ -129,7 +129,7 @@
final Slice slice = mBluetoothDevicesSlice.getSlice();
final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems,
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems,
mContext.getString(R.string.bluetooth_pairing_pref_title));
}
@@ -139,8 +139,9 @@
final Slice slice = mBluetoothDevicesSlice.getSlice();
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.no_bluetooth_devices));
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.no_bluetooth_devices));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java
index 3bd29b9..99f2723 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/LowStorageSliceTest.java
@@ -23,12 +23,11 @@
import android.content.Context;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
+import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
@@ -43,8 +42,6 @@
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Resetter;
-import java.util.List;
-
@RunWith(RobolectricTestRunner.class)
public class LowStorageSliceTest {
@@ -73,8 +70,8 @@
final Slice slice = mLowStorageSlice.getSlice();
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.storage_menu_free));
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.storage_menu_free));
}
@Test
@@ -94,8 +91,8 @@
final Slice slice = mLowStorageSlice.getSlice();
- final List<SliceItem> sliceItems = slice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.storage_settings));
+ final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.storage_settings));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/location/LocationSliceTest.java b/tests/robotests/src/com/android/settings/location/LocationSliceTest.java
index 427307d..0618cd9 100644
--- a/tests/robotests/src/com/android/settings/location/LocationSliceTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationSliceTest.java
@@ -6,14 +6,12 @@
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import org.junit.Before;
import org.junit.Test;
@@ -39,7 +37,10 @@
@Test
public void getLocationSlice_correctSliceContent() {
final Slice LocationSlice = new LocationSlice(mContext).getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, LocationSlice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.location_settings_title));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).isEmpty();
@@ -48,8 +49,5 @@
final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_signal_location);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString());
-
- final List<SliceItem> sliceItems = LocationSlice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.location_settings_title));
}
}
diff --git a/tests/robotests/src/com/android/settings/location/TopLevelLocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/TopLevelLocationPreferenceControllerTest.java
new file mode 100644
index 0000000..68e7f88
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/location/TopLevelLocationPreferenceControllerTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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.settings.location;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.location.LocationManager;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class TopLevelLocationPreferenceControllerTest {
+ private static final String PREFERENCE_KEY = "top_level_location";
+ private Context mContext;
+ private TopLevelLocationPreferenceController mController;
+ private LocationManager mLocationManager;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mController = new TopLevelLocationPreferenceController(mContext, PREFERENCE_KEY);
+ mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+ }
+
+ @Test
+ public void isAvailable_byDefault_shouldReturnTrue() {
+ assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void getSummary_whenLocationIsOff_shouldReturnStringForOff() {
+ mLocationManager.setLocationEnabledForUser(false, android.os.Process.myUserHandle());
+ assertThat(mController.getSummary()).isEqualTo(
+ mContext.getString(R.string.location_settings_summary_location_off));
+ }
+
+ @Test
+ public void getSummary_whenLocationIsOn_shouldShowLoadingString() {
+ mLocationManager.setLocationEnabledForUser(true, android.os.Process.myUserHandle());
+ assertThat(mController.getSummary()).isEqualTo(
+ mContext.getString(R.string.location_settings_loading_app_permission_stats));
+ }
+
+ @Test
+ public void getSummary_whenLocationAppCountIsOne_shouldShowSingularString() {
+ final int LOCATION_APP_COUNT = 1;
+ mLocationManager.setLocationEnabledForUser(true, android.os.Process.myUserHandle());
+ mController.setLocationAppCount(LOCATION_APP_COUNT);
+ assertThat(mController.getSummary()).isEqualTo(
+ mContext.getResources().getQuantityString(
+ R.plurals.location_settings_summary_location_on,
+ LOCATION_APP_COUNT, LOCATION_APP_COUNT));
+ }
+
+ @Test
+ public void getSummary_whenLocationAppCountIsGreaterThanOne_shouldShowPluralString() {
+ final int LOCATION_APP_COUNT = 5;
+ mLocationManager.setLocationEnabledForUser(true, android.os.Process.myUserHandle());
+ mController.setLocationAppCount(LOCATION_APP_COUNT);
+ assertThat(mController.getSummary()).isEqualTo(
+ mContext.getResources().getQuantityString(
+ R.plurals.location_settings_summary_location_on,
+ LOCATION_APP_COUNT, LOCATION_APP_COUNT));
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
index 5144877..89d0465fa 100644
--- a/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/VpnPreferenceControllerTest.java
@@ -34,6 +34,7 @@
import android.net.NetworkRequest;
import android.os.IBinder;
import android.os.UserHandle;
+import android.os.ServiceManager;
import android.provider.SettingsSlicesContract;
import androidx.lifecycle.LifecycleOwner;
@@ -50,7 +51,6 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowServiceManager;
@RunWith(RobolectricTestRunner.class)
public class VpnPreferenceControllerTest {
@@ -78,7 +78,7 @@
.thenReturn(mConnectivityManager);
when(mBinder.queryLocalInterface("android.net.IConnectivityManager"))
.thenReturn(mConnectivityManagerService);
- ShadowServiceManager.addService(Context.CONNECTIVITY_SERVICE, mBinder);
+ ServiceManager.addService(Context.CONNECTIVITY_SERVICE, mBinder);
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
mController = spy(new VpnPreferenceController(mContext));
diff --git a/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
index 9b8a3e3..ba8be90 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceControllerTest.java
@@ -125,6 +125,18 @@
}
@Test
+ public void updateState_updateByNetworkMode_useDefaultValue() {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID,
+ TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.getValue()).isEqualTo(
+ String.valueOf(TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA));
+ }
+
+ @Test
public void onPreferenceChange_updateSuccess() {
doReturn(true).when(mTelephonyManager).setPreferredNetworkType(SUB_ID,
TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA);
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java
index 6169f92..6cf19a6 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeBackendTest.java
@@ -1,26 +1,58 @@
package com.android.settings.notification;
+import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertEquals;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.database.Cursor;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class ZenModeBackendTest {
+ @Mock
+ private NotificationManager mNotificationManager;
private static final String GENERIC_RULE_NAME = "test";
private static final String DEFAULT_ID_1 = ZenModeConfig.EVENTS_DEFAULT_RULE_ID;
private static final String DEFAULT_ID_2 = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
+ private Context mContext;
+ private ZenModeBackend mBackend;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = RuntimeEnvironment.application;
+ mBackend = new ZenModeBackend(mContext);
+ }
+
@Test
public void updateState_checkRuleOrderingDescending() {
final int NUM_RULES = 4;
@@ -63,6 +95,39 @@
}
}
+ @Test
+ public void updateSummary_nullCursorValues() {
+ Cursor testCursorWithNullValues = createMockCursor(3);
+ when(testCursorWithNullValues.getString(0)).thenReturn(null);
+
+ // expected - no null values
+ List<String> contacts = mBackend.getStarredContacts(testCursorWithNullValues);
+ for (String contact : contacts) {
+ assertThat(contact).isNotNull();
+ }
+ }
+
+ private Cursor createMockCursor(int size) {
+ Cursor mockCursor = mock(Cursor.class);
+ when(mockCursor.moveToFirst()).thenReturn(true);
+
+ doAnswer(new Answer<Boolean>() {
+ int count = 0;
+
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ if (count < size) {
+ count++;
+ return true;
+ }
+ return false;
+ }
+
+ }).when(mockCursor).moveToNext();
+
+ return mockCursor;
+ }
+
private Map.Entry<String, AutomaticZenRule>[] populateAutoZenRulesAscendingCreationTime(
int numRules, boolean addDefaultRules) {
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java
index 5589cae..808766d 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java
@@ -17,12 +17,16 @@
package com.android.settings.notification;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
import android.content.Context;
+import androidx.preference.Preference;
+
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -67,11 +71,10 @@
assertTrue(mController.isAvailable());
}
-// TODO: (b/111475013 - beverlyt) set messages summary
-// @Test
-// public void testHasSummary() {
-// Preference pref = mock(Preference.class);
-// mController.updateState(pref);
-// verify(pref).setSummary(any());
-// }
+ @Test
+ public void testHasSummary() {
+ Preference pref = mock(Preference.class);
+ mController.updateState(pref);
+ verify(pref).setSummary(any());
+ }
}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceControllerTest.java
index 516d98f..3451868 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeSettingsFooterPreferenceControllerTest.java
@@ -22,9 +22,8 @@
import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;
-import static org.junit.Assert.assertTrue;
-
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -40,6 +39,7 @@
import android.service.notification.ZenModeConfig.ZenRule;
import android.util.ArrayMap;
+import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@@ -92,8 +92,8 @@
mContentResolver = RuntimeEnvironment.application.getContentResolver();
when(mNotificationManager.getZenModeConfig()).thenReturn(mZenModeConfig);
- mController =
- new ZenModeSettingsFooterPreferenceController(mContext, mock(Lifecycle.class));
+ mController = new ZenModeSettingsFooterPreferenceController(mContext, mock(Lifecycle.class),
+ mock(FragmentManager.class));
ReflectionHelpers.setField(mZenModeConfig, AUTOMATIC_RULES_FIELD, mInjectedAutomaticRules);
ReflectionHelpers.setField(mController, "mZenModeConfigWrapper", mConfigWrapper);
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeSliceBuilderTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeSliceBuilderTest.java
index bc9e370..ac185ac 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeSliceBuilderTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeSliceBuilderTest.java
@@ -26,14 +26,12 @@
import android.provider.Settings;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import com.android.settings.testutils.shadow.ShadowNotificationManager;
import org.junit.Before;
@@ -62,16 +60,16 @@
@Test
public void getZenModeSlice_correctSliceContent() {
final Slice dndSlice = ZenModeSliceBuilder.getSlice(mContext);
+
final SliceMetadata metadata = SliceMetadata.from(mContext, dndSlice);
+ assertThat(metadata.getTitle()).isEqualTo(
+ mContext.getString(R.string.zen_mode_settings_title));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).hasSize(1);
final SliceAction primaryAction = metadata.getPrimaryAction();
assertThat(primaryAction.getIcon()).isNull();
-
- final List<SliceItem> sliceItems = dndSlice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.zen_mode_settings_title));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
index db551a2..fd6e639 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeStarredContactsPreferenceControllerTest.java
@@ -30,7 +30,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.database.Cursor;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
@@ -49,7 +48,6 @@
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
-import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class ZenModeStarredContactsPreferenceControllerTest {
@@ -157,18 +155,6 @@
}
@Test
- public void updateSummary_nullCursorValues() {
- Cursor testCursorWithNullValues = createMockCursor(3);
- when(testCursorWithNullValues.getString(0)).thenReturn(null);
-
- // expected - no null values
- List<String> contacts = mMessagesController.getStarredContacts(testCursorWithNullValues);
- for (String contact : contacts) {
- assertThat(contact).isNotNull();
- }
- }
-
- @Test
public void nullPreference_displayPreference() {
when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
.thenReturn(null);
@@ -176,25 +162,4 @@
// should not throw a null pointer
mMessagesController.displayPreference(mPreferenceScreen);
}
-
- private Cursor createMockCursor(int size) {
- Cursor mockCursor = mock(Cursor.class);
- when(mockCursor.moveToFirst()).thenReturn(true);
-
- doAnswer(new Answer<Boolean>() {
- int count = 0;
-
- @Override
- public Boolean answer(InvocationOnMock invocation) {
- if (count < size) {
- count++;
- return true;
- }
- return false;
- }
-
- }).when(mockCursor).moveToNext();
-
- return mockCursor;
- }
}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleCustomPolicyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleCustomPolicyPreferenceControllerTest.java
new file mode 100644
index 0000000..5d3a601
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleCustomPolicyPreferenceControllerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleCustomPolicyPreferenceControllerTest extends
+ ZenRuleCustomPrefContrTestBase {
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ZenCustomRadioButtonPreference mockPref;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private Context mContext;
+ private ZenRuleCustomPolicyPreferenceController mController;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = RuntimeEnvironment.application;
+ mController = new ZenRuleCustomPolicyPreferenceController(mContext, mock(Lifecycle.class),
+ PREF_KEY);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ mController.displayPreference(mScreen);
+ }
+
+ @Test
+ public void updateState_nullZenPolicy() {
+ updateControllerZenPolicy(null);
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_hasZenPolicy() {
+ updateControllerZenPolicy(new ZenPolicy.Builder().build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(true);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleCustomPrefContrTestBase.java b/tests/robotests/src/com/android/settings/notification/ZenRuleCustomPrefContrTestBase.java
new file mode 100644
index 0000000..10472a5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleCustomPrefContrTestBase.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.service.notification.ZenPolicy;
+
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+abstract class ZenRuleCustomPrefContrTestBase {
+ public static final String RULE_ID = "test_rule_id";
+ public static final String PREF_KEY = "main_pref";
+
+ AutomaticZenRule mRule = new AutomaticZenRule("test", null, null, null, null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+
+ abstract AbstractZenCustomRulePreferenceController getController();
+
+ void updateControllerZenPolicy(ZenPolicy policy) {
+ mRule.setZenPolicy(policy);
+ getController().onResume(mRule, RULE_ID);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleCustomSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleCustomSwitchPreferenceControllerTest.java
new file mode 100644
index 0000000..e15eb60
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleCustomSwitchPreferenceControllerTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleCustomSwitchPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
+ private ZenRuleCustomSwitchPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private Context mContext;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = RuntimeEnvironment.application;
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ mController = new ZenRuleCustomSwitchPreferenceController(mContext, mock(Lifecycle.class),
+ PREF_KEY, ZenPolicy.PRIORITY_CATEGORY_ALARMS, 0);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
+ .thenReturn(mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void onPreferenceChanged_enable() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowMedia(false)
+ .allowAlarms(false)
+ .build());
+ mController.onPreferenceChange(mockPref, true);
+ mRule.setZenPolicy(new ZenPolicy.Builder()
+ .allowMedia(false)
+ .allowAlarms(true)
+ .build());
+ verify(mBackend).updateZenRule(RULE_ID, mRule);
+ }
+
+ @Test
+ public void onPreferenceChanged_disable() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowMedia(false)
+ .allowAlarms(true)
+ .build());
+ mController.onPreferenceChange(mockPref, false);
+ mRule.setZenPolicy(new ZenPolicy.Builder()
+ .allowMedia(false)
+ .allowAlarms(false)
+ .build());
+ verify(mBackend).updateZenRule(RULE_ID, mRule);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleDefaultPolicyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleDefaultPolicyPreferenceControllerTest.java
new file mode 100644
index 0000000..e350793
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleDefaultPolicyPreferenceControllerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleDefaultPolicyPreferenceControllerTest extends
+ ZenRuleCustomPrefContrTestBase {
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ZenCustomRadioButtonPreference mockPref;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private Context mContext;
+ private ZenRuleDefaultPolicyPreferenceController mController;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = RuntimeEnvironment.application;
+ mController = new ZenRuleDefaultPolicyPreferenceController(mContext, mock(Lifecycle.class),
+ PREF_KEY);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ mController.displayPreference(mScreen);
+ }
+
+ @Test
+ public void updateState_nullZenPolicy() {
+ updateControllerZenPolicy(null);
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void updateState_hasZenPolicy() {
+ updateControllerZenPolicy(new ZenPolicy.Builder().build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(false);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRulePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRulePreferenceControllerTest.java
new file mode 100644
index 0000000..5d070e5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRulePreferenceControllerTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.Context;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRulePreferenceControllerTest {
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ZenCustomRadioButtonPreference mockPref;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private Context mContext;
+ private TestablePreferenceController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = RuntimeEnvironment.application;
+ mController = new TestablePreferenceController(mContext,"test", mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ mController.displayPreference(mScreen);
+ }
+
+ @Test
+ public void onResumeTest() {
+ final String id = "testid";
+ final AutomaticZenRule rule = new AutomaticZenRule("test", null, null,
+ null, null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+
+ assertTrue(mController.mRule == null);
+ assertTrue(mController.mId == null);
+
+ mController.onResume(rule, id);
+
+ assertEquals(mController.mId, id);
+ assertEquals(mController.mRule, rule);
+ }
+
+ class TestablePreferenceController extends AbstractZenCustomRulePreferenceController {
+ TestablePreferenceController(Context context, String key,
+ Lifecycle lifecycle) {
+ super(context, key, lifecycle);
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleRepeatCallersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleRepeatCallersPreferenceControllerTest.java
new file mode 100644
index 0000000..45062d4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleRepeatCallersPreferenceControllerTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleRepeatCallersPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
+
+ private ZenRuleRepeatCallersPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private Context mContext;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = RuntimeEnvironment.application;
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ mController = new ZenRuleRepeatCallersPreferenceController(mContext, PREF_KEY,
+ mock(Lifecycle.class), 15);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mBackend.getAutomaticZenRule(anyString())).thenReturn(mRule);
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_Priority_anyCallers() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_ANYONE)
+ .allowRepeatCallers(false)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableRepeatCallers() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
+ .allowRepeatCallers(false)
+ .build());
+ mController.updateState(mockPref);
+ mController.onPreferenceChange(mockPref, true);
+ mRule.setZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
+ .allowRepeatCallers(true)
+ .build());
+ verify(mBackend).updateZenRule(RULE_ID, mRule);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableRepeatCallers() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
+ .allowRepeatCallers(true)
+ .build());
+ mController.updateState(mockPref);
+ mController.onPreferenceChange(mockPref, false);
+ mRule.setZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
+ .allowRepeatCallers(false)
+ .build());
+ verify(mBackend).updateZenRule(RULE_ID, mRule);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleStarredContactsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleStarredContactsPreferenceControllerTest.java
new file mode 100644
index 0000000..6c422eb
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleStarredContactsPreferenceControllerTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleStarredContactsPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
+
+ private ZenRuleStarredContactsPreferenceController mCallsController;
+ private ZenRuleStarredContactsPreferenceController mMessagesController;
+ private static int CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private Preference mockPref;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ @Mock
+ private Intent testIntent;
+ @Mock
+ private ComponentName mComponentName;
+ private Context mContext;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ if (CURR_CONTROLLER == ZenPolicy.PRIORITY_CATEGORY_MESSAGES) {
+ return mMessagesController;
+ } else {
+ return mCallsController;
+ }
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = RuntimeEnvironment.application;
+ when(testIntent.resolveActivity(any())).thenReturn(mComponentName);
+
+ mCallsController = new ZenRuleStarredContactsPreferenceController(
+ mContext, mock(Lifecycle.class), ZenPolicy.PRIORITY_CATEGORY_CALLS,
+ "zen_mode_starred_contacts_callers");
+ when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
+ ReflectionHelpers.setField(mCallsController, "mBackend", mBackend);
+ ReflectionHelpers.setField(mCallsController, "mStarredContactsIntent", testIntent);
+ when(mPreferenceScreen.findPreference(mCallsController.getPreferenceKey()))
+ .thenReturn(mockPref);
+ mCallsController.displayPreference(mPreferenceScreen);
+
+ mMessagesController = new ZenRuleStarredContactsPreferenceController(
+ mContext, mock(Lifecycle.class), ZenPolicy.PRIORITY_CATEGORY_MESSAGES,
+ "zen_mode_starred_contacts_messages");
+ ReflectionHelpers.setField(mMessagesController, "mBackend", mBackend);
+ ReflectionHelpers.setField(mMessagesController, "mStarredContactsIntent", testIntent);
+ when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
+ .thenReturn(mockPref);
+ mMessagesController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void isAvailable_noCallers() {
+ CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE)
+ .build());
+ assertThat(mCallsController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_anyCallers() {
+ CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_ANYONE)
+ .build());
+
+ assertThat(mCallsController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_starredCallers() {
+ CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_CALLS;
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowCalls(ZenPolicy.PEOPLE_TYPE_STARRED)
+ .build());
+
+ assertThat(mCallsController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_noMessages() {
+ CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_MESSAGES;
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowMessages(ZenPolicy.PEOPLE_TYPE_NONE)
+ .build());
+ assertThat(mCallsController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_anyMessages() {
+ CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_MESSAGES;
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowMessages(ZenPolicy.PEOPLE_TYPE_ANYONE)
+ .build());
+
+ assertThat(mMessagesController.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void isAvailable_starredMessageContacts() {
+ CURR_CONTROLLER = ZenPolicy.PRIORITY_CATEGORY_MESSAGES;
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .allowMessages(ZenPolicy.PEOPLE_TYPE_STARRED)
+ .build());
+
+ assertThat(mMessagesController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void nullPreference_displayPreference() {
+ when(mPreferenceScreen.findPreference(mMessagesController.getPreferenceKey()))
+ .thenReturn(null);
+
+ // should not throw a null pointer
+ mMessagesController.displayPreference(mPreferenceScreen);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectPreferenceControllerTest.java
new file mode 100644
index 0000000..c99d207
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectPreferenceControllerTest.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.widget.DisabledCheckBoxPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleVisEffectPreferenceControllerTest extends ZenRuleCustomPrefContrTestBase {
+
+ private static final @ZenPolicy.VisualEffect int EFFECT_PEEK = ZenPolicy.VISUAL_EFFECT_PEEK;
+ private static final @ZenPolicy.VisualEffect int PARENT_EFFECT1 = ZenPolicy.VISUAL_EFFECT_BADGE;
+ private static final @ZenPolicy.VisualEffect int PARENT_EFFECT2 =
+ ZenPolicy.VISUAL_EFFECT_NOTIFICATION_LIST;
+ private static final int PREF_METRICS = 1;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private DisabledCheckBoxPreference mockPref;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ NotificationManager mNotificationManager;
+
+ private Context mContext;
+ private ZenRuleVisEffectPreferenceController mController;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(
+ mock(NotificationManager.Policy.class));
+
+ mContext = RuntimeEnvironment.application;
+ mController = new ZenRuleVisEffectPreferenceController(mContext, mock(Lifecycle.class),
+ PREF_KEY, EFFECT_PEEK, PREF_METRICS, null);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
+
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ mController.displayPreference(mScreen);
+ }
+
+ @Test
+ public void isAvailable() {
+ // VISUAL_EFFECT_PEEK isn't available until after onResume is called
+ assertFalse(mController.isAvailable());
+ updateControllerZenPolicy(new ZenPolicy()); // calls onResume
+ assertTrue(mController.isAvailable());
+
+ // VISUAL_EFFECT_LIGHTS is only available if the device has an LED:
+ Context mockContext = mock(Context.class);
+ mController = new ZenRuleVisEffectPreferenceController(mockContext, mock(Lifecycle.class),
+ PREF_KEY, ZenPolicy.VISUAL_EFFECT_LIGHTS, PREF_METRICS, null);
+ updateControllerZenPolicy(new ZenPolicy()); // calls onResume
+
+ Resources mockResources = mock(Resources.class);
+ when(mockContext.getResources()).thenReturn(mockResources);
+
+ when(mockResources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed))
+ .thenReturn(false); // no light
+ assertFalse(mController.isAvailable());
+
+ when(mockResources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed))
+ .thenReturn(true); // has light
+ assertTrue(mController.isAvailable());
+ }
+
+ @Test
+ public void updateState_notChecked() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showPeeking(true)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(false);
+ verify(mockPref).enableCheckbox(true);
+ }
+
+ @Test
+ public void updateState_checked() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showPeeking(false)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(true);
+ verify(mockPref).enableCheckbox(true);
+ }
+
+ @Test
+ public void updateState_checkedFalse_parentChecked() {
+ mController.mParentSuppressedEffects = new int[]{PARENT_EFFECT1, PARENT_EFFECT2};
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showVisualEffect(EFFECT_PEEK, true)
+ .showVisualEffect(PARENT_EFFECT1, true)
+ .showVisualEffect(PARENT_EFFECT2, false)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(true);
+ verify(mockPref).enableCheckbox(false);
+ }
+
+ @Test
+ public void updateState_checkedFalse_parentNotChecked() {
+ mController.mParentSuppressedEffects = new int[]{PARENT_EFFECT1, PARENT_EFFECT2};
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showVisualEffect(EFFECT_PEEK, true)
+ .showVisualEffect(PARENT_EFFECT1, true)
+ .showVisualEffect(PARENT_EFFECT2, true)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(false);
+ verify(mockPref).enableCheckbox(true);
+ }
+
+ @Test
+ public void onPreferenceChanged_checkedFalse() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showPeeking(false)
+ .build());
+ mController.onPreferenceChange(mockPref, false);
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .showPeeking(true)
+ .build());
+ verify(mBackend).updateZenRule(RULE_ID, mRule);
+ }
+
+ @Test
+ public void onPreferenceChanged_checkedTrue() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showPeeking(true)
+ .build());
+ mController.onPreferenceChange(mockPref, true);
+ mRule.setZenPolicy(new ZenPolicy.Builder(mRule.getZenPolicy())
+ .showPeeking(false)
+ .build());
+ verify(mBackend).updateZenRule(RULE_ID, mRule);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsAllPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsAllPreferenceControllerTest.java
new file mode 100644
index 0000000..5ef6194
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsAllPreferenceControllerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleVisEffectsAllPreferenceControllerTest extends
+ ZenRuleCustomPrefContrTestBase {
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ZenCustomRadioButtonPreference mockPref;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private ZenRuleVisEffectsAllPreferenceController mController;
+ private Context mContext;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+ mContext = RuntimeEnvironment.application;
+ mController = new ZenRuleVisEffectsAllPreferenceController(mContext, mock(Lifecycle.class),
+ PREF_KEY);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ mController.displayPreference(mScreen);
+ }
+
+ @Test
+ public void updateState_noVisEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .hideAllVisualEffects()
+ .build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_showAllVisualEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showAllVisualEffects()
+ .build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void updateState_customEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showPeeking(true)
+ .showBadges(false)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(false);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsCustomPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsCustomPreferenceControllerTest.java
new file mode 100644
index 0000000..79ef8d2
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsCustomPreferenceControllerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleVisEffectsCustomPreferenceControllerTest extends
+ ZenRuleCustomPrefContrTestBase {
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ZenCustomRadioButtonPreference mockPref;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private ZenRuleVisEffectsCustomPreferenceController mController;
+ private Context mContext;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+ mContext = RuntimeEnvironment.application;
+ mController = new ZenRuleVisEffectsCustomPreferenceController(mContext, mock(Lifecycle.class),
+ PREF_KEY);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ mController.displayPreference(mScreen);
+ }
+
+ @Test
+ public void updateState_noVisEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .hideAllVisualEffects()
+ .build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_showAllVisualEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showAllVisualEffects()
+ .build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_customEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showPeeking(true)
+ .showBadges(false)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(true);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsNonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsNonePreferenceControllerTest.java
new file mode 100644
index 0000000..d66433e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenRuleVisEffectsNonePreferenceControllerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2018 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.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.service.notification.ZenPolicy;
+
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenRuleVisEffectsNonePreferenceControllerTest extends
+ ZenRuleCustomPrefContrTestBase {
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private ZenCustomRadioButtonPreference mockPref;
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private ZenRuleVisEffectsNonePreferenceController mController;
+ private Context mContext;
+
+ @Override
+ AbstractZenCustomRulePreferenceController getController() {
+ return mController;
+ }
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+ mContext = RuntimeEnvironment.application;
+ mController = new ZenRuleVisEffectsNonePreferenceController(mContext, mock(Lifecycle.class),
+ PREF_KEY);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ when(mBackend.getAutomaticZenRule(RULE_ID)).thenReturn(mRule);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mockPref);
+ mController.displayPreference(mScreen);
+ }
+
+ @Test
+ public void updateState_noVisEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .hideAllVisualEffects()
+ .build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void updateState_showAllVisualEffects() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showAllVisualEffects()
+ .build());
+ mController.updateState(mockPref);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_custom() {
+ updateControllerZenPolicy(new ZenPolicy.Builder()
+ .showPeeking(true)
+ .showBadges(false)
+ .build());
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(false);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
index 7eb64b9..d7aa42c 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
@@ -28,6 +28,7 @@
import android.content.pm.ServiceInfo;
import android.service.trust.TrustAgentService;
+import android.text.TextUtils;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
@@ -96,7 +97,7 @@
@Test
public void onStart_noTrustAgent_shouldNotAddPreference() {
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
- mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
mController.displayPreference(mPreferenceScreen);
mController.onStart();
@@ -109,15 +110,16 @@
onStart_hasAUninstalledTrustAgent_shouldRemoveOnePreferenceAndLeaveTwoPreferences() {
final List<ResolveInfo> availableAgents = createFakeAvailableAgents();
final ResolveInfo uninstalledTrustAgent = availableAgents.get(0);
+
for (ResolveInfo rInfo : availableAgents) {
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
}
- mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
mController.displayPreference(mPreferenceScreen);
mController.onStart();
availableAgents.remove(uninstalledTrustAgent);
- mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
mController.onStart();
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(2);
@@ -131,13 +133,13 @@
for (ResolveInfo rInfo : availableAgents) {
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
}
- mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
mController.displayPreference(mPreferenceScreen);
mController.onStart();
availableAgents.add(newTrustAgent);
ShadowTrustAgentManager.grantPermissionToResolveInfo(newTrustAgent);
- mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
mController.onStart();
assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(4);
@@ -150,7 +152,7 @@
for (ResolveInfo rInfo : availableAgents) {
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
}
- mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
mController.displayPreference(mPreferenceScreen);
mController.onStart();
@@ -169,7 +171,7 @@
for (ResolveInfo rInfo : availableAgents) {
ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
}
- mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mPackageManager.setResolveInfosForIntent(TEST_INTENT, availableAgents);
ShadowRestrictedLockUtilsInternal.setKeyguardDisabledFeatures(
DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
@@ -213,8 +215,14 @@
private final static List<ResolveInfo> sPermissionGrantedList = new ArrayList<>();
@Implementation
- public boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm) {
- return sPermissionGrantedList.contains(resolveInfo);
+ protected boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm) {
+ for (ResolveInfo info : sPermissionGrantedList) {
+ if (info.serviceInfo.equals(resolveInfo.serviceInfo)) {
+ return true;
+ }
+ }
+
+ return false;
}
private static void grantPermissionToResolveInfo(ResolveInfo rInfo) {
diff --git a/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
index e132aac..f9cedb3 100644
--- a/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
@@ -118,13 +118,13 @@
ri2.activityInfo.applicationInfo = new ApplicationInfo();
ri2.activityInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
- mPackageManager.addResolveInfoForIntent(
+ mPackageManager.setResolveInfosForIntent(
new Intent(CreateShortcutPreferenceController.SHORTCUT_PROBE),
Arrays.asList(ri1, ri2));
final List<ResolveInfo> info = mController.queryShortcuts();
assertThat(info).hasSize(1);
- assertThat(info.get(0)).isEqualTo(ri2);
+ assertThat(info.get(0).activityInfo).isEqualTo(ri2.activityInfo);
}
@Test
@@ -143,13 +143,13 @@
ri2.activityInfo.applicationInfo = new ApplicationInfo();
ri2.activityInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
- mPackageManager.addResolveInfoForIntent(
+ mPackageManager.setResolveInfosForIntent(
new Intent(CreateShortcutPreferenceController.SHORTCUT_PROBE),
Arrays.asList(ri1, ri2));
final List<ResolveInfo> info = mController.queryShortcuts();
assertThat(info).hasSize(2);
- assertThat(info.get(0)).isEqualTo(ri2);
- assertThat(info.get(1)).isEqualTo(ri1);
+ assertThat(info.get(0).activityInfo).isEqualTo(ri2.activityInfo);
+ assertThat(info.get(1).activityInfo).isEqualTo(ri1.activityInfo);
}
}
diff --git a/tests/robotests/src/com/android/settings/shortcut/ShortcutsUpdateTaskTest.java b/tests/robotests/src/com/android/settings/shortcut/ShortcutsUpdateTaskTest.java
index 0bc0414..8352e7a 100644
--- a/tests/robotests/src/com/android/settings/shortcut/ShortcutsUpdateTaskTest.java
+++ b/tests/robotests/src/com/android/settings/shortcut/ShortcutsUpdateTaskTest.java
@@ -80,12 +80,14 @@
.setComponent(new ComponentName(
mContext, Settings.ManageApplicationsActivity.class));
final ResolveInfo ri1 = mock(ResolveInfo.class);
+ ri1.nonLocalizedLabel = "label1";
+
final Intent shortcut2 = new Intent(CreateShortcutPreferenceController.SHORTCUT_PROBE)
.setComponent(new ComponentName(
mContext, Settings.SoundSettingsActivity.class));
final ResolveInfo ri2 = mock(ResolveInfo.class);
- when(ri1.loadLabel(any(PackageManager.class))).thenReturn("label1");
- when(ri2.loadLabel(any(PackageManager.class))).thenReturn("label2");
+ ri2.nonLocalizedLabel = "label2";
+
mPackageManager.addResolveInfoForIntent(shortcut1, ri1);
mPackageManager.addResolveInfoForIntent(shortcut2, ri2);
diff --git a/tests/robotests/src/com/android/settings/testutils/SliceTester.java b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
index c0ffdcd..17edb6e 100644
--- a/tests/robotests/src/com/android/settings/testutils/SliceTester.java
+++ b/tests/robotests/src/com/android/settings/testutils/SliceTester.java
@@ -79,8 +79,7 @@
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
- final List<SliceItem> sliceItems = slice.getItems();
- assertTitle(sliceItems, sliceData.getTitle());
+ assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
@@ -122,8 +121,7 @@
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
- final List<SliceItem> sliceItems = slice.getItems();
- assertTitle(sliceItems, sliceData.getTitle());
+ assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
@@ -160,8 +158,7 @@
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
- final List<SliceItem> sliceItems = slice.getItems();
- assertTitle(sliceItems, sliceData.getTitle());
+ assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
@@ -197,8 +194,7 @@
assertThat(primaryPendingIntent).isEqualTo(
SliceBuilderUtils.getContentPendingIntent(context, sliceData));
- final List<SliceItem> sliceItems = slice.getItems();
- assertTitle(sliceItems, sliceData.getTitle());
+ assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
@@ -230,14 +226,18 @@
assertThat(primaryPendingIntent).isEqualTo(SliceBuilderUtils.getContentPendingIntent(
context, sliceData));
- final List<SliceItem> sliceItems = slice.getItems();
- assertTitle(sliceItems, sliceData.getTitle());
+ assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
assertKeywords(metadata, sliceData);
}
- // TODO(b/120592507): Clean up method of SliceTester
- public static void assertTitle(List<SliceItem> sliceItems, String title) {
+ /**
+ * Assert any slice item contains title.
+ *
+ * @param sliceItems All slice items of a Slice.
+ * @param title Title for asserting.
+ */
+ public static void assertAnySliceItemContainsTitle(List<SliceItem> sliceItems, String title) {
boolean hasTitle = false;
for (SliceItem item : sliceItems) {
List<SliceItem> titleItems = SliceQuery.findAll(item, FORMAT_TEXT, HINT_TITLE,
@@ -256,7 +256,6 @@
assertThat(hasTitle).isTrue();
}
- // TODO(b/120592507): Clean up method of SliceTester
private static void assertKeywords(SliceMetadata metadata, SliceData data) {
final List<String> keywords = metadata.getSliceKeywords();
final Set<String> expectedKeywords = Arrays.stream(data.getKeywords().split(","))
@@ -266,4 +265,4 @@
expectedKeywords.add(data.getScreenTitle().toString());
assertThat(keywords).containsExactlyElementsIn(expectedKeywords);
}
-}
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
index 1435529..363e046 100644
--- a/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
+++ b/tests/robotests/src/com/android/settings/webview/WebViewAppPickerTest.java
@@ -39,6 +39,7 @@
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.graphics.drawable.ColorDrawable;
import android.os.UserManager;
import android.webkit.UserPackage;
@@ -56,6 +57,8 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.util.ReflectionHelpers;
import java.util.Arrays;
@@ -341,6 +344,11 @@
when(mPackageManager.getPackageInfo(eq(DEFAULT_PACKAGE_NAME), anyInt())).thenReturn(
packageInfo);
+ // Subvert attempts to load an unbadged icon for the application.
+ PackageManager pm = RuntimeEnvironment.application.getPackageManager();
+ ShadowPackageManager spm = Shadows.shadowOf(pm);
+ spm.setUnbadgedApplicationIcon(DEFAULT_PACKAGE_NAME, new ColorDrawable());
+
RadioButtonPreference mockPreference = mock(RadioButtonPreference.class);
mPicker.bindPreference(mockPreference, DEFAULT_PACKAGE_NAME, webviewAppInfo, null);
mPicker
diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java
index 8bbb2be..20c5838 100644
--- a/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java
@@ -38,8 +38,8 @@
@RunWith(RobolectricTestRunner.class)
public class WifiPrivacyPreferenceControllerTest {
- private static final int PRIVACY_RANDOMIZED = 0;
- private static final int PRIVACY_TRUSTED = 1;
+ private static final int PRIVACY_RANDOMIZED = WifiConfiguration.RANDOMIZATION_PERSISTENT;
+ private static final int PRIVACY_TRUSTED = WifiConfiguration.RANDOMIZATION_NONE;
@Mock
private WifiConfiguration mWifiConfiguration;
@@ -47,6 +47,7 @@
private WifiPrivacyPreferenceController mPreferenceController;
private Context mContext;
private DropDownPreference mDropDownPreference;
+ private String[] perferenceString;
@Before
public void setUp() {
@@ -59,6 +60,8 @@
mDropDownPreference = new DropDownPreference(mContext);
mDropDownPreference.setEntries(R.array.wifi_privacy_entries);
mDropDownPreference.setEntryValues(R.array.wifi_privacy_values);
+
+ perferenceString = mContext.getResources().getStringArray(R.array.wifi_privacy_entries);
}
@Test
@@ -67,7 +70,8 @@
mPreferenceController.updateState(mDropDownPreference);
- assertThat(mDropDownPreference.getEntry()).isEqualTo("Trusted");
+
+ assertThat(mDropDownPreference.getEntry()).isEqualTo(perferenceString[PRIVACY_TRUSTED]);
}
@Test
@@ -76,7 +80,7 @@
mPreferenceController.updateState(mDropDownPreference);
- assertThat(mDropDownPreference.getEntry()).isEqualTo("Default (use randomized MAC)");
+ assertThat(mDropDownPreference.getEntry()).isEqualTo(perferenceString[PRIVACY_RANDOMIZED]);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java b/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java
new file mode 100644
index 0000000..1b7c0a8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.settings.wifi.dpp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Intent;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class WifiNetworkConfigTest {
+ private WifiNetworkConfig mWifiConfig;
+
+ @Before
+ public void setUp() {
+ Intent intent = new Intent();
+ intent.putExtra(WifiDppUtils.EXTRA_WIFI_SSID, "Pixel:_ABCD;");
+ intent.putExtra(WifiDppUtils.EXTRA_WIFI_SECURITY, "WPA");
+ intent.putExtra(WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY, "\\012345678,");
+ mWifiConfig = WifiNetworkConfig.getValidConfigOrNull(intent);
+ }
+
+ @Test
+ public void testInitConfig_IntentReceived_QRCodeValue() {
+ String qrcode = mWifiConfig.getQrCode();
+ assertThat(qrcode).isEqualTo("WIFI:S:Pixel\\:_ABCD\\;;T:WPA;P:\\\\012345678\\,;H:false;;");
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
index 0ef0273..a57fefc 100644
--- a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
@@ -85,6 +85,11 @@
public void setTransform(Matrix transform) {
// Do nothing
}
+
+ @Override
+ public boolean isValid(String qrCode) {
+ return true;
+ }
}
private ScannerTestCallback mScannerCallback;
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java
index bf5fba8..b7f713d 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/ContextualWifiSliceTest.java
@@ -29,14 +29,12 @@
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
-import androidx.slice.SliceItem;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceProvider;
import androidx.slice.core.SliceAction;
import androidx.slice.widget.SliceLiveData;
import com.android.settings.R;
-import com.android.settings.testutils.SliceTester;
import org.junit.Before;
import org.junit.Test;
@@ -87,7 +85,9 @@
mWifiManager.connect(config, null /* listener */);
final Slice wifiSlice = mWifiSlice.getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).hasSize(1);
@@ -96,8 +96,5 @@
final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_settings_wireless);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString());
-
- final List<SliceItem> sliceItems = wifiSlice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.wifi_settings));
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
index 3c78749..ae352cc 100644
--- a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java
@@ -81,7 +81,9 @@
@Test
public void getWifiSlice_shouldHaveTitleAndToggle() {
final Slice wifiSlice = mWifiSlice.getSlice();
+
final SliceMetadata metadata = SliceMetadata.from(mContext, wifiSlice);
+ assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.wifi_settings));
final List<SliceAction> toggles = metadata.getToggles();
assertThat(toggles).hasSize(1);
@@ -90,9 +92,6 @@
final IconCompat expectedToggleIcon = IconCompat.createWithResource(mContext,
R.drawable.ic_settings_wireless);
assertThat(primaryAction.getIcon().toString()).isEqualTo(expectedToggleIcon.toString());
-
- final List<SliceItem> sliceItems = wifiSlice.getItems();
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.wifi_settings));
}
@Test
@@ -119,7 +118,8 @@
// All AP rows + title row
assertThat(rows).isEqualTo(DEFAULT_EXPANDED_ROW_COUNT + 1);
// Has scanning text
- SliceTester.assertTitle(sliceItems, mContext.getString(R.string.wifi_empty_list_wifi_on));
+ SliceTester.assertAnySliceItemContainsTitle(sliceItems,
+ mContext.getString(R.string.wifi_empty_list_wifi_on));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
index 40d651e..cdc74b3 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
@@ -35,6 +35,9 @@
import android.os.UserManager;
import android.widget.TextView;
+import androidx.fragment.app.FragmentActivity;
+import androidx.preference.PreferenceScreen;
+
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowWifiManager;
@@ -51,15 +54,13 @@
import java.util.ArrayList;
import java.util.List;
-import androidx.fragment.app.FragmentActivity;
-import androidx.preference.PreferenceScreen;
-
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowWifiManager.class})
public class WifiTetherSettingsTest {
private static final String[] WIFI_REGEXS = {"wifi_regexs"};
private Context mContext;
+ private WifiTetherSettings mWifiTetherSettings;
@Mock
private ConnectivityManager mConnectivityManager;
@@ -75,6 +76,8 @@
.when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE);
doReturn(WIFI_REGEXS).when(mConnectivityManager).getTetherableWifiRegexs();
doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
+
+ mWifiTetherSettings = new WifiTetherSettings();
}
@Test
@@ -136,6 +139,15 @@
verify(screen).removeAll();
}
+ @Test
+ public void createPreferenceControllers_hasAutoOffPreference() {
+ assertThat(mWifiTetherSettings.createPreferenceControllers(mContext)
+ .stream()
+ .filter(controller -> controller instanceof WifiTetherAutoOffPreferenceController)
+ .count())
+ .isEqualTo(1);
+ }
+
private void setupIsTetherAvailable(boolean returnValue) {
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
diff --git a/tests/unit/src/com/android/settings/EncryptionInterstitialTest.java b/tests/unit/src/com/android/settings/EncryptionInterstitialTest.java
index 9a6b754..3b4abfe 100644
--- a/tests/unit/src/com/android/settings/EncryptionInterstitialTest.java
+++ b/tests/unit/src/com/android/settings/EncryptionInterstitialTest.java
@@ -35,6 +35,9 @@
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.google.android.setupcompat.PartnerCustomizationLayout;
+import com.google.android.setupcompat.template.ButtonFooterMixin;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -63,10 +66,11 @@
@Test
public void clickYes_shouldRequirePassword() {
- mInstrumentation.startActivitySync(
+ final Activity activity = mInstrumentation.startActivitySync(
new Intent(mContext, EncryptionInterstitial.class)
.putExtra("extra_unlock_method_intent", new Intent("test.unlock.intent")));
- onView(withId(R.id.encrypt_require_password)).perform(click());
+ final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
+ layout.getMixin(ButtonFooterMixin.class).getPrimaryButtonView().performClick();
mActivityMonitor.waitForActivityWithTimeout(1000);
assertEquals(1, mActivityMonitor.getHits());
@@ -77,10 +81,11 @@
@Test
public void clickNo_shouldNotRequirePassword() {
- mInstrumentation.startActivitySync(
+ final Activity activity = mInstrumentation.startActivitySync(
new Intent(mContext, EncryptionInterstitial.class)
.putExtra("extra_unlock_method_intent", new Intent("test.unlock.intent")));
- onView(withId(R.id.encrypt_dont_require_password)).perform(click());
+ final PartnerCustomizationLayout layout = activity.findViewById(R.id.setup_wizard_layout);
+ layout.getMixin(ButtonFooterMixin.class).getSecondaryButtonView().performClick();
mActivityMonitor.waitForActivityWithTimeout(1000);
assertEquals(1, mActivityMonitor.getHits());
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
index 235f182..61033e9 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java
@@ -80,4 +80,20 @@
assertThat(activity instanceof WifiDppQrCodeGeneratorFragment
.OnQrCodeGeneratorFragmentAddButtonClickedListener).isEqualTo(true);
}
+
+ @Test
+ public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
+ WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
+
+ assertThat(activity instanceof WifiDppQrCodeScannerFragment
+ .OnScanWifiDppSuccessListener).isEqualTo(true);
+ }
+
+ @Test
+ public void testActivity_shouldImplementsOnScanZxingWifiFormatSuccessCallback() {
+ WifiDppConfiguratorActivity activity = mActivityRule.getActivity();
+
+ assertThat(activity instanceof WifiDppQrCodeScannerFragment
+ .OnScanZxingWifiFormatSuccessListener).isEqualTo(true);
+ }
}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java
new file mode 100644
index 0000000..283da13
--- /dev/null
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppEnrolleeActivityTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 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.settings.wifi.dpp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiDppEnrolleeActivityTest {
+ @Rule
+ public final ActivityTestRule<WifiDppEnrolleeActivity> mActivityRule =
+ new ActivityTestRule<>(WifiDppEnrolleeActivity.class);
+
+ @Test
+ public void testActivity_shouldImplementsOnScanWifiDppSuccessCallback() {
+ WifiDppEnrolleeActivity activity = mActivityRule.getActivity();
+
+ assertThat(activity instanceof WifiDppQrCodeScannerFragment
+ .OnScanWifiDppSuccessListener).isEqualTo(true);
+ }
+
+ @Test
+ public void testActivity_shouldImplementsOnScanZxingWifiFormatSuccessCallback() {
+ WifiDppEnrolleeActivity activity = mActivityRule.getActivity();
+
+ assertThat(activity instanceof WifiDppQrCodeScannerFragment
+ .OnScanZxingWifiFormatSuccessListener).isEqualTo(true);
+ }
+}
diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodetest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java
similarity index 83%
rename from tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodetest.java
rename to tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java
index 775ca48..3595597 100644
--- a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodetest.java
+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java
@@ -29,7 +29,7 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class WifiQrCodetest {
+public class WifiQrCodeTest {
// Valid Wi-Fi DPP QR code & it's parameters
private static final String VALID_WIFI_DPP_QR_CODE = "DPP:I:SN=4774LH2b4044;M:010203040506;K:"
+ "MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;";
@@ -57,6 +57,13 @@
private static final String SSID_OF_VALID_ZXING_WIFI_QR_CODE = "mynetwork";
private static final String PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE = "mypass";
+ // Valid ZXing reader library's Wi-Fi Network config format - escaped characters
+ private static final String VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS =
+ "WIFI:T:WPA;S:mynetwork;P:m\\;y\\:p\\\\a\\,ss;H:true;;";
+
+ private static final String PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS =
+ "m;y:p\\a,ss";
+
// Invalid scheme QR code
private static final String INVALID_SCHEME_QR_CODE = "BT:T:WPA;S:mynetwork;P:mypass;H:true;;";
@@ -118,19 +125,35 @@
assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
assertNotNull(config);
- assertNull(config.getSecurity());
+ assertEquals("", config.getSecurity());
assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
- assertNull(config.getPreSharedKey());
+ assertEquals("", config.getPreSharedKey());
assertEquals(false, config.getHiddenSsid());
}
@Test
+ public void parseValidZxingWifiQrCode_specialCharacters() {
+ WifiQrCode wifiQrCode = new WifiQrCode(VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS);
+ WifiNetworkConfig config = wifiQrCode.getWifiNetworkConfig();
+
+ assertEquals(WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG, wifiQrCode.getScheme());
+ assertNotNull(config);
+ assertEquals(SECURITY_OF_VALID_ZXING_WIFI_QR_CODE, config.getSecurity());
+ assertEquals(SSID_OF_VALID_ZXING_WIFI_QR_CODE, config.getSsid());
+ assertEquals(PASSWORD_OF_VALID_ZXING_WIFI_QR_CODE_SPECIAL_CHARACTERS,
+ config.getPreSharedKey());
+ assertEquals(true, config.getHiddenSsid());
+ }
+
+ @Test
public void testRemoveBackSlash() {
- assertEquals("\\", WifiQrCode.removeBackSlash("\\\\"));
- assertEquals("ab", WifiQrCode.removeBackSlash("a\\b"));
- assertEquals("a", WifiQrCode.removeBackSlash("\\a"));
- assertEquals("\\b", WifiQrCode.removeBackSlash("\\\\b"));
- assertEquals("c\\", WifiQrCode.removeBackSlash("c\\\\"));
+ WifiQrCode wifiQrCode = new WifiQrCode(VALID_WIFI_DPP_QR_CODE);
+
+ assertEquals("\\", wifiQrCode.removeBackSlash("\\\\"));
+ assertEquals("ab", wifiQrCode.removeBackSlash("a\\b"));
+ assertEquals("a", wifiQrCode.removeBackSlash("\\a"));
+ assertEquals("\\b", wifiQrCode.removeBackSlash("\\\\b"));
+ assertEquals("c\\", wifiQrCode.removeBackSlash("c\\\\"));
}
@Test