Merge "Use compact battery status string if available (1/3)"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fcd6cc0..290f84e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1951,7 +1951,6 @@
android:targetActivity=".accessibility.AccessibilitySettingsForSetupWizardActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <category android:name="com.android.settings.suggested.category.DISPLAY_SETTINGS" />
</intent-filter>
<meta-data android:name="com.android.settings.title"
android:resource="@string/vision_settings_suggestion_title" />
@@ -1961,6 +1960,29 @@
android:value="com.android.settings.accessibility.AccessibilitySettingsForSetupWizard" />
</activity-alias>
+ <activity-alias
+ android:name=".TextReadingForSetupWizardActivity"
+ android:exported="true"
+ android:icon="@drawable/ic_font_download"
+ android:targetActivity=".accessibility.AccessibilitySettingsForSetupWizardActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <!-- TODO(b/1352717): Consider replacing it with another category, temporarily
+ using an older one to avoid side problems. -->
+ <category android:name="com.android.settings.suggested.category.DISPLAY_SETTINGS" />
+ </intent-filter>
+
+ <meta-data
+ android:name="com.android.settings.title"
+ android:resource="@string/accessibility_text_reading_options_suggestion_title" />
+ <meta-data
+ android:name="com.android.settings.icon_tintable"
+ android:value="true" />
+ <meta-data
+ android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.accessibility.TextReadingPreferenceFragmentForSetupWizard" />
+ </activity-alias>
+
<activity
android:name=".accessibility.AccessibilityScreenSizeForSetupWizardActivity"
android:theme="@android:style/Theme.DeviceDefault.Settings"
@@ -2920,24 +2942,6 @@
android:value="true" />
</activity>
- <activity android:name=".dream.DreamSetupActivity"
- android:exported="true"
- android:immersive="true"
- android:theme="@style/SudThemeGlif.DayNight"
- android:icon="@drawable/ic_settings_display">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="com.android.settings.suggested.category.SCREEN_SAVER"/>
- </intent-filter>
- <meta-data android:name="com.android.settings.is_supported"
- android:resource="@bool/dream_setup_supported"/>
- <meta-data android:name="com.android.settings.title"
- android:resource="@string/dream_setup_title"/>
- <meta-data android:name="com.android.settings.summary"
- android:resource="@string/dream_setup_description"/>
- <meta-data android:name="com.android.settings.icon_tintable" android:value="true"/>
- </activity>
-
<activity
android:name="Settings$UserSettingsActivity"
android:label="@string/user_settings_title"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 16658f8..ba4d2f6 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -3736,7 +3736,7 @@
errorLine1=" android:color="@color/accessibility_feature_background"/>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
- file="res/drawable/ic_text_and_display.xml"
+ file="res/drawable/ic_color_and_motion.xml"
line="22"
column="13"/>
</issue>
diff --git a/res/color/dream_card_color_state_list.xml b/res/color/dream_card_color_state_list.xml
index b5de7b4..b0c86bb 100644
--- a/res/color/dream_card_color_state_list.xml
+++ b/res/color/dream_card_color_state_list.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:state_selected="true" android:color="?androidprv:attr/colorSurfaceVariant"/>
- <item android:color="?androidprv:attr/colorSurfaceHighlight"/>
+ <item android:state_selected="true" android:color="?androidprv:attr/colorAccentPrimary"/>
+ <item android:color="?androidprv:attr/colorSurface"/>
</selector>
\ No newline at end of file
diff --git a/res/color/dream_card_text_color_state_list.xml b/res/color/dream_card_text_color_state_list.xml
new file mode 100644
index 0000000..438855f
--- /dev/null
+++ b/res/color/dream_card_text_color_state_list.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <item android:state_selected="true" android:color="?androidprv:attr/textColorOnAccent"/>
+ <item android:color="?android:attr/textColorPrimary"/>
+</selector>
\ No newline at end of file
diff --git a/res/drawable/dream_default_preview_icon.xml b/res/drawable/dream_default_preview_icon.xml
new file mode 100644
index 0000000..7d247bb
--- /dev/null
+++ b/res/drawable/dream_default_preview_icon.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="?android:attr/textColorSecondary"
+ android:pathData="M3,19Q2.175,19 1.588,18.413Q1,17.825 1,17V7Q1,6.175 1.588,5.588Q2.175,5 3,5H13Q13.825,5 14.413,5.588Q15,6.175 15,7V17Q15,17.825 14.413,18.413Q13.825,19 13,19ZM3,17H13Q13,17 13,17Q13,17 13,17V7Q13,7 13,7Q13,7 13,7H3Q3,7 3,7Q3,7 3,7V17Q3,17 3,17Q3,17 3,17ZM17,19V5H19V19ZM21,19V5H23V19ZM4,15H12L9.4,11.5L7.5,14L6.1,12.15ZM3,7Q3,7 3,7Q3,7 3,7V17Q3,17 3,17Q3,17 3,17Q3,17 3,17Q3,17 3,17V7Q3,7 3,7Q3,7 3,7Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/dream_preview_icon.xml b/res/drawable/dream_preview_icon.xml
new file mode 100644
index 0000000..c4bd739
--- /dev/null
+++ b/res/drawable/dream_preview_icon.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M12,16Q13.875,16 15.188,14.688Q16.5,13.375 16.5,11.5Q16.5,9.625 15.188,8.312Q13.875,7 12,7Q10.125,7 8.812,8.312Q7.5,9.625 7.5,11.5Q7.5,13.375 8.812,14.688Q10.125,16 12,16ZM12,14.2Q10.875,14.2 10.088,13.412Q9.3,12.625 9.3,11.5Q9.3,10.375 10.088,9.587Q10.875,8.8 12,8.8Q13.125,8.8 13.913,9.587Q14.7,10.375 14.7,11.5Q14.7,12.625 13.913,13.412Q13.125,14.2 12,14.2ZM12,19Q8.35,19 5.35,16.962Q2.35,14.925 1,11.5Q2.35,8.075 5.35,6.037Q8.35,4 12,4Q15.65,4 18.65,6.037Q21.65,8.075 23,11.5Q21.65,14.925 18.65,16.962Q15.65,19 12,19ZM12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5Q12,11.5 12,11.5ZM12,17Q14.825,17 17.188,15.512Q19.55,14.025 20.8,11.5Q19.55,8.975 17.188,7.487Q14.825,6 12,6Q9.175,6 6.812,7.487Q4.45,8.975 3.2,11.5Q4.45,14.025 6.812,15.512Q9.175,17 12,17Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/dream_preview_rounded_bg.xml b/res/drawable/dream_preview_rounded_bg.xml
new file mode 100644
index 0000000..4da0c7c1
--- /dev/null
+++ b/res/drawable/dream_preview_rounded_bg.xml
@@ -0,0 +1,22 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle">
+ <solid android:color="?androidprv:attr/colorSurfaceHighlight" />
+ <corners android:radius="@dimen/dream_item_corner_radius"/>
+</shape>
\ No newline at end of file
diff --git a/res/drawable/ic_text_and_display.xml b/res/drawable/ic_color_and_motion.xml
similarity index 100%
rename from res/drawable/ic_text_and_display.xml
rename to res/drawable/ic_color_and_motion.xml
diff --git a/res/layout/accessibility_qs_tooltips.xml b/res/layout/accessibility_qs_tooltips.xml
index 85d9c52..2bc9f5f 100644
--- a/res/layout/accessibility_qs_tooltips.xml
+++ b/res/layout/accessibility_qs_tooltips.xml
@@ -23,10 +23,10 @@
android:background="@drawable/accessibility_qs_tooltips_background">
<ImageView
+ android:id="@+id/qs_illustration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/accessibility_qs_tooltips_margin_top"
- android:src="@drawable/accessibility_qs_tooltips_illustration"
android:layout_gravity="center_horizontal"
android:contentDescription="@null" />
diff --git a/res/layout/dream_picker_layout.xml b/res/layout/dream_picker_layout.xml
index 6530ea2..68e2051 100644
--- a/res/layout/dream_picker_layout.xml
+++ b/res/layout/dream_picker_layout.xml
@@ -15,43 +15,25 @@
limitations under the License.
-->
-<LinearLayout
+
+<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <androidx.cardview.widget.CardView
- android:id="@+id/dream_picker_container"
- android:layout_width="match_parent"
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/dream_list"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- style="@style/DreamPickerBackgroundStyle">
+ android:clipToPadding="true"
+ android:nestedScrollingEnabled="false"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingBottom="@dimen/dream_preference_card_padding"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"/>
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/dream_list"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:clipToPadding="true"
- android:nestedScrollingEnabled="false"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <Button
- android:id="@+id/preview_button"
- style="@style/ActionPrimaryButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:text="@string/dream_preview_button_title"
- app:layout_constraintTop_toBottomOf="@+id/dream_list"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- </androidx.cardview.widget.CardView>
-</LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/layout/dream_preference_layout.xml b/res/layout/dream_preference_layout.xml
index 2bc67ba..9528f4d 100644
--- a/res/layout/dream_preference_layout.xml
+++ b/res/layout/dream_preference_layout.xml
@@ -17,7 +17,6 @@
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
android:layout_width="match_parent"
@@ -30,21 +29,26 @@
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight">
- <androidx.cardview.widget.CardView
- android:id="@+id/preview_container"
- android:layout_width="match_parent"
+ <ImageView
+ android:id="@+id/preview"
+ android:layout_width="0dp"
android:layout_height="0dp"
- app:cardCornerRadius="@dimen/dream_item_corner_radius"
- app:cardElevation="0dp"
+ android:background="@drawable/dream_preview_rounded_bg"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent">
- <ImageView
- android:id="@+id/preview"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="centerCrop"/>
- </androidx.cardview.widget.CardView>
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <ImageView
+ android:id="@+id/preview_placeholder"
+ android:layout_width="@dimen/dream_preview_placeholder_width"
+ android:layout_height="0dp"
+ android:src="@drawable/dream_default_preview_icon"
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintTop_toTopOf="@+id/preview"
+ app:layout_constraintBottom_toBottomOf="@+id/preview"
+ app:layout_constraintStart_toStartOf="@+id/preview"
+ app:layout_constraintEnd_toEndOf="@+id/preview"/>
<Button
android:id="@+id/customize_button"
@@ -53,10 +57,10 @@
android:layout_height="wrap_content"
android:visibility="gone"
android:text="@string/customize_button_title"
- app:layout_constraintTop_toTopOf="@+id/preview_container"
- app:layout_constraintBottom_toBottomOf="@+id/preview_container"
- app:layout_constraintStart_toStartOf="@+id/preview_container"
- app:layout_constraintEnd_toEndOf="@+id/preview_container"/>
+ app:layout_constraintTop_toTopOf="@+id/preview"
+ app:layout_constraintBottom_toBottomOf="@+id/preview"
+ app:layout_constraintStart_toStartOf="@+id/preview"
+ app:layout_constraintEnd_toEndOf="@+id/preview"/>
<ImageView
android:id="@+id/icon"
@@ -68,7 +72,7 @@
android:gravity="center_vertical"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintHorizontal_chainStyle="packed"
- app:layout_constraintTop_toBottomOf="@+id/preview_container"
+ app:layout_constraintTop_toBottomOf="@+id/preview"
app_layout_constraintEnd_toStartOf="@+id/title_text"
app:layout_constraintStart_toStartOf="parent"/>
@@ -82,8 +86,9 @@
android:gravity="center_vertical"
android:maxLines="1"
android:ellipsize="end"
- android:textAppearance="?android:attr/textAppearanceListItemSmall"
- app:layout_constraintTop_toBottomOf="@+id/preview_container"
+ android:textSize="16sp"
+ android:textColor="@color/dream_card_text_color_state_list"
+ app:layout_constraintTop_toBottomOf="@+id/preview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/icon"/>
diff --git a/res/layout/dream_preview_button.xml b/res/layout/dream_preview_button.xml
new file mode 100644
index 0000000..b347863
--- /dev/null
+++ b/res/layout/dream_preview_button.xml
@@ -0,0 +1,33 @@
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+
+<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/dream_preview_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dream_preview_button_title"
+ android:textAllCaps="false"
+ android:textColor="?androidprv:attr/textColorOnAccent"
+ android:theme="@style/Theme.CollapsingToolbar.Settings"
+ android:layout_marginBottom="16dp"
+ android:layout_gravity="bottom|center"
+ app:backgroundTint="?androidprv:attr/colorAccentPrimaryVariant"
+ app:iconTint="?androidprv:attr/textColorOnAccent"
+ app:icon="@drawable/dream_preview_icon"/>
diff --git a/res/layout/dream_setup_layout.xml b/res/layout/dream_setup_layout.xml
deleted file mode 100644
index 31a0fb1..0000000
--- a/res/layout/dream_setup_layout.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<com.google.android.setupdesign.GlifLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/setup_wizard_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:icon="@drawable/ic_settings_display"
- app:sucHeaderText="@string/dream_setup_title"
- app:sudDescriptionText="@string/dream_setup_description">
-
- <RelativeLayout
- android:id="@+id/dream_container"
- style="@style/SudContentFrame"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/dream_setup_list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </RelativeLayout>
-
-</com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
diff --git a/res/layout/lockscreen_remote_input.xml b/res/layout/lockscreen_remote_input.xml
deleted file mode 100644
index 4fa44ce..0000000
--- a/res/layout/lockscreen_remote_input.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2016 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <CheckBox
- android:id="@+id/lockscreen_remote_input"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_marginStart="20dp"
- android:paddingStart="20dp"
- android:paddingEnd="?android:attr/dialogPreferredPadding"
- android:minHeight="?android:attr/listPreferredItemHeightSmall"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorAlertDialogListItem"
- android:gravity="center_vertical"
- android:text="@string/lockscreen_remote_input"
- />
-
- <ImageView
- android:id="@+id/restricted_lock_icon_remote_input"
- android:layout_width="@*android:dimen/config_restrictedIconSize"
- android:layout_height="@*android:dimen/config_restrictedIconSize"
- android:tint="?android:attr/colorAccent"
- android:src="@*android:drawable/ic_info"
- android:layout_marginEnd="?android:attr/dialogPreferredPadding"
- android:layout_gravity="center_vertical"
- android:scaleType="centerInside" />
-</LinearLayout>
diff --git a/res/layout/restricted_dialog_singlechoice.xml b/res/layout/restricted_dialog_singlechoice.xml
index a9984a8..9b19884 100644
--- a/res/layout/restricted_dialog_singlechoice.xml
+++ b/res/layout/restricted_dialog_singlechoice.xml
@@ -35,14 +35,4 @@
android:drawableStart="?android:attr/listChoiceIndicatorSingle"
android:drawablePadding="20dp"
android:ellipsize="marquee" />
- <ImageView
- android:id="@+id/restricted_lock_icon"
- android:layout_width="@*android:dimen/config_restrictedIconSize"
- android:layout_height="@*android:dimen/config_restrictedIconSize"
- android:tint="?android:attr/colorAccent"
- android:src="@*android:drawable/ic_info"
- android:layout_marginLeft="@dimen/restricted_icon_padding"
- android:baselineAlignBottom="true"
- android:scaleType="centerInside"
- android:visibility="gone" />
</com.android.settings.CheckableLinearLayout>
diff --git a/res/layout/restricted_preference_dropdown.xml b/res/layout/restricted_preference_dropdown.xml
deleted file mode 100644
index 8930e24..0000000
--- a/res/layout/restricted_preference_dropdown.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2016 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
- -->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <view android:id="@+id/spinner"
- class="com.android.settings.notification.RestrictedDropDownPreference$ReselectionSpinner"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:visibility="invisible"
- android:layout_marginStart="@dimen/preference_no_icon_padding_start"/>
-
- <include layout="@layout/settingslib_preference" />
-
-</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/restricted_radio_with_summary.xml b/res/layout/restricted_radio_with_summary.xml
deleted file mode 100644
index 5e7fcd8..0000000
--- a/res/layout/restricted_radio_with_summary.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.settings.CheckableLinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:background="?android:attr/selectableItemBackground"
- android:minHeight="?android:attr/listPreferredItemHeightSmall">
-
- <com.android.settings.CheckableLinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:paddingStart="20dp"
- android:paddingEnd="?android:attr/dialogPreferredPadding">
- <CheckedTextView
- android:id="@android:id/title"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="?android:attr/textColorAlertDialogListItem"
- android:gravity="center_vertical"
- android:drawableStart="?android:attr/listChoiceIndicatorSingle"
- android:ellipsize="marquee" />
- <ImageView
- android:id="@+id/restricted_icon"
- android:layout_width="@*android:dimen/config_restrictedIconSize"
- android:layout_height="match_parent"
- android:scaleType="centerInside"
- android:tint="?android:attr/colorAccent"
- android:src="@*android:drawable/ic_info"
- android:layout_marginLeft="@dimen/restricted_icon_padding"
- android:visibility="gone" />
- </com.android.settings.CheckableLinearLayout>
-
-
- <TextView android:id="@android:id/summary"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="8dp"
- android:paddingStart="52dp"
- android:textAppearance="?android:attr/textAppearanceListItemSecondary"
- android:textColor="?android:attr/textColorSecondary"
- android:maxLines="10" />
-
-</com.android.settings.CheckableLinearLayout>
diff --git a/res/layout/spinner_dropdown_restricted_item.xml b/res/layout/spinner_dropdown_restricted_item.xml
deleted file mode 100644
index d95e4be..0000000
--- a/res/layout/spinner_dropdown_restricted_item.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:gravity="center_vertical">
- <TextView android:id="@android:id/text1"
- style="?android:attr/spinnerDropDownItemStyle"
- android:singleLine="true"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="?android:attr/listPreferredItemHeightSmall"
- android:ellipsize="marquee" />
- <ImageView android:id="@+id/restricted_icon"
- android:layout_width="@*android:dimen/config_restrictedIconSize"
- android:layout_height="@*android:dimen/config_restrictedIconSize"
- android:tint="?android:attr/colorAccent"
- android:src="@*android:drawable/ic_info"
- android:baselineAlignBottom="true"
- android:layout_marginEnd="@dimen/restricted_icon_padding"
- android:gravity="end|center_vertical"
- android:visibility="gone" />
-</LinearLayout>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index a3e53f5..5ebaeed 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -816,20 +816,11 @@
<string-array name="captioning_font_size_selector_titles">
<item>Very small</item>
<item>Small</item>
- <item>Default</item>
+ <item>Medium</item>
<item>Large</item>
<item>Very large</item>
</string-array>
- <!-- Summary for Captions settings, explaining important settings under it. [CHAR LIMIT=NONE] -->
- <string-array name="captioning_font_size_selector_summaries">
- <item>Very small text size</item>
- <item>Small text size</item>
- <item>Default text size</item>
- <item>Large text size</item>
- <item>Very large text size</item>
- </string-array>
-
<!-- Values for captioning font size preference. -->
<string-array name="captioning_font_size_selector_values" translatable="false" >
<item>0.25</item>
diff --git a/res/values/config.xml b/res/values/config.xml
index 50eddb5..bf78fd7 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -570,7 +570,19 @@
<item>2</item>
<item>3</item>
</integer-array>
-
+
+ <!-- The settings/preference description for each settable device state defined in the array
+ "config_perDeviceStateRotationLockDefaults".
+ The item in position "i" describes the auto-rotation setting for the device state also in
+ position "i" in the array "config_perDeviceStateRotationLockDefaults". -->
+ <string-array name="config_settableAutoRotationDeviceStatesDescriptions">
+ <!-- Example:
+ <item>Auto-rotate when folded</item>
+ <item>@null</item> No description for state in position 1
+ <item>Auto-rotate when unfolded</item>
+ -->
+ </string-array>
+
<!-- Whether to aggregate for network selection list-->
<bool name="config_network_selection_list_aggregation_enabled">false</bool>
@@ -596,4 +608,5 @@
<!-- Whether the dream setup activity should be enabled as part of setupwizard -->
<bool name="dream_setup_supported">false</bool>
+
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index be1ba5b..78dbcce 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -441,7 +441,7 @@
<dimen name="chartview_trapezoid_margin_bottom">2dp</dimen>
<!-- Dimensions for Dream settings cards -->
- <dimen name="dream_item_min_column_width">210dp</dimen>
+ <dimen name="dream_item_min_column_width">174dp</dimen>
<dimen name="dream_item_corner_radius">28dp</dimen>
<dimen name="dream_item_content_padding">8dp</dimen>
<dimen name="dream_item_icon_size">20dp</dimen>
@@ -449,9 +449,10 @@
<dimen name="dream_item_title_margin_bottom">8dp</dimen>
<dimen name="dream_item_title_margin_start">18dp</dimen>
<dimen name="dream_item_icon_margin_start">10dp</dimen>
- <dimen name="dream_preference_margin_horizontal">10dp</dimen>
+ <dimen name="dream_preference_card_padding">16dp</dimen>
<dimen name="dream_preference_margin_bottom">20dp</dimen>
<dimen name="dream_picker_margin_horizontal">48dp</dimen>
+ <dimen name="dream_preview_placeholder_width">52dp</dimen>
<!-- Sims/Data mobile/Calls/SMS select dialog-->
<dimen name="sims_select_margin_bottom">24dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f071f5d..6f86803 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -491,6 +491,12 @@
<!-- Category for the app's locale picker activity. [CHAR LIMIT=50]-->
<string name="all_supported_app_locales_title">All languages</string>
+ <!-- Title for preference of the system default locale. [CHAR LIMIT=50]-->
+ <string name="preference_of_system_locale_title">System language</string>
+
+ <!-- Summary for preference of the system default locale. [CHAR LIMIT=50]-->
+ <string name="preference_of_system_locale_summary">System default - <xliff:g id="default_language" example="English (United States)">%1$s</xliff:g></string>
+
<!-- Description for the app without any supported languages. [CHAR LIMIT=NONE]-->
<string name="no_multiple_language_supported">The app is set to <xliff:g id="default_language" example="English (United States)">%1$s</xliff:g> by default and doesn\u2019t support multiple languages.</string>
<!-- The title of the confirmation dialog shown when the user selects one / several languages and tries to remove them [CHAR LIMIT=60] -->
@@ -597,7 +603,7 @@
<string name="date_and_time_settings_title_setup_wizard">Set date and time</string>
<!-- Main Settings screen setting option summary text for the item to go into the date and time settings. -->
<string name="date_and_time_settings_summary">Set date, time, time zone, & formats</string>
- <!-- Date & time setting screen setting switch title: whether the system clock (UTC time) should be determined automatically [CHAR LIMIT=100] -->
+ <!-- Date & time setting screen setting switch title: whether the system clock (Unix epoch time) should be determined automatically [CHAR LIMIT=100] -->
<string name="date_time_auto">Set time automatically</string>
<!-- Date & time setting screen setting switch title: whether the time zone should be determined automatically [CHAR LIMIT=100] -->
<string name="zone_auto_title">Set time zone automatically</string>
@@ -5150,8 +5156,8 @@
<string name="general_category_title">General</string>
<!-- Title for the accessibility preference category of display services and settings. [CHAR LIMIT=50] -->
<string name="display_category_title">Display</string>
- <!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
- <string name="accessibility_text_and_display_title">Text and display</string>
+ <!-- Title for the accessibility color and motion page. [CHAR LIMIT=50] -->
+ <string name="accessibility_color_and_motion_title">Color and motion</string>
<!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
<string name="accessibility_turn_screen_darker_title">Turn screen darker</string>
<!-- Title for the accessibility preference category of interaction control services and settings. [CHAR LIMIT=50] -->
@@ -5229,7 +5235,9 @@
<!-- Title for the footer text to explain what accessibility service does. [CHAR LIMIT=35] -->
<string name="accessibility_introduction_title">About <xliff:g id="service" example="Select to Speak">%1$s</xliff:g></string>
<!-- Title for the accessibility preference to adjust the display size, font size, bold text, and high contrast text features. [CHAR LIMIT=NONE] -->
- <string name="accessibility_text_reading_options_title">Text and reading options</string>
+ <string name="accessibility_text_reading_options_title">Display size and text</string>
+ <!-- Title for the entry of the text reading options. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_text_reading_options_suggestion_title">Change how text displays</string>
<!-- Subject for the mail content of the accessibility text reading preview. [CHAR LIMIT=NONE] -->
<string name="accessibility_text_reading_preview_mail_subject">Email: Plans for time machine, v2</string>
<!-- Message for the mail content of the accessibility text reading preview. [CHAR LIMIT=NONE] -->
@@ -5246,9 +5254,11 @@
<string name="accessibility_screen_magnification_short_summary">Tap 3 times to zoom</string>
<!-- Short summary for nav bar Magnification. Tells the user that this feature allows the user to magnify the screen using a button in the nav bar -->
<string name="accessibility_screen_magnification_navbar_short_summary">Tap a button to zoom</string>
+ <!-- Intro for the accessibility preference screen to enable screen magnification gestures. [CHAR LIMIT=none] -->
+ <string name="accessibility_screen_magnification_intro_text">Quickly zoom in on the screen to make content larger</string>
<!-- Summary for the accessibility preference screen to enable screen magnification gestures. [CHAR LIMIT=none] -->
<string name="accessibility_screen_magnification_summary">
- <![CDATA[Quickly zoom in on the screen to make content larger.<br/><br/>
+ <![CDATA[
<b>To zoom in:</b><br/>
{0,number,integer}. Use shortcut to start magnification<br/>
{1,number,integer}. Tap the screen<br/>
@@ -5256,10 +5266,11 @@
{3,number,integer}. Pinch with 2 fingers to adjust zoom<br/>
{4,number,integer}. Use shortcut to stop magnification<br/><br/>
<b>To zoom in temporarily:</b><br/>
- {0,number,integer}. Use shortcut to start magnification<br/>
- {1,number,integer}. Touch & hold anywhere on the screen<br/>
- {2,number,integer}. Drag finger to move around screen<br/>
- {3,number,integer}. Lift finger to stop magnification
+ {0,number,integer}. Make sure your magnification type is set to full screen<br/>
+ {1,number,integer}. Use shortcut to start magnification<br/>
+ {2,number,integer}. Touch & hold anywhere on the screen<br/>
+ {3,number,integer}. Drag finger to move around screen<br/>
+ {4,number,integer}. Lift finger to stop magnification
]]>
</string>
<!-- Summary for the accessibility preference screen to enable screen magnification via the nav bar. [CHAR LIMIT=none] -->
@@ -5350,6 +5361,8 @@
<string name="accessibility_button_title">Accessibility button</string>
<!-- Title for the accessibility button & gesture page. [CHAR LIMIT=35] -->
<string name="accessibility_button_gesture_title">Accessibility button & gesture</string>
+ <!-- Introduction for the accessibility button page. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_button_intro_text">Quickly access accessibility features from any screen</string>
<!-- Title for the accessibility button footer. [CHAR LIMIT=35] -->
<string name="accessibility_button_about_title">About accessibility button</string>
<!-- Title for the accessibility button & gesture footer. [CHAR LIMIT=55] -->
@@ -5361,9 +5374,9 @@
<!-- Summary text for the accessibility button preference. [CHAR LIMIT=50] -->
<string name="accessibility_button_summary">Quickly access accessibility features</string>
<!-- Description for the accessibility button in gesture navigation. Explain how this page works. [CHAR LIMIT=NONE] -->
- <string name="accessibility_button_gesture_description">Quickly access accessibility features from any screen.\n\nTo get started, go to accessibility settings and select a feature. Tap on the shortcut and select the accessibility button or gesture.</string>
+ <string name="accessibility_button_gesture_description"><b>How to use the button or gesture</b>\n\n1. Go to accessibility settings\n2. Select a feature and tap the shortcut\n3. To use the feature, tap the accessibility button or gesture</string>
<!-- Description for the accessibility button page. Explain how this page works. [CHAR LIMIT=NONE] -->
- <string name="accessibility_button_description">Quickly access accessibility features from any screen.\n\nTo get started, go to accessibility settings and select a feature. Tap on the shortcut and select the accessibility button.</string>
+ <string name="accessibility_button_description"><b>How to use the button</b>\n\n1. Go to accessibility settings\n2. Select a feature and tap the shortcut\n3. To use the feature, tap the accessibility button</string>
<!-- Title for the button or gesture of the accessibility button. [CHAR LIMIT=35] -->
<string name="accessibility_button_or_gesture_title">Use button or gesture</string>
<!-- Title for the location of the accessibility button. [CHAR LIMIT=35] -->
@@ -5382,6 +5395,8 @@
<string name="accessibility_button_high_label">Non-transparent</string>
<!-- Title for the accessibility preference to high contrast text. [CHAR LIMIT=35] -->
<string name="accessibility_toggle_high_text_contrast_preference_title">High contrast text</string>
+ <!-- Summary for the accessibility preference to high contrast text. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_toggle_high_text_contrast_preference_summary">Change text color to black or white. Maximizes contrast with the background.</string>
<!-- Title for the accessibility preference to auto update screen magnification. [CHAR LIMIT=35] -->
<string name="accessibility_toggle_screen_magnification_auto_update_preference_title">Auto
update screen magnification</string>
@@ -5424,7 +5439,9 @@
<!-- Title for accessibility preference to accessibility timeout. [CHAR LIMIT=35] -->
<string name="accessibility_control_timeout_preference_title">Time to take action</string>
<!-- Descriptive text for accessibility preference to accessibility control timeout. [CHAR LIMIT=NONE] -->
- <string name="accessibility_control_timeout_preference_summary">Choose how long to show messages that ask you to take action, but are visible only temporarily.\n\nNot all apps support this setting.</string>
+ <string name="accessibility_control_timeout_preference_summary">This timing preference isn\u2019t supported by all apps</string>
+ <!-- Intro text for accessibility preference to accessibility control timeout. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_control_timeout_preference_intro_text">Choose how long to show temporary messages that ask you to take action</string>
<!-- Title for accessibility preference to choose long-press delay i.e. timeout before it is detected. [CHAR LIMIT=35] -->
<string name="accessibility_long_press_timeout_preference_title">Touch & hold delay</string>
@@ -5434,14 +5451,15 @@
<string name="accessibility_display_inversion_switch_title">Use color inversion</string>
<!-- Title for accessibility shortcut preference for color inversion. [CHAR LIMIT=60] -->
<string name="accessibility_display_inversion_shortcut_title">Color inversion shortcut</string>
+ <!-- Intro for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_display_inversion_preference_intro_text">Color inversion turns light screens dark. It also turns dark screens light.</string>
<!-- Subtitle for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
<string name="accessibility_display_inversion_preference_subtitle">
- <![CDATA[Color inversion turns light screens dark.<br/><br/>
- Note:
+ <![CDATA[<b>Keep in mind</b><br/>
<ol>
- <li>\u00a0Color inversion also turns dark screens light.</li>
- <li>\u00a0Colors will change in media and images.</li>
- <li>\u00a0Dark theme can be used to display a dark background. Dark theme works with supported apps. Color inversion works on all apps.</li>
+ <li>\u00a0Colors will change in media and images</li>
+ <li>\u00a0Color inversion works on all apps</li>
+ <li>\u00a0To display a dark background, Dark theme can be used instead</li>
</ol>
]]>
</string>
@@ -5451,10 +5469,12 @@
<string name="accessibility_autoclick_about_title">About autoclick (dwell timing)</string>
<!-- Accessibility dwell timing footer link content description [CHAR LIMIT=NONE] -->
<string name="accessibility_autoclick_footer_learn_more_content_description">Learn more about autoclick (dwell timing)</string>
- <!-- Footer text to explain what autoclick does -->
- <string name="accessibility_autoclick_description">Autoclick works with a connected mouse. You can set the mouse cursor to click automatically when the cursor stops moving for a certain amount of time.</string>
+ <!-- Intro text to explain what autoclick does. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_autoclick_intro_text">You can set a connected mouse to click automatically when the cursor stops moving for a certain amount of time</string>
+ <!-- Footer text to explain what autoclick does. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_autoclick_description">Autoclick can be helpful if clicking the mouse is difficult</string>
<!-- Option heading to leave the auto click requirement for accessibility users at its default level. [CHAR LIMIT=50] -->
- <string name="accessibility_autoclick_default_title">Off</string>
+ <string name="accessibility_autoclick_default_title">Autoclick off</string>
<!-- Option heading to leave the auto click requirement for accessibility users at its short level. [CHAR LIMIT=35] -->
<string name="accessibility_autoclick_short_title">Short</string>
<!-- Option summary text for the auto click delay 0.2 seconds radio button. [CHAR LIMIT=35] -->
@@ -5503,10 +5523,16 @@
<string name="accessibility_service_primary_switch_title">Use <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g></string>
<!-- Used in the accessibility service settings to open the activity. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_primary_open_title">Open <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g></string>
+ <!-- Used in the accessibility service settings to show quick settings tooltips for auto-added feature. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_service_auto_added_qs_tooltips_content"><xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> added to Quick Settings. Swipe down to turn it on or off anytime.</string>
<!-- Used in the accessibility service settings to show quick settings tooltips. [CHAR LIMIT=NONE] -->
- <string name="accessibility_service_quick_settings_tooltips_content"><xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> added to Quick Settings. Swipe down to turn it on or off anytime.</string>
+ <string name="accessibility_service_qs_tooltips_content">You can add a shortcut to <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> by editing quick settings</string>
<!-- Used in the accessibility action for accessibility quick settings tooltips to dismiss. [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_tooltips_dismiss">Dismiss</string>
+ <!-- Intro for color correction settings screen to control turning on/off the feature entirely. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_daltonizer_about_intro_text" product="default">Adjust how colors display on your phone</string>
+ <!-- Intro for color correction settings screen to control turning on/off the feature entirely. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_daltonizer_about_intro_text" product="tablet">Adjust how colors display on your tablet</string>
<!-- Used in the Color correction settings screen to control turning on/off the feature entirely [CHAR LIMIT=60] -->
<string name="accessibility_daltonizer_primary_switch_title">Use color correction</string>
<!-- Title for accessibility shortcut preference for color correction. [CHAR LIMIT=60] -->
@@ -5529,8 +5555,10 @@
<string name="captioning_caption_appearance_summary"><xliff:g id="accessibility_font_size" example="Large">%1$s</xliff:g> text size</string>
<!-- Title for Caption preference settings screen for configuring language. [CHAR LIMIT=NONE] -->
<string name="captioning_more_options_title">More options</string>
- <!-- Used in the Captions preference to tell users that the setting doesn't support all apps. [CHAR LIMIT=NONE] -->
- <string name="accessibility_caption_preference_summary">Not all apps support these caption preferences</string>
+ <!-- Introduction for the captions preference page. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_caption_preference_intro">Customize caption size and style to make them easier to read</string>
+ <!-- Summary for the captions preference page. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_caption_preference_summary">These caption preferences aren\u2019t supported by all media apps</string>
<!-- Summary for accessibility shortcut preference for software shortcut type. [CHAR LIMIT=NONE] -->
<string name="accessibility_shortcut_type_software">Accessibility button</string>
<!-- Summary for accessibility shortcut preference for software shortcut type when gesture mode is on. [CHAR LIMIT=NONE] -->
@@ -5584,22 +5612,20 @@
<!-- Title for the preference to show a tile for a particular feature in the Quick Settings pane. [CHAR LIMIT=NONE] -->
<string name="enable_quick_setting">Show in Quick Settings</string>
- <!-- Title for the preference to configure the type of color space correction to apply. [CHAR LIMIT=NONE] -->
- <string name="daltonizer_type">Correction mode</string>
<!-- Title shown for deuteranomaly (red-green color blindness) [CHAR LIMIT=45] -->
- <string name="daltonizer_mode_deuteranomaly_title">Deuteranomaly</string>
+ <string name="daltonizer_mode_deuteranomaly_title">Red-green</string>
<!-- Title shown for protanomaly (red-green color blindness) [CHAR LIMIT=45] -->
- <string name="daltonizer_mode_protanomaly_title">Protanomaly</string>
+ <string name="daltonizer_mode_protanomaly_title">Red-green</string>
<!-- Title shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
- <string name="daltonizer_mode_tritanomaly_title">Tritanomaly</string>
+ <string name="daltonizer_mode_tritanomaly_title">Blue-yellow</string>
<!-- Title shown for grayscale [CHAR LIMIT=45] -->
<string name="daltonizer_mode_grayscale_title">Grayscale</string>
<!-- Summary shown for deuteranomaly (red-green color blindness) [CHAR LIMIT=45] -->
- <string name="daltonizer_mode_deuteranomaly_summary">Red-green</string>
+ <string name="daltonizer_mode_deuteranomaly_summary">Green weak, deuteranomaly</string>
<!-- Summary shown for protanomaly (red-green color blindness) [CHAR LIMIT=45] -->
- <string name="daltonizer_mode_protanomaly_summary">Red-green</string>
+ <string name="daltonizer_mode_protanomaly_summary">Red weak, protanomaly</string>
<!-- Summary shown for tritanomaly (blue-yellow color blindness) [CHAR LIMIT=45] -->
- <string name="daltonizer_mode_tritanomaly_summary">Blue-yellow</string>
+ <string name="daltonizer_mode_tritanomaly_summary">Tritanomaly</string>
<!-- Title for the accessibility preference of the Extra Dim/Reduce Brightness feature that dims your screen. [CHAR LIMIT=NONE] -->
<string name="reduce_bright_colors_preference_title">Extra dim</string>
@@ -5613,10 +5639,11 @@
<string name="reduce_bright_colors_preference_summary" product="default">Dim screen beyond your phone\u2019s minimum brightness</string>
<!-- Summary for the accessibility preference to configure Reduce Brightness feature. [CHAR LIMIT=NONE] -->
<string name="reduce_bright_colors_preference_summary" product="tablet">Dim screen beyond your tablet\u2019s minimum brightness</string>
+ <!-- Intro that describes Reduce Brightness. [CHAR LIMIT=NONE] -->
+ <string name="reduce_bright_colors_preference_intro_text">Make your screen dimmer so it\u2019s more comfortable to read</string>
<!-- Subtitle that describes Reduce Brightness. [CHAR LIMIT=NONE] -->
<string name="reduce_bright_colors_preference_subtitle" product="default">
- <![CDATA[Make your screen dimmer so it\u2019s more comfortable to read.<br/><br/>
- This can be helpful when:
+ <![CDATA[Extra dim can be helpful when:
<ol>
<li>\u00a0Your phone\u2019s default minimum brightness is still too bright</li>
<li>\u00a0You\u2019re using your phone in dark situations, like at night or in a dark room before bed</li>
@@ -5625,8 +5652,7 @@
</string>
<!-- Subtitle that describes Reduce Brightness. [CHAR LIMIT=NONE] -->
<string name="reduce_bright_colors_preference_subtitle" product="tablet">
- <![CDATA[Make your screen darker so it\u2019s more comfortable to read.<br/><br/>
- This can be helpful when:
+ <![CDATA[Extra dim can be helpful when:
<ol>
<li>\u00a0Your tablet\u2019s default minimum brightness is still too bright</li>
<li>\u00a0You\u2019re using your tablet in dark situations, like at night or in a dark room before bed</li>
@@ -7651,8 +7677,8 @@
<string name="nfc_default_payment_workapp_confirmation_message_title">To make a payment using a work app:</string>
<!-- Text string in the dialog [CHAR LIMIT=60] -->
<string name="nfc_default_payment_workapp_confirmation_message_1">work profile must be turned on.</string>
- <!-- Text string in the dialog [CHAR LIMIT=60] -->
- <string name="nfc_default_payment_workapp_confirmation_message_2">you\u2019ll need to enter your work profile lock if you have one.</string>
+ <!-- Text string in the dialog [CHAR LIMIT=80] -->
+ <string name="nfc_default_payment_workapp_confirmation_message_2">you\u2019ll need to enter your work PIN, pattern, or password if you have one.</string>
<!-- Caption for button linking to a page explaining how Tap and Pay works-->
<string name="nfc_payment_how_it_works">How it works</string>
@@ -13881,11 +13907,13 @@
<!-- TARE dialog button to proceed with a value change [CHAR LIMIT=none] -->
<string name="tare_dialog_confirm_button_title">Confirm</string>
<!-- Button to preview the selected screensaver in settings [CHAR LIMIT=40] -->
- <string name="dream_preview_button_title">Preview screensaver</string>
+ <string name="dream_preview_button_title">Preview screen saver</string>
<!-- The title of the category to show for the screensaver selector in settings [CHAR LIMIT=none] -->
- <string name="dream_picker_category">Choose an image</string>
- <!-- The title of the category to show for the screensaver overlay selector in settings [CHAR LIMIT=none] -->
- <string name="dream_complications_picker_category">Choose more options</string>
+ <string name="dream_picker_category">Choose a background</string>
+ <!-- The title of the toggle which enables/disables overlays on top of the screen saver [CHAR LIMIT=none] -->
+ <string name="dream_complications_toggle_title">Show additional information</string>
+ <!-- The summary of what overlays this toggle controls [CHAR LIMIT=none] -->
+ <string name="dream_complications_toggle_summary">Display data time, date and weather on the screen saver</string>
<!-- The title of the category to show for the screensaver miscellaneous settings [CHAR LIMIT=none] -->
<string name="dream_more_settings_category">More settings</string>
<!-- The title of the screen saver setup page [CHAR LIMIT=none] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a64eb1f..ebaea6b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -944,23 +944,10 @@
</style>
<style name="DreamCardStyle">
- <item name="android:layout_marginBottom">@dimen/dream_preference_margin_bottom</item>
- <item name="android:layout_marginStart">@dimen/dream_preference_margin_horizontal</item>
- <item name="android:layout_marginEnd">@dimen/dream_preference_margin_horizontal</item>
<item name="cardBackgroundColor">@color/dream_card_color_state_list</item>
<item name="cardCornerRadius">@dimen/dream_item_corner_radius</item>
<item name="cardElevation">0dp</item>
<item name="rippleColor">?android:attr/colorControlHighlight</item>
<item name="contentPadding">@dimen/dream_item_content_padding</item>
</style>
-
- <style name="DreamPickerBackgroundStyle">
- <item name="android:layout_marginBottom">48dp</item>
- <item name="android:layout_marginStart">@dimen/dream_picker_margin_horizontal</item>
- <item name="android:layout_marginEnd">@dimen/dream_picker_margin_horizontal</item>
- <item name="cardBackgroundColor">?androidprv:attr/colorSurface</item>
- <item name="cardCornerRadius">24dp</item>
- <item name="cardElevation">0dp</item>
- <item name="contentPadding">32dp</item>
- </style>
</resources>
diff --git a/res/xml/accessibility_autoclick_settings.xml b/res/xml/accessibility_autoclick_settings.xml
index 617f22a..943bc67 100644
--- a/res/xml/accessibility_autoclick_settings.xml
+++ b/res/xml/accessibility_autoclick_settings.xml
@@ -19,18 +19,21 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/accessibility_autoclick_preference_title">
+ <com.android.settingslib.widget.TopIntroPreference
+ android:key="accessibility_autoclick_intro"
+ android:persistent="false"
+ android:title="@string/accessibility_autoclick_intro_text" />
+
<com.android.settingslib.widget.IllustrationPreference
android:key="accessibility_autoclick_banner"
android:persistent="false"
android:selectable="false"
- settings:allowDividerBelow="true"
settings:searchable="false"
settings:lottie_rawRes="@drawable/accessibility_dwell" />
<com.android.settingslib.widget.SelectorWithWidgetPreference
android:key="accessibility_control_autoclick_default"
- android:title="@string/accessibility_autoclick_default_title"
- settings:allowDividerAbove="true" />
+ android:title="@string/accessibility_autoclick_default_title" />
<com.android.settingslib.widget.SelectorWithWidgetPreference
android:key="accessibility_control_autoclick_200ms"
@@ -56,7 +59,6 @@
android:layout="@layout/accessibility_autoclick_custom_seekbar"
android:selectable="false"
android:visibility="gone"
- settings:allowDividerBelow="true"
settings:controller="com.android.settings.accessibility.ToggleAutoclickCustomSeekbarController" />
<com.android.settings.accessibility.AccessibilityFooterPreference
diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml
index 86dd087..ab9fc41 100644
--- a/res/xml/accessibility_button_settings.xml
+++ b/res/xml/accessibility_button_settings.xml
@@ -14,61 +14,65 @@
limitations under the License.
-->
-<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto">
+ <com.android.settingslib.widget.TopIntroPreference
+ android:key="accessibility_button_intro"
+ android:persistent="false"
+ android:title="@string/accessibility_button_intro_text" />
+
<com.android.settingslib.widget.IllustrationPreference
android:key="accessibility_button_preview"
- android:selectable="false"
- settings:searchable="false"
android:persistent="false"
- settings:controller="com.android.settings.accessibility.AccessibilityButtonPreviewPreferenceController"/>
+ android:selectable="false"
+ settings:controller="com.android.settings.accessibility.AccessibilityButtonPreviewPreferenceController"
+ settings:searchable="false" />
<ListPreference
android:entries="@array/accessibility_button_location_selector_titles"
android:entryValues="@array/accessibility_button_location_selector_values"
android:key="accessibility_button_location"
- android:title="@string/accessibility_button_location_title"
- android:summary="%s"
android:persistent="false"
- settings:controller="com.android.settings.accessibility.AccessibilityButtonLocationPreferenceController"/>
+ android:summary="%s"
+ android:title="@string/accessibility_button_location_title"
+ settings:controller="com.android.settings.accessibility.AccessibilityButtonLocationPreferenceController" />
<ListPreference
android:entries="@array/accessibility_button_gesture_selector_titles"
android:entryValues="@array/accessibility_button_gesture_selector_values"
android:key="accessibility_button_or_gesture"
- android:title="@string/accessibility_button_or_gesture_title"
- android:summary="%s"
android:persistent="false"
- settings:controller="com.android.settings.accessibility.AccessibilityButtonGesturePreferenceController"/>
+ android:summary="%s"
+ android:title="@string/accessibility_button_or_gesture_title"
+ settings:controller="com.android.settings.accessibility.AccessibilityButtonGesturePreferenceController" />
<ListPreference
android:entries="@array/accessibility_button_size_selector_titles"
android:entryValues="@array/accessibility_button_size_selector_values"
android:key="accessibility_button_size"
- android:title="@string/accessibility_button_size_title"
- android:summary="%s"
android:persistent="false"
- settings:controller="com.android.settings.accessibility.FloatingMenuSizePreferenceController"/>
+ android:summary="%s"
+ android:title="@string/accessibility_button_size_title"
+ settings:controller="com.android.settings.accessibility.FloatingMenuSizePreferenceController" />
<SwitchPreference
android:key="accessibility_button_fade"
- android:title="@string/accessibility_button_fade_title"
- android:summary="@string/accessibility_button_fade_summary"
android:persistent="false"
- settings:controller="com.android.settings.accessibility.FloatingMenuFadePreferenceController"/>
+ android:summary="@string/accessibility_button_fade_summary"
+ android:title="@string/accessibility_button_fade_title"
+ settings:controller="com.android.settings.accessibility.FloatingMenuFadePreferenceController" />
<com.android.settings.widget.SeekBarPreference
android:key="accessibility_button_opacity"
- android:title="@string/accessibility_button_opacity_title"
android:persistent="false"
- settings:controller="com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController"/>
+ android:title="@string/accessibility_button_opacity_title"
+ settings:controller="com.android.settings.accessibility.FloatingMenuTransparencyPreferenceController" />
<com.android.settings.accessibility.AccessibilityFooterPreference
android:key="accessibility_button_footer"
android:persistent="false"
android:selectable="false"
- settings:searchable="false"
- settings:controller="com.android.settings.accessibility.AccessibilityButtonFooterPreferenceController"/>
+ settings:controller="com.android.settings.accessibility.AccessibilityButtonFooterPreferenceController"
+ settings:searchable="false" />
</PreferenceScreen>
diff --git a/res/xml/accessibility_text_and_display.xml b/res/xml/accessibility_color_and_motion.xml
similarity index 62%
rename from res/xml/accessibility_text_and_display.xml
rename to res/xml/accessibility_color_and_motion.xml
index 659acab..f251d1e 100644
--- a/res/xml/accessibility_text_and_display.xml
+++ b/res/xml/accessibility_color_and_motion.xml
@@ -17,34 +17,9 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:key="accessibility_text_and_display"
+ android:key="accessibility_color_and_motion"
android:persistent="false"
- android:title="@string/accessibility_text_and_display_title">
-
- <Preference
- android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
- android:icon="@drawable/ic_font_size"
- android:key="font_size_preference_screen"
- android:persistent="false"
- android:title="@string/title_font_size"
- settings:controller="com.android.settings.display.FontSizePreferenceController"
- settings:searchable="false"/>
-
- <com.android.settings.display.ScreenZoomPreference
- android:fragment="com.android.settings.display.ScreenZoomSettings"
- android:icon="@drawable/ic_screen_zoom"
- android:key="accessibility_settings_screen_zoom"
- android:persistent="false"
- android:title="@string/screen_zoom_title"
- settings:searchable="false"/>
-
- <SwitchPreference
- android:key="toggle_force_bold_text"
- android:icon="@drawable/ic_force_bold"
- android:persistent="false"
- android:title="@string/force_bold_text"
- settings:keywords="@string/keywords_bold_text"
- settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
+ android:title="@string/accessibility_color_and_motion_title">
<Preference
android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
@@ -76,12 +51,6 @@
android:title="@string/accessibility_toggle_large_pointer_icon_title"
settings:controller="com.android.settings.accessibility.LargePointerIconPreferenceController"/>
- <SwitchPreference
- android:key="toggle_high_text_contrast_preference"
- android:persistent="false"
- android:title="@string/accessibility_toggle_high_text_contrast_preference_title"
- settings:controller="com.android.settings.accessibility.HighTextContrastPreferenceController"/>
-
<PreferenceCategory
android:key="experimental_category"
android:persistent="false"
diff --git a/res/xml/accessibility_control_timeout_settings.xml b/res/xml/accessibility_control_timeout_settings.xml
index aaa2c06..3cd0dd6 100644
--- a/res/xml/accessibility_control_timeout_settings.xml
+++ b/res/xml/accessibility_control_timeout_settings.xml
@@ -21,6 +21,11 @@
android:title="@string/accessibility_control_timeout_preference_title"
android:persistent="false" >
+ <com.android.settingslib.widget.TopIntroPreference
+ android:key="accessibility_control_timeout_intro"
+ android:persistent="false"
+ android:title="@string/accessibility_control_timeout_preference_intro_text" />
+
<com.android.settingslib.widget.IllustrationPreference
android:key="accessibility_control_timeout_banner"
settings:lottie_rawRes="@raw/accessibility_timeout_banner"/>
@@ -28,7 +33,6 @@
<com.android.settingslib.widget.SelectorWithWidgetPreference
android:key="accessibility_control_timeout_default"
android:title="@string/accessibility_timeout_default"
- settings:allowDividerAbove="true"
android:persistent="false" />
<com.android.settingslib.widget.SelectorWithWidgetPreference
diff --git a/res/xml/accessibility_daltonizer_settings.xml b/res/xml/accessibility_daltonizer_settings.xml
index 1b69dc6..91b163b 100644
--- a/res/xml/accessibility_daltonizer_settings.xml
+++ b/res/xml/accessibility_daltonizer_settings.xml
@@ -28,32 +28,27 @@
settings:allowDividerBelow="true"
settings:searchable="false"/>
- <PreferenceCategory
- android:title="@string/daltonizer_type"
- android:key="daltonizer_mode_category" >
+ <com.android.settingslib.widget.SelectorWithWidgetPreference
+ android:key="daltonizer_mode_deuteranomaly"
+ android:persistent="false"
+ android:summary="@string/daltonizer_mode_deuteranomaly_summary"
+ android:title="@string/daltonizer_mode_deuteranomaly_title" />
- <com.android.settingslib.widget.SelectorWithWidgetPreference
- android:key="daltonizer_mode_deuteranomaly"
- android:persistent="false"
- android:summary="@string/daltonizer_mode_deuteranomaly_summary"
- android:title="@string/daltonizer_mode_deuteranomaly_title" />
+ <com.android.settingslib.widget.SelectorWithWidgetPreference
+ android:key="daltonizer_mode_protanomaly"
+ android:persistent="false"
+ android:summary="@string/daltonizer_mode_protanomaly_summary"
+ android:title="@string/daltonizer_mode_protanomaly_title" />
- <com.android.settingslib.widget.SelectorWithWidgetPreference
- android:key="daltonizer_mode_protanomaly"
- android:persistent="false"
- android:summary="@string/daltonizer_mode_protanomaly_summary"
- android:title="@string/daltonizer_mode_protanomaly_title" />
+ <com.android.settingslib.widget.SelectorWithWidgetPreference
+ android:key="daltonizer_mode_tritanomaly"
+ android:persistent="false"
+ android:summary="@string/daltonizer_mode_tritanomaly_summary"
+ android:title="@string/daltonizer_mode_tritanomaly_title" />
- <com.android.settingslib.widget.SelectorWithWidgetPreference
- android:key="daltonizer_mode_tritanomaly"
- android:persistent="false"
- android:summary="@string/daltonizer_mode_tritanomaly_summary"
- android:title="@string/daltonizer_mode_tritanomaly_title" />
- <com.android.settingslib.widget.SelectorWithWidgetPreference
- android:key="daltonizer_mode_grayscale"
- android:persistent="false"
- android:title="@string/daltonizer_mode_grayscale_title" />
-
- </PreferenceCategory>
+ <com.android.settingslib.widget.SelectorWithWidgetPreference
+ android:key="daltonizer_mode_grayscale"
+ android:persistent="false"
+ android:title="@string/daltonizer_mode_grayscale_title" />
</PreferenceScreen>
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index fcdf47b..22226a1 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -36,21 +36,19 @@
android:persistent="false"
android:title="@string/display_category_title">
- <!-- After completely finishing the Text and reading options feature, it will be visible. -->
<Preference
android:fragment="com.android.settings.accessibility.TextReadingPreferenceFragment"
android:icon="@drawable/ic_adaptive_font_download"
android:key="text_reading_options"
android:persistent="false"
- android:title="@string/accessibility_text_reading_options_title"
- settings:isPreferenceVisible="false"/>
+ android:title="@string/accessibility_text_reading_options_title" />
<Preference
- android:fragment="com.android.settings.accessibility.TextAndDisplayFragment"
- android:key="text_and_display_preference_screen"
- android:icon="@drawable/ic_text_and_display"
+ android:fragment="com.android.settings.accessibility.ColorAndMotionFragment"
+ android:key="color_and_motion"
+ android:icon="@drawable/ic_color_and_motion"
android:persistent="false"
- android:title="@string/accessibility_text_and_display_title"
+ android:title="@string/accessibility_color_and_motion_title"
settings:searchable="true"/>
<com.android.settingslib.PrimarySwitchPreference
diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml
index 3272ae5..78d8f72 100644
--- a/res/xml/accessibility_settings_for_setup_wizard.xml
+++ b/res/xml/accessibility_settings_for_setup_wizard.xml
@@ -26,24 +26,9 @@
android:key="text_reading_options"
android:persistent="false"
android:title="@string/accessibility_text_reading_options_title"
- settings:isPreferenceVisible="false"
settings:keywords="text_reading_options" />
<Preference
- android:key="font_size_preference"
- android:icon="@drawable/ic_font_size"
- android:summary="@string/short_summary_font_size"
- android:title="@string/title_font_size"
- settings:controller="com.android.settings.accessibility.FontSizePreferenceController" />
-
- <com.android.settings.display.ScreenZoomPreference
- android:key="force_density_preference"
- android:icon="@drawable/ic_screen_zoom"
- android:summary="@string/screen_zoom_short_summary"
- android:title="@string/screen_zoom_title"
- settings:controller="com.android.settings.accessibility.ScreenSizePreferenceController" />
-
- <Preference
android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragmentForSetupWizard"
android:key="screen_magnification_preference"
android:icon="@drawable/ic_accessibility_magnification"
diff --git a/res/xml/accessibility_system_controls.xml b/res/xml/accessibility_system_controls.xml
index 71e1143..37c4d67 100644
--- a/res/xml/accessibility_system_controls.xml
+++ b/res/xml/accessibility_system_controls.xml
@@ -42,9 +42,22 @@
android:title="@string/accessibility_power_button_ends_call_prerefence_title"
settings:controller="com.android.settings.accessibility.PowerButtonEndsCallPreferenceController"/>
+ <!-- Standard auto-rotation preference that will be shown when device state based auto-rotation
+ settings are NOT available. -->
<SwitchPreference
android:key="toggle_lock_screen_rotation_preference"
android:persistent="false"
android:title="@string/accelerometer_title"
settings:controller="com.android.settings.accessibility.LockScreenRotationPreferenceController"/>
+
+ <!-- Auto-rotation preference that will be shown when device state based auto-rotation settings
+ are available. -->
+ <Preference
+ android:key="device_state_auto_rotate_accessibility"
+ android:persistent="false"
+ android:title="@string/accelerometer_title"
+ android:fragment="com.android.settings.display.DeviceStateAutoRotateDetailsFragment"
+ settings:keywords="@string/keywords_auto_rotate"
+ settings:controller="com.android.settings.display.DeviceStateAutoRotateOverviewController"/>
+
</PreferenceScreen>
diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml
index 7d81565..ad742c9 100644
--- a/res/xml/accessibility_text_reading_options.xml
+++ b/res/xml/accessibility_text_reading_options.xml
@@ -33,7 +33,8 @@
settings:iconEnd="@drawable/ic_add_24dp"
settings:iconEndContentDescription="@string/font_size_make_larger_desc"
settings:iconStart="@drawable/ic_remove_24dp"
- settings:iconStartContentDescription="@string/font_size_make_smaller_desc"/>
+ settings:iconStartContentDescription="@string/font_size_make_smaller_desc"
+ settings:keywords="@string/keywords_font_size" />
<com.android.settings.widget.LabeledSeekBarPreference
android:key="display_size"
@@ -43,7 +44,8 @@
settings:iconEnd="@drawable/ic_add_24dp"
settings:iconEndContentDescription="@string/screen_zoom_make_larger_desc"
settings:iconStart="@drawable/ic_remove_24dp"
- settings:iconStartContentDescription="@string/screen_zoom_make_smaller_desc"/>
+ settings:iconStartContentDescription="@string/screen_zoom_make_smaller_desc"
+ settings:keywords="@string/keywords_display_size" />
<SwitchPreference
android:key="toggle_force_bold_text"
@@ -54,6 +56,7 @@
<SwitchPreference
android:key="toggle_high_text_contrast_preference"
android:persistent="false"
+ android:summary="@string/accessibility_toggle_high_text_contrast_preference_summary"
android:title="@string/accessibility_toggle_high_text_contrast_preference_title" />
<com.android.settingslib.widget.LayoutPreference
diff --git a/res/xml/app_locale_details.xml b/res/xml/app_locale_details.xml
index 8056cbf..40ca582 100644
--- a/res/xml/app_locale_details.xml
+++ b/res/xml/app_locale_details.xml
@@ -28,7 +28,14 @@
<PreferenceCategory
android:key="category_key_suggested_languages"
- android:title="@string/suggested_app_locales_title" />
+ android:title="@string/suggested_app_locales_title" >
+
+ <com.android.settingslib.widget.RadioButtonPreference
+ android:key="system_default_locale"
+ android:title="@string/preference_of_system_locale_title"
+ android:order="-10000"/>
+
+ </PreferenceCategory>
<PreferenceCategory
android:key="category_key_all_languages"
diff --git a/res/xml/captioning_settings.xml b/res/xml/captioning_settings.xml
index f5059e5..f9e9948 100644
--- a/res/xml/captioning_settings.xml
+++ b/res/xml/captioning_settings.xml
@@ -21,6 +21,11 @@
android:persistent="false"
android:title="@string/accessibility_captioning_title">
+ <com.android.settingslib.widget.TopIntroPreference
+ android:key="captions_intro"
+ android:persistent="false"
+ android:title="@string/accessibility_caption_preference_intro"/>
+
<com.android.settingslib.widget.IllustrationPreference
android:key="captions_preview"
android:persistent="false"
@@ -38,7 +43,8 @@
android:fragment="com.android.settings.accessibility.CaptionAppearanceFragment"
android:key="captioning_caption_appearance"
android:persistent="false"
- android:title="@string/captioning_caption_appearance_title" />
+ android:title="@string/captioning_caption_appearance_title"
+ settings:controller="com.android.settings.accessibility.CaptionAppearancePreferenceController" />
<Preference
android:fragment="com.android.settings.accessibility.CaptionMoreOptionsFragment"
diff --git a/res/xml/device_state_auto_rotate_settings.xml b/res/xml/device_state_auto_rotate_settings.xml
new file mode 100644
index 0000000..2ddb4c7
--- /dev/null
+++ b/res/xml/device_state_auto_rotate_settings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/accelerometer_title" >
+
+ <!-- Device state based auto-rotation preferences will be added programmatically here. -->
+
+</PreferenceScreen>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 328e15c..ba52a30 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -69,17 +69,10 @@
settings:keywords="@string/keywords_dark_ui_mode"/>
<Preference
- android:key="font_size"
- android:title="@string/title_font_size"
- android:fragment="com.android.settings.display.ToggleFontSizePreferenceFragment"
- settings:controller="com.android.settings.display.FontSizePreferenceController"
- settings:keywords="@string/keywords_font_size"/>
-
- <com.android.settings.display.ScreenZoomPreference
- android:key="display_settings_screen_zoom"
- android:title="@string/screen_zoom_title"
- android:fragment="com.android.settings.display.ScreenZoomSettings"
- settings:keywords="@string/keywords_display_size"/>
+ android:fragment="com.android.settings.accessibility.TextReadingPreferenceFragment"
+ android:key="text_reading_options"
+ android:persistent="false"
+ android:title="@string/accessibility_text_reading_options_title" />
</PreferenceCategory>
<PreferenceCategory
@@ -103,12 +96,27 @@
<PreferenceCategory
android:title="@string/category_name_display_controls">
+ <!--
+ Standard auto-rotation preference that will be shown when device state based
+ auto-rotation settings are NOT available.
+ -->
<SwitchPreference
android:key="auto_rotate"
android:title="@string/accelerometer_title"
settings:keywords="@string/keywords_auto_rotate"
settings:controller="com.android.settings.display.AutoRotatePreferenceController"/>
+ <!--
+ Auto-rotation preference that will be shown when device state based auto-rotation
+ settings are available.
+ -->
+ <Preference
+ android:key="device_state_auto_rotate"
+ android:title="@string/accelerometer_title"
+ android:fragment="com.android.settings.display.DeviceStateAutoRotateDetailsFragment"
+ settings:keywords="@string/keywords_auto_rotate"
+ settings:controller="com.android.settings.display.DeviceStateAutoRotateOverviewController"/>
+
<SwitchPreference
android:key="display_white_balance"
android:title="@string/display_white_balance_title"
diff --git a/res/xml/dream_fragment_overview.xml b/res/xml/dream_fragment_overview.xml
index 9dfa105..105cec4 100644
--- a/res/xml/dream_fragment_overview.xml
+++ b/res/xml/dream_fragment_overview.xml
@@ -29,18 +29,12 @@
</PreferenceCategory>
<PreferenceCategory
- android:key="dream_complication_category"
- android:title="@string/dream_complications_picker_category"
- settings:controller="com.android.settings.dream.DreamComplicationCategoryController">
- <com.android.settingslib.widget.LayoutPreference
- android:key="dream_complication_picker"
- android:selectable="false"
- android:layout="@layout/dream_picker_layout"
- settings:controller="com.android.settings.dream.DreamComplicationPickerController"/>
- </PreferenceCategory>
-
- <PreferenceCategory
android:title="@string/dream_more_settings_category">
+ <SwitchPreference
+ android:key="dream_complications_toggle"
+ android:title="@string/dream_complications_toggle_title"
+ android:summary="@string/dream_complications_toggle_summary"
+ settings:controller="com.android.settings.dream.DreamComplicationPreferenceController"/>
<Preference
android:key="when_to_start"
android:title="@string/screensaver_settings_when_to_dream"
diff --git a/res/xml/language_and_input.xml b/res/xml/language_and_input.xml
index c99d591..770a862 100644
--- a/res/xml/language_and_input.xml
+++ b/res/xml/language_and_input.xml
@@ -25,7 +25,6 @@
<Preference
android:key="phone_language"
android:title="@string/phone_language"
- android:icon="@drawable/ic_translate_24dp"
android:fragment="com.android.settings.localepicker.LocaleListEditor" />
<Preference
diff --git a/src/com/android/settings/RestrictedListPreference.java b/src/com/android/settings/RestrictedListPreference.java
index bd3cd17..d75f1b8 100644
--- a/src/com/android/settings/RestrictedListPreference.java
+++ b/src/com/android/settings/RestrictedListPreference.java
@@ -30,7 +30,6 @@
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
-import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
@@ -53,7 +52,6 @@
public RestrictedListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- setWidgetLayoutResource(R.layout.restricted_icon);
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
@@ -67,10 +65,6 @@
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
- final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
- if (restrictedIcon != null) {
- restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
- }
}
@Override
@@ -187,11 +181,9 @@
View root = super.getView(position, convertView, parent);
CharSequence entry = getItem(position);
CheckedTextView text = (CheckedTextView) root.findViewById(R.id.text1);
- ImageView padlock = (ImageView) root.findViewById(R.id.restricted_lock_icon);
if (isRestrictedForEntry(entry)) {
text.setEnabled(false);
text.setChecked(false);
- padlock.setVisibility(View.VISIBLE);
} else {
if (mSelectedIndex != -1) {
text.setChecked(position == mSelectedIndex);
@@ -199,7 +191,6 @@
if (!text.isEnabled()) {
text.setEnabled(true);
}
- padlock.setVisibility(View.GONE);
}
return root;
}
diff --git a/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java
index 55b8019..ca9c3d8 100644
--- a/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java
+++ b/src/com/android/settings/accessibility/AccessibilityButtonFooterPreferenceController.java
@@ -50,9 +50,10 @@
final int titleResource = AccessibilityUtil.isGestureNavigateEnabled(mContext)
? R.string.accessibility_button_gesture_description
: R.string.accessibility_button_description;
+ final CharSequence footerText = mContext.getText(titleResource);
final AccessibilityFooterPreference footerPreference =
screen.findPreference(getPreferenceKey());
- footerPreference.setTitle(titleResource);
+ footerPreference.setTitle(footerText);
super.displayPreference(screen);
}
}
diff --git a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
index 5fc4cd2..2cdbb33 100644
--- a/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityDetailsSettingsFragment.java
@@ -234,6 +234,9 @@
final String htmlDescription = info.loadHtmlDescription(getActivity().getPackageManager());
extras.putString(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, htmlDescription);
+ final CharSequence intro = info.loadIntro(getActivity().getPackageManager());
+ extras.putCharSequence(AccessibilitySettings.EXTRA_INTRO, intro);
+
// We will log nonA11yTool status from PolicyWarningUIController; others none.
extras.putLong(AccessibilitySettings.EXTRA_TIME_FOR_LOGGING,
getActivity().getIntent().getLongExtra(
diff --git a/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java b/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java
index f24934f..2c77102 100644
--- a/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java
+++ b/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java
@@ -27,10 +27,12 @@
import android.view.View.AccessibilityDelegate;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
+import androidx.annotation.DrawableRes;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
@@ -76,9 +78,10 @@
* Sets up {@link #AccessibilityQuickSettingsTooltipWindow}'s layout and content.
*
* @param text text to be displayed
+ * @param imageResId the resource ID of the image drawable
*/
- public void setup(String text) {
- this.setup(text, /* closeDelayTimeMillis= */ 0);
+ public void setup(String text, @DrawableRes int imageResId) {
+ this.setup(text, imageResId, /* closeDelayTimeMillis= */ 0);
}
/**
@@ -88,9 +91,10 @@
* close delay time is positive number. </p>
*
* @param text text to be displayed
+ * @param imageResId the resource ID of the image drawable
* @param closeDelayTimeMillis how long the popup window be auto-closed
*/
- public void setup(String text, long closeDelayTimeMillis) {
+ public void setup(String text, @DrawableRes int imageResId, long closeDelayTimeMillis) {
this.mCloseDelayTimeMillis = closeDelayTimeMillis;
setBackgroundDrawable(new ColorDrawable(mContext.getColor(android.R.color.transparent)));
@@ -101,6 +105,8 @@
popupView.setAccessibilityDelegate(mAccessibilityDelegate);
setContentView(popupView);
+ final ImageView imageView = getContentView().findViewById(R.id.qs_illustration);
+ imageView.setImageResource(imageResId);
final TextView textView = getContentView().findViewById(R.id.qs_content);
textView.setText(text);
setWidth(getWindowWidthWith(textView));
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index e834640..6539f32 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -94,6 +94,7 @@
static final String EXTRA_TITLE_RES = "title_res";
static final String EXTRA_RESOLVE_INFO = "resolve_info";
static final String EXTRA_SUMMARY = "summary";
+ static final String EXTRA_INTRO = "intro";
static final String EXTRA_SETTINGS_TITLE = "settings_title";
static final String EXTRA_COMPONENT_NAME = "component_name";
static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
@@ -570,14 +571,15 @@
final String prefKey = preference.getKey();
final int imageRes = info.getAnimatedImageRes();
+ final CharSequence intro = info.loadIntro(mPm);
final CharSequence description = getServiceDescription(mContext, info,
serviceEnabled);
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
final String tileServiceClassName = info.getTileServiceClassName();
- putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
- componentName);
+ putBasicExtras(preference, prefKey, title, intro, description, imageRes,
+ htmlDescription, componentName);
putServiceExtras(preference, resolveInfo, serviceEnabled);
putSettingsExtras(preference, packageName, settingsClassName);
putTileServiceExtras(preference, packageName, tileServiceClassName);
@@ -630,14 +632,15 @@
setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled);
final String prefKey = preference.getKey();
+ final CharSequence intro = info.loadIntro(mPm);
final String description = info.loadDescription(mPm);
final int imageRes = info.getAnimatedImageRes();
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
final String tileServiceClassName = info.getTileServiceClassName();
- putBasicExtras(preference, prefKey, title, description, imageRes, htmlDescription,
- componentName);
+ putBasicExtras(preference, prefKey, title, intro, description, imageRes,
+ htmlDescription, componentName);
putSettingsExtras(preference, componentName.getPackageName(), settingsClassName);
putTileServiceExtras(preference, componentName.getPackageName(),
tileServiceClassName);
@@ -722,11 +725,12 @@
/** Puts the basic extras into {@link RestrictedPreference}'s getExtras(). */
private void putBasicExtras(RestrictedPreference preference, String prefKey,
- CharSequence title, CharSequence summary, int imageRes, String htmlDescription,
- ComponentName componentName) {
+ CharSequence title, CharSequence intro, CharSequence summary, int imageRes,
+ String htmlDescription, ComponentName componentName) {
final Bundle extras = preference.getExtras();
extras.putString(EXTRA_PREFERENCE_KEY, prefKey);
extras.putCharSequence(EXTRA_TITLE, title);
+ extras.putCharSequence(EXTRA_INTRO, intro);
extras.putCharSequence(EXTRA_SUMMARY, summary);
extras.putParcelable(EXTRA_COMPONENT_NAME, componentName);
extras.putInt(EXTRA_ANIMATED_IMAGE_RES, imageRes);
diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
index 2b9729e..5798723 100644
--- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java
@@ -18,6 +18,7 @@
import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_GENERAL_CATEGORY;
+import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_SAVED_QS_TOOLTIP_TYPE;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
@@ -41,6 +42,7 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
+import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.utils.LocaleUtils;
@@ -70,6 +72,7 @@
private CheckBox mHardwareTypeCheckBox;
private AccessibilityQuickSettingsTooltipWindow mTooltipWindow;
private boolean mNeedsQSTooltipReshow = false;
+ private int mNeedsQSTooltipType = QuickSettingsTooltipType.GUIDE_TO_EDIT;
/** Returns the accessibility component name. */
protected abstract ComponentName getComponentName();
@@ -96,6 +99,9 @@
if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_RESHOW)) {
mNeedsQSTooltipReshow = savedInstanceState.getBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW);
}
+ if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_TYPE)) {
+ mNeedsQSTooltipType = savedInstanceState.getInt(KEY_SAVED_QS_TOOLTIP_TYPE);
+ }
}
final int resId = getPreferenceScreenResId();
@@ -176,6 +182,7 @@
}
if (mTooltipWindow != null) {
outState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, mTooltipWindow.isShowing());
+ outState.putInt(KEY_SAVED_QS_TOOLTIP_TYPE, mNeedsQSTooltipType);
}
super.onSaveInstanceState(outState);
}
@@ -198,7 +205,7 @@
case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
dialog = AccessibilityGestureNavigationTutorial
.createAccessibilityTutorialDialog(getPrefContext(),
- getUserShortcutTypes());
+ getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
dialog.setCanceledOnTouchOutside(false);
return dialog;
default:
@@ -297,6 +304,17 @@
};
/**
+ * This method will be invoked when a button in the tutorial dialog is clicked.
+ *
+ * @param dialog The dialog that received the click
+ * @param which The button that was clicked
+ */
+ private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ showQuickSettingsTooltipIfNeeded();
+ }
+
+ /**
* This method will be invoked when a button in the edit shortcut dialog is clicked.
*
* @param dialog The dialog that received the click
@@ -308,12 +326,17 @@
}
final int value = getShortcutTypeCheckBoxValue();
-
saveNonEmptyUserShortcutType(value);
AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), value, getComponentName());
AccessibilityUtil.optOutAllValuesFromSettings(getPrefContext(), ~value, getComponentName());
- mShortcutPreference.setChecked(value != AccessibilityUtil.UserShortcutType.EMPTY);
+ final boolean shortcutAssigned = value != AccessibilityUtil.UserShortcutType.EMPTY;
+ mShortcutPreference.setChecked(shortcutAssigned);
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
+
+ // Show the quick setting tooltip if the shortcut assigned in the first time
+ if (shortcutAssigned) {
+ showQuickSettingsTooltipIfNeeded();
+ }
}
@VisibleForTesting
@@ -452,7 +475,18 @@
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
}
- protected void showQuickSettingsTooltipIfNeeded() {
+ /**
+ * Shows the quick settings tooltip if the quick settings feature is assigned. The tooltip only
+ * shows once.
+ *
+ * @param type The quick settings tooltip type
+ */
+ protected void showQuickSettingsTooltipIfNeeded(@QuickSettingsTooltipType int type) {
+ mNeedsQSTooltipType = type;
+ showQuickSettingsTooltipIfNeeded();
+ }
+
+ private void showQuickSettingsTooltipIfNeeded() {
final ComponentName tileComponentName = getTileComponentName();
if (tileComponentName == null) {
// Returns if no tile service assigned.
@@ -471,10 +505,13 @@
return;
}
- final String title =
- getString(R.string.accessibility_service_quick_settings_tooltips_content, tileName);
+ final int titleResId = mNeedsQSTooltipType == QuickSettingsTooltipType.GUIDE_TO_EDIT
+ ? R.string.accessibility_service_qs_tooltips_content
+ : R.string.accessibility_service_auto_added_qs_tooltips_content;
+ final String title = getString(titleResId, tileName);
+ final int imageResId = R.drawable.accessibility_qs_tooltips_illustration;
mTooltipWindow = new AccessibilityQuickSettingsTooltipWindow(getContext());
- mTooltipWindow.setup(title);
+ mTooltipWindow.setup(title, imageResId);
mTooltipWindow.showAtTopCenter(getView());
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(getContext(),
tileComponentName);
diff --git a/src/com/android/settings/accessibility/AccessibilityUtil.java b/src/com/android/settings/accessibility/AccessibilityUtil.java
index c935956..3e97edc 100644
--- a/src/com/android/settings/accessibility/AccessibilityUtil.java
+++ b/src/com/android/settings/accessibility/AccessibilityUtil.java
@@ -46,7 +46,7 @@
import java.util.StringJoiner;
/** Provides utility methods to accessibility settings only. */
-final class AccessibilityUtil {
+public final class AccessibilityUtil {
private AccessibilityUtil(){}
@@ -105,6 +105,17 @@
int TRIPLETAP = 4; // 1 << 2
}
+ /**
+ * Denotes the quick setting tooltip type.
+ *
+ * {@code GUIDE_TO_EDIT} for QS tiles that need to be added by editing.
+ * {@code GUIDE_TO_DIRECT_USE} for QS tiles that have been auto-added already.
+ */
+ public @interface QuickSettingsTooltipType {
+ int GUIDE_TO_EDIT = 0;
+ int GUIDE_TO_DIRECT_USE = 1;
+ }
+
/** Denotes the accessibility enabled status */
@Retention(RetentionPolicy.SOURCE)
public @interface State {
diff --git a/src/com/android/settings/accessibility/CaptionAppearancePreferenceController.java b/src/com/android/settings/accessibility/CaptionAppearancePreferenceController.java
new file mode 100644
index 0000000..4bcdceb
--- /dev/null
+++ b/src/com/android/settings/accessibility/CaptionAppearancePreferenceController.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.Context;
+import android.view.accessibility.CaptioningManager;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+import com.google.common.primitives.Floats;
+import com.google.common.primitives.Ints;
+
+/** Controller that shows the caption scale and style summary. */
+public class CaptionAppearancePreferenceController extends BasePreferenceController {
+
+ private final CaptioningManager mCaptioningManager;
+
+ public CaptionAppearancePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ mCaptioningManager = context.getSystemService(CaptioningManager.class);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ return mContext.getString(R.string.preference_summary_default_combination,
+ geFontScaleSummary(), getPresetSummary());
+ }
+
+ private float[] getFontScaleValuesArray() {
+ final String[] fontScaleValuesStrArray = mContext.getResources().getStringArray(
+ R.array.captioning_font_size_selector_values);
+ final int length = fontScaleValuesStrArray.length;
+ final float[] fontScaleValuesArray = new float[length];
+ for (int i = 0; i < length; ++i) {
+ fontScaleValuesArray[i] = Float.parseFloat(fontScaleValuesStrArray[i]);
+ }
+ return fontScaleValuesArray;
+ }
+
+ private CharSequence geFontScaleSummary() {
+ final float[] fontScaleValuesArray = getFontScaleValuesArray();
+ final String[] fontScaleSummaries = mContext.getResources().getStringArray(
+ R.array.captioning_font_size_selector_titles);
+ final float fontScale = mCaptioningManager.getFontScale();
+ final int idx = Floats.indexOf(fontScaleValuesArray, fontScale);
+ return fontScaleSummaries[idx == /* not exist */ -1 ? 0 : idx];
+ }
+
+ private CharSequence getPresetSummary() {
+ final int[] presetValuesArray = mContext.getResources().getIntArray(
+ R.array.captioning_preset_selector_values);
+ final String[] presetSummaries = mContext.getResources().getStringArray(
+ R.array.captioning_preset_selector_titles);
+ final int preset = mCaptioningManager.getRawUserStyle();
+ final int idx = Ints.indexOf(presetValuesArray, preset);
+ return presetSummaries[idx];
+ }
+}
diff --git a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
index bcdba11..2d4bb11 100644
--- a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
+++ b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
@@ -34,8 +34,6 @@
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.OnMainSwitchChangeListener;
-import com.google.common.primitives.Floats;
-
import java.util.ArrayList;
import java.util.List;
@@ -56,7 +54,6 @@
private Preference mMoreOptions;
private final List<Preference> mPreferenceList = new ArrayList<>();
- private float[] mFontSizeValuesArray;
@Override
public int getMetricsCategory() {
@@ -71,13 +68,12 @@
initializeAllPreferences();
installUpdateListeners();
- initFontSizeValuesArray();
}
@Override
public void onResume() {
super.onResume();
- updateAllPreferences();
+ mSwitch.setChecked(mCaptioningManager.isEnabled());
}
@Override
@@ -105,21 +101,6 @@
}
- private void initFontSizeValuesArray() {
- final String[] fontSizeValuesStrArray = getPrefContext().getResources().getStringArray(
- R.array.captioning_font_size_selector_values);
- final int length = fontSizeValuesStrArray.length;
- mFontSizeValuesArray = new float[length];
- for (int i = 0; i < length; ++i) {
- mFontSizeValuesArray[i] = Float.parseFloat(fontSizeValuesStrArray[i]);
- }
- }
-
- private void updateAllPreferences() {
- mSwitch.setChecked(mCaptioningManager.isEnabled());
- mTextAppearance.setSummary(geTextAppearanceSummary(getPrefContext()));
- }
-
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
final ContentResolver cr = getActivity().getContentResolver();
@@ -136,16 +117,6 @@
return R.string.help_url_caption;
}
- private CharSequence geTextAppearanceSummary(Context context) {
- final String[] fontSizeSummaries = context.getResources().getStringArray(
- R.array.captioning_font_size_selector_summaries);
-
- final float fontSize = mCaptioningManager.getFontScale();
- final int idx = Floats.indexOf(mFontSizeValuesArray, fontSize);
-
- return fontSizeSummaries[idx == /* not exist */ -1 ? 0 : idx];
- }
-
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.captioning_settings);
diff --git a/src/com/android/settings/accessibility/TextAndDisplayFragment.java b/src/com/android/settings/accessibility/ColorAndMotionFragment.java
similarity index 91%
rename from src/com/android/settings/accessibility/TextAndDisplayFragment.java
rename to src/com/android/settings/accessibility/ColorAndMotionFragment.java
index e81dded..7f55053 100644
--- a/src/com/android/settings/accessibility/TextAndDisplayFragment.java
+++ b/src/com/android/settings/accessibility/ColorAndMotionFragment.java
@@ -30,11 +30,11 @@
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
-/** Accessibility settings for text and display. */
+/** Accessibility settings for color and motion. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
-public class TextAndDisplayFragment extends DashboardFragment {
+public class ColorAndMotionFragment extends DashboardFragment {
- private static final String TAG = "TextAndDisplayFragment";
+ private static final String TAG = "ColorAndMotionFragment";
private static final String CATEGORY_EXPERIMENTAL = "experimental_category";
@@ -49,7 +49,7 @@
@Override
public int getMetricsCategory() {
- return SettingsEnums.ACCESSIBILITY_TEXT_AND_DISPLAY;
+ return SettingsEnums.ACCESSIBILITY_COLOR_AND_MOTION;
}
@@ -62,7 +62,7 @@
@Override
protected int getPreferenceScreenResId() {
- return R.xml.accessibility_text_and_display;
+ return R.xml.accessibility_color_and_motion;
}
@Override
@@ -104,5 +104,5 @@
}
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.accessibility_text_and_display);
+ new BaseSearchIndexProvider(R.xml.accessibility_color_and_motion);
}
diff --git a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
index ce8db21..b04582f 100644
--- a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java
@@ -20,11 +20,9 @@
import android.accessibilityservice.AccessibilityShortcutInfo;
import android.app.ActivityOptions;
-import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
@@ -139,20 +137,6 @@
}
@Override
- public Dialog onCreateDialog(int dialogId) {
- switch (dialogId) {
- case AccessibilityDialogUtils.DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
- final Dialog dialog = AccessibilityGestureNavigationTutorial
- .createAccessibilityTutorialDialog(getPrefContext(),
- getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
- dialog.setCanceledOnTouchOutside(false);
- return dialog;
- default:
- return super.onCreateDialog(dialogId);
- }
- }
-
- @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Do not call super. We don't want to see the "Help & feedback" option on this page so as
// not to confuse users who think they might be able to send feedback about a specific
@@ -236,22 +220,4 @@
return settingsIntent;
}
-
- /**
- * This method will be invoked when a button in the tutorial dialog is clicked.
- *
- * @param dialog The dialog that received the click
- * @param which The button that was clicked
- */
- private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
- dialog.dismiss();
- showQuickSettingsTooltipIfNeeded();
- }
-
-
- @Override
- protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
- super.callOnAlertDialogCheckboxClicked(dialog, which);
- showQuickSettingsTooltipIfNeeded(getShortcutTypeCheckBoxValue());
- }
}
diff --git a/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java b/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java
index 5ed4b5c..a1c292a 100644
--- a/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java
+++ b/src/com/android/settings/accessibility/LockScreenRotationPreferenceController.java
@@ -25,6 +25,7 @@
import com.android.internal.view.RotationPolicy.RotationPolicyListener;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.display.DeviceStateAutoRotationHelper;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -59,7 +60,9 @@
@Override
public int getAvailabilityStatus() {
- return RotationPolicy.isRotationSupported(mContext) ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ return RotationPolicy.isRotationSupported(mContext)
+ && !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabledForA11y(mContext)
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
@Override
diff --git a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
index 37d09a7..01ee249 100644
--- a/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationGesturesPreferenceController.java
@@ -100,7 +100,10 @@
extras.putInt(AccessibilitySettings.EXTRA_TITLE_RES,
R.string.accessibility_screen_magnification_gestures_title);
- String summary = context.getString(R.string.accessibility_screen_magnification_summary);
+ String intro = context.getString(R.string.accessibility_screen_magnification_intro_text);
+ extras.putCharSequence(AccessibilitySettings.EXTRA_INTRO, intro);
+
+ String summary = context.getString(R.string.accessibility_screen_magnification_summary);
final Object[] numberArguments = {1, 2, 3, 4, 5};
summary = MessageFormat.format(summary, numberArguments);
extras.putCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, summary);
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index d7a506a..02da51e 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -206,12 +206,6 @@
.createDisableDialog(getPrefContext(), info,
this::onDialogButtonFromDisableToggleClicked);
return mWarningDialog;
- case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
- final Dialog dialog = AccessibilityGestureNavigationTutorial
- .createAccessibilityTutorialDialog(getPrefContext(),
- getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
- dialog.setCanceledOnTouchOutside(false);
- return dialog;
default:
return super.onCreateDialog(dialogId);
}
@@ -496,23 +490,6 @@
mWarningDialog.dismiss();
}
- /**
- * This method will be invoked when a button in the tutorial dialog is clicked.
- *
- * @param dialog The dialog that received the click
- * @param which The button that was clicked
- */
- private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
- dialog.dismiss();
- showQuickSettingsTooltipIfNeeded();
- }
-
- @Override
- protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
- super.callOnAlertDialogCheckboxClicked(dialog, which);
- showQuickSettingsTooltipIfNeeded(getShortcutTypeCheckBoxValue());
- }
-
void onDialogButtonFromShortcutClicked(View view) {
final int viewId = view.getId();
if (viewId == R.id.permission_enable_allow_button) {
diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
index 679e284..1f498d6 100644
--- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java
@@ -33,6 +33,7 @@
import android.view.ViewGroup;
import com.android.settings.R;
+import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.widget.SettingsMainSwitchPreference;
import java.util.ArrayList;
@@ -50,7 +51,9 @@
@Override
protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
- super.onPreferenceToggled(preferenceKey, enabled);
+ if (enabled) {
+ showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
+ }
logAccessibilityServiceEnabled(mComponentName, enabled);
Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? ON : OFF);
}
@@ -82,6 +85,7 @@
mComponentName = COLOR_INVERSION_COMPONENT_NAME;
mPackageName = getText(R.string.accessibility_display_inversion_preference_title);
mHtmlDescription = getText(R.string.accessibility_display_inversion_preference_subtitle);
+ mTopIntroTitle = getText(R.string.accessibility_display_inversion_preference_intro_text);
mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(getPrefContext().getPackageName())
.appendPath(String.valueOf(R.raw.accessibility_color_inversion_banner))
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index 5d9cbe5..c4df5bf 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -35,6 +35,7 @@
import androidx.preference.Preference;
import com.android.settings.R;
+import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SettingsMainSwitchPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -51,7 +52,10 @@
private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
private static final String KEY_PREVIEW = "daltonizer_preview";
- private static final String KEY_CATEGORY_MODE = "daltonizer_mode_category";
+ private static final String KEY_DEUTERANOMALY = "daltonizer_mode_deuteranomaly";
+ private static final String KEY_PROTANOMALY = "daltonizer_mode_protanomaly";
+ private static final String KEY_TRITANOMEALY = "daltonizer_mode_tritanomaly";
+ private static final String KEY_GRAYSCALE = "daltonizer_mode_grayscale";
private static final List<AbstractPreferenceController> sControllers = new ArrayList<>();
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
@@ -82,6 +86,7 @@
mComponentName = DALTONIZER_COMPONENT_NAME;
mPackageName = getText(R.string.accessibility_display_daltonizer_preference_title);
mHtmlDescription = getText(R.string.accessibility_display_daltonizer_preference_subtitle);
+ mTopIntroTitle = getText(R.string.accessibility_daltonizer_about_intro_text);
final View view = super.onCreateView(inflater, container, savedInstanceState);
updateFooterPreference();
return view;
@@ -111,9 +116,13 @@
/** Customizes the order by preference key. */
protected List<String> getPreferenceOrderList() {
final List<String> lists = new ArrayList<>();
+ lists.add(KEY_TOP_INTRO_PREFERENCE);
lists.add(KEY_PREVIEW);
lists.add(KEY_USE_SERVICE_PREFERENCE);
- lists.add(KEY_CATEGORY_MODE);
+ lists.add(KEY_DEUTERANOMALY);
+ lists.add(KEY_PROTANOMALY);
+ lists.add(KEY_TRITANOMEALY);
+ lists.add(KEY_GRAYSCALE);
lists.add(KEY_GENERAL_CATEGORY);
lists.add(KEY_HTML_DESCRIPTION_PREFERENCE);
return lists;
@@ -157,7 +166,9 @@
@Override
protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
- super.onPreferenceToggled(preferenceKey, enabled);
+ if (enabled) {
+ showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
+ }
logAccessibilityServiceEnabled(mComponentName, enabled);
Settings.Secure.putInt(getContentResolver(), ENABLED, enabled ? ON : OFF);
}
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 08e9b88..5992ceb 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -56,6 +56,7 @@
import com.android.settings.SettingsActivity;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
+import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import com.android.settings.utils.LocaleUtils;
import com.android.settings.widget.SettingsMainSwitchBar;
@@ -63,6 +64,7 @@
import com.android.settingslib.accessibility.AccessibilityUtils;
import com.android.settingslib.widget.IllustrationPreference;
import com.android.settingslib.widget.OnMainSwitchChangeListener;
+import com.android.settingslib.widget.TopIntroPreference;
import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -92,14 +94,17 @@
protected Uri mImageUri;
private CharSequence mDescription;
protected CharSequence mHtmlDescription;
+ protected CharSequence mTopIntroTitle;
private static final String DRAWABLE_FOLDER = "drawable";
+ protected static final String KEY_TOP_INTRO_PREFERENCE = "top_intro";
protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service";
public static final String KEY_GENERAL_CATEGORY = "general_categories";
protected static final String KEY_HTML_DESCRIPTION_PREFERENCE = "html_description";
private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
protected static final String KEY_SAVED_USER_SHORTCUT_TYPE = "shortcut_type";
protected static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow";
+ protected static final String KEY_SAVED_QS_TOOLTIP_TYPE = "qs_tooltip_type";
protected static final String KEY_ANIMATED_IMAGE = "animated_image";
private TouchExplorationStateChangeListener mTouchExplorationStateChangeListener;
@@ -110,6 +115,7 @@
private AccessibilityQuickSettingsTooltipWindow mTooltipWindow;
private boolean mNeedsQSTooltipReshow = false;
+ private int mNeedsQSTooltipType = QuickSettingsTooltipType.GUIDE_TO_EDIT;
public static final int NOT_SET = -1;
// Save user's shortcutType value when savedInstance has value (e.g. device rotated).
@@ -145,6 +151,9 @@
if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_RESHOW)) {
mNeedsQSTooltipReshow = savedInstanceState.getBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW);
}
+ if (savedInstanceState.containsKey(KEY_SAVED_QS_TOOLTIP_TYPE)) {
+ mNeedsQSTooltipType = savedInstanceState.getInt(KEY_SAVED_QS_TOOLTIP_TYPE);
+ }
}
setupDefaultShortcutIfNecessary(getPrefContext());
@@ -182,6 +191,7 @@
// Need to be called as early as possible. Protected variables will be assigned here.
onProcessArguments(getArguments());
+ initTopIntroPreference();
initAnimatedImagePreference();
initToggleServiceSwitchPreference();
initGeneralCategory();
@@ -250,6 +260,7 @@
}
if (mTooltipWindow != null) {
outState.putBoolean(KEY_SAVED_QS_TOOLTIP_RESHOW, mTooltipWindow.isShowing());
+ outState.putInt(KEY_SAVED_QS_TOOLTIP_TYPE, mNeedsQSTooltipType);
}
super.onSaveInstanceState(outState);
}
@@ -270,7 +281,7 @@
case DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL:
mDialog = AccessibilityGestureNavigationTutorial
.createAccessibilityTutorialDialog(getPrefContext(),
- getUserShortcutTypes());
+ getUserShortcutTypes(), this::callOnTutorialDialogButtonClicked);
mDialog.setCanceledOnTouchOutside(false);
return mDialog;
default:
@@ -388,11 +399,17 @@
mHtmlDescription = arguments.getCharSequence(
AccessibilitySettings.EXTRA_HTML_DESCRIPTION);
}
+
+ // Intro.
+ if (arguments.containsKey(AccessibilitySettings.EXTRA_INTRO)) {
+ mTopIntroTitle = arguments.getCharSequence(AccessibilitySettings.EXTRA_INTRO);
+ }
}
/** Customizes the order by preference key. */
protected List<String> getPreferenceOrderList() {
final List<String> lists = new ArrayList<>();
+ lists.add(KEY_TOP_INTRO_PREFERENCE);
lists.add(KEY_ANIMATED_IMAGE);
lists.add(KEY_USE_SERVICE_PREFERENCE);
lists.add(KEY_GENERAL_CATEGORY);
@@ -461,6 +478,17 @@
getPreferenceScreen().addPreference(illustrationPreference);
}
+ @VisibleForTesting
+ void initTopIntroPreference() {
+ if (TextUtils.isEmpty(mTopIntroTitle)) {
+ return;
+ }
+ final TopIntroPreference topIntroPreference = new TopIntroPreference(getPrefContext());
+ topIntroPreference.setKey(KEY_TOP_INTRO_PREFERENCE);
+ topIntroPreference.setTitle(mTopIntroTitle);
+ getPreferenceScreen().addPreference(topIntroPreference);
+ }
+
private void initToggleServiceSwitchPreference() {
mToggleServiceSwitchPreference = new SettingsMainSwitchPreference(getPrefContext());
mToggleServiceSwitchPreference.setKey(KEY_USE_SERVICE_PREFERENCE);
@@ -674,6 +702,17 @@
}
/**
+ * This method will be invoked when a button in the tutorial dialog is clicked.
+ *
+ * @param dialog The dialog that received the click
+ * @param which The button that was clicked
+ */
+ private void callOnTutorialDialogButtonClicked(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ showQuickSettingsTooltipIfNeeded();
+ }
+
+ /**
* This method will be invoked when a button in the edit shortcut dialog is clicked.
*
* @param dialog The dialog that received the click
@@ -685,12 +724,17 @@
}
final int value = getShortcutTypeCheckBoxValue();
-
saveNonEmptyUserShortcutType(value);
AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), value, mComponentName);
AccessibilityUtil.optOutAllValuesFromSettings(getPrefContext(), ~value, mComponentName);
- mShortcutPreference.setChecked(value != UserShortcutType.EMPTY);
+ final boolean shortcutAssigned = value != UserShortcutType.EMPTY;
+ mShortcutPreference.setChecked(shortcutAssigned);
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
+
+ // Show the quick setting tooltip if the shortcut assigned in the first time
+ if (shortcutAssigned) {
+ showQuickSettingsTooltipIfNeeded();
+ }
}
protected void updateShortcutPreferenceData() {
@@ -802,23 +846,17 @@
}
/**
- * Shows the quick settings tooltip if the quick settings service and the shortcut are assigned.
- * The tooltip only shows once.
+ * Shows the quick settings tooltip if the quick settings feature is assigned. The tooltip only
+ * shows once.
*
- * @param shortcutType The shortcut type.
+ * @param type The quick settings tooltip type
*/
- protected void showQuickSettingsTooltipIfNeeded(@UserShortcutType int shortcutType) {
- if (shortcutType == AccessibilityUtil.UserShortcutType.EMPTY) {
- return;
- }
+ protected void showQuickSettingsTooltipIfNeeded(@QuickSettingsTooltipType int type) {
+ mNeedsQSTooltipType = type;
showQuickSettingsTooltipIfNeeded();
}
- /**
- * Shows the quick settings tooltip if the quick settings service is assigned. The tooltip only
- * shows once.
- */
- protected void showQuickSettingsTooltipIfNeeded() {
+ private void showQuickSettingsTooltipIfNeeded() {
final ComponentName tileComponentName = getTileComponentName();
if (tileComponentName == null) {
// Returns if no tile service assigned.
@@ -837,10 +875,13 @@
return;
}
- final String title =
- getString(R.string.accessibility_service_quick_settings_tooltips_content, tileName);
+ final int titleResId = mNeedsQSTooltipType == QuickSettingsTooltipType.GUIDE_TO_EDIT
+ ? R.string.accessibility_service_qs_tooltips_content
+ : R.string.accessibility_service_auto_added_qs_tooltips_content;
+ final String title = getString(titleResId, tileName);
+ final int imageResId = R.drawable.accessibility_qs_tooltips_illustration;
mTooltipWindow = new AccessibilityQuickSettingsTooltipWindow(getContext());
- mTooltipWindow.setup(title);
+ mTooltipWindow.setup(title, imageResId);
mTooltipWindow.showAtTopCenter(getView());
AccessibilityQuickSettingUtils.optInValueToSharedPreferences(getContext(),
tileComponentName);
diff --git a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
index 973e27c..fb9c4a8 100644
--- a/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleReduceBrightColorsPreferenceFragment.java
@@ -36,6 +36,7 @@
import androidx.preference.SwitchPreference;
import com.android.settings.R;
+import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SeekBarPreference;
import com.android.settings.widget.SettingsMainSwitchPreference;
@@ -68,6 +69,7 @@
mComponentName = REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
mPackageName = getText(R.string.reduce_bright_colors_preference_title);
mHtmlDescription = getText(R.string.reduce_bright_colors_preference_subtitle);
+ mTopIntroTitle = getText(R.string.reduce_bright_colors_preference_intro_text);
mRbcIntensityPreferenceController =
new ReduceBrightColorsIntensityPreferenceController(getContext(), KEY_INTENSITY);
mRbcPersistencePreferenceController =
@@ -146,7 +148,9 @@
@Override
protected void onPreferenceToggled(String preferenceKey, boolean enabled) {
- super.onPreferenceToggled(preferenceKey, enabled);
+ if (enabled) {
+ showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
+ }
logAccessibilityServiceEnabled(mComponentName, enabled);
mColorDisplayManager.setReduceBrightColorsActivated(enabled);
}
diff --git a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
index 164cfd9..8f1c212 100644
--- a/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
+++ b/src/com/android/settings/applications/appinfo/AppLocaleDetails.java
@@ -38,8 +38,6 @@
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
-import com.android.internal.app.LocalePicker;
-import com.android.internal.app.LocalePicker.LocaleInfo;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoBase;
@@ -48,11 +46,8 @@
import com.android.settingslib.widget.LayoutPreference;
import com.android.settingslib.widget.RadioButtonPreference;
-import com.google.common.collect.Iterables;
-
import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
import java.util.Locale;
/**
@@ -66,13 +61,17 @@
private static final String CATEGORY_KEY_ALL_LANGUAGES =
"category_key_all_languages";
private static final String KEY_APP_DESCRIPTION = "app_locale_description";
+ @VisibleForTesting
+ static final String KEY_SYSTEM_DEFAULT_LOCALE = "system_default_locale";
private boolean mCreated = false;
- private AppLocaleDetailsHelper mAppLocaleDetailsHelper;
+ @VisibleForTesting
+ AppLocaleDetailsHelper mAppLocaleDetailsHelper;
private PreferenceGroup mGroupOfSuggestedLocales;
private PreferenceGroup mGroupOfSupportedLocales;
private LayoutPreference mPrefOfDescription;
+ private RadioButtonPreference mDefaultPreference;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -85,6 +84,10 @@
mGroupOfSupportedLocales =
getPreferenceScreen().findPreference(CATEGORY_KEY_ALL_LANGUAGES);
mPrefOfDescription = getPreferenceScreen().findPreference(KEY_APP_DESCRIPTION);
+
+ mDefaultPreference = (RadioButtonPreference) getPreferenceScreen()
+ .findPreference(KEY_SYSTEM_DEFAULT_LOCALE);
+ mDefaultPreference.setOnClickListener(this);
}
// Override here so we don't have an empty screen
@@ -104,30 +107,43 @@
// Update Locales first, before refresh ui.
mAppLocaleDetailsHelper.handleAllLocalesData();
super.onResume();
+ mDefaultPreference.setSummary(Locale.getDefault().getDisplayName(Locale.getDefault()));
}
@Override
protected boolean refreshUi() {
+ refreshUiInternal();
+ return true;
+ }
+
+ @VisibleForTesting
+ void refreshUiInternal() {
if (mAppLocaleDetailsHelper.getSupportedLocales().isEmpty()) {
Log.d(TAG, "No supported language.");
mGroupOfSuggestedLocales.setVisible(false);
mGroupOfSupportedLocales.setVisible(false);
mPrefOfDescription.setVisible(true);
TextView description = (TextView) mPrefOfDescription.findViewById(R.id.description);
- Locale locale = mAppLocaleDetailsHelper.getCurrentSystemLocales().get(0);
description.setText(getContext().getString(R.string.no_multiple_language_supported,
- locale.getDisplayName(locale)));
- return true;
+ Locale.getDefault().getDisplayName(Locale.getDefault())));
+ return;
}
-
- mGroupOfSuggestedLocales.removeAll();
- mGroupOfSupportedLocales.removeAll();
+ resetLocalePreferences();
Locale appLocale = AppLocaleDetailsHelper.getAppDefaultLocale(getContext(), mPackageName);
+ // Sets up default locale preference.
+ mGroupOfSuggestedLocales.addPreference(mDefaultPreference);
+ mDefaultPreference.setChecked(appLocale == null);
+ // Sets up suggested locales of per app.
setLanguagesPreference(mGroupOfSuggestedLocales,
mAppLocaleDetailsHelper.getSuggestedLocales(), appLocale);
+ // Sets up supported locales of per app.
setLanguagesPreference(mGroupOfSupportedLocales,
mAppLocaleDetailsHelper.getSupportedLocales(), appLocale);
- return true;
+ }
+
+ private void resetLocalePreferences() {
+ mGroupOfSuggestedLocales.removeAll();
+ mGroupOfSupportedLocales.removeAll();
}
@Override
@@ -142,7 +158,12 @@
@Override
public void onRadioButtonClicked(RadioButtonPreference pref) {
- mAppLocaleDetailsHelper.setAppDefaultLocale(pref.getKey());
+ String key = pref.getKey();
+ if (KEY_SYSTEM_DEFAULT_LOCALE.equals(key)) {
+ mAppLocaleDetailsHelper.setAppDefaultLocale(LocaleList.forLanguageTags(""));
+ } else {
+ mAppLocaleDetailsHelper.setAppDefaultLocale(key);
+ }
refreshUi();
}
@@ -180,7 +201,13 @@
public static CharSequence getSummary(Context context, String packageName) {
Locale appLocale =
AppLocaleDetailsHelper.getAppDefaultLocale(context, packageName);
- return appLocale == null ? "" : appLocale.getDisplayName(appLocale);
+ if (appLocale == null) {
+ Locale systemLocale = Locale.getDefault();
+ return context.getString(R.string.preference_of_system_locale_summary,
+ systemLocale.getDisplayName(systemLocale));
+ } else {
+ return appLocale.getDisplayName(appLocale);
+ }
}
private void setLanguagesPreference(PreferenceGroup group,
@@ -190,9 +217,15 @@
}
for (Locale locale : locales) {
+ if (locale == null) {
+ continue;
+ }
+
RadioButtonPreference pref = new RadioButtonPreference(getContext());
pref.setTitle(locale.getDisplayName(locale));
pref.setKey(locale.toLanguageTag());
+ // Will never be checked if appLocale is null
+ // aka if there is no per-app locale
pref.setChecked(locale.equals(appLocale));
pref.setOnClickListener(this);
group.addPreference(pref);
@@ -206,14 +239,17 @@
private TelephonyManager mTelephonyManager;
private LocaleManager mLocaleManager;
- private Collection<Locale> mSuggestedLocales = new ArrayList<>();
- private Collection<Locale> mSupportedLocales = new ArrayList<>();
+ private Collection<Locale> mProcessedSuggestedLocales = new ArrayList<>();
+ private Collection<Locale> mProcessedSupportedLocales = new ArrayList<>();
+
+ private Collection<Locale> mAppSupportedLocales = new ArrayList<>();
AppLocaleDetailsHelper(Context context, String packageName) {
mContext = context;
mPackageName = packageName;
mTelephonyManager = context.getSystemService(TelephonyManager.class);
mLocaleManager = context.getSystemService(LocaleManager.class);
+ mAppSupportedLocales = getAppSupportedLocales();
}
/** Handle suggested and supported locales for UI display. */
@@ -225,49 +261,47 @@
/** Gets suggested locales in the app. */
public Collection<Locale> getSuggestedLocales() {
- return mSuggestedLocales;
+ return mProcessedSuggestedLocales;
}
/** Gets supported locales in the app. */
public Collection<Locale> getSupportedLocales() {
- return mSupportedLocales;
+ return mProcessedSupportedLocales;
}
@VisibleForTesting
void handleSuggestedLocales() {
- LocaleList currentSystemLocales = getCurrentSystemLocales();
Locale appLocale = getAppDefaultLocale(mContext, mPackageName);
+ // 1st locale in suggested languages group.
+ for (Locale supportedlocale : mAppSupportedLocales) {
+ if (compareLocale(supportedlocale, appLocale)) {
+ mProcessedSuggestedLocales.add(appLocale);
+ break;
+ }
+ }
+
+ // 2nd and 3rd locale in suggested languages group.
String simCountry = mTelephonyManager.getSimCountryIso().toUpperCase(Locale.US);
String networkCountry = mTelephonyManager.getNetworkCountryIso().toUpperCase(Locale.US);
- // 1st locale in suggested languages group.
- if (appLocale != null) {
- mSuggestedLocales.add(appLocale);
- }
- // 2nd locale in suggested languages group.
- final List<LocaleInfo> localeInfos = LocalePicker.getAllAssetLocales(mContext, false);
- for (LocaleInfo localeInfo : localeInfos) {
- Locale locale = localeInfo.getLocale();
- String localeCountry = locale.getCountry().toUpperCase(Locale.US);
- if (!compareLocale(locale, appLocale)
+ mAppSupportedLocales.forEach(supportedlocale -> {
+ String localeCountry = supportedlocale.getCountry().toUpperCase(Locale.US);
+ if (!compareLocale(supportedlocale, appLocale)
&& isCountrySuggestedLocale(localeCountry, simCountry, networkCountry)) {
- mSuggestedLocales.add(locale);
+ mProcessedSuggestedLocales.add(supportedlocale);
}
- }
+ });
+
// Other locales in suggested languages group.
- for (int i = 0; i < currentSystemLocales.size(); i++) {
- Locale locale = currentSystemLocales.get(i);
- boolean isInSuggestedLocales = false;
- for (int j = 0; j < mSuggestedLocales.size(); j++) {
- Locale suggestedLocale = Iterables.get(mSuggestedLocales, j);
- if (compareLocale(locale, suggestedLocale)) {
- isInSuggestedLocales = true;
- break;
+ Collection<Locale> supportedSystemLocales = new ArrayList<>();
+ getCurrentSystemLocales().forEach(systemLocale -> {
+ mAppSupportedLocales.forEach(supportedLocale -> {
+ if (compareLocale(systemLocale, supportedLocale)) {
+ supportedSystemLocales.add(supportedLocale);
}
- }
- if (!isInSuggestedLocales) {
- mSuggestedLocales.add(locale);
- }
- }
+ });
+ });
+ supportedSystemLocales.removeAll(mProcessedSuggestedLocales);
+ mProcessedSuggestedLocales.addAll(supportedSystemLocales);
}
@VisibleForTesting
@@ -290,26 +324,34 @@
@VisibleForTesting
void handleSupportedLocales() {
- LocaleList localeList = getPackageLocales();
- if (localeList == null) {
- String[] languages = getAssetSystemLocales();
- for (String language : languages) {
- mSupportedLocales.add(Locale.forLanguageTag(language));
- }
- } else {
- for (int i = 0; i < localeList.size(); i++) {
- mSupportedLocales.add(localeList.get(i));
- }
- }
+ mProcessedSupportedLocales.addAll(mAppSupportedLocales);
- if (mSuggestedLocales != null || !mSuggestedLocales.isEmpty()) {
- mSupportedLocales.removeAll(mSuggestedLocales);
+ if (mProcessedSuggestedLocales != null || !mProcessedSuggestedLocales.isEmpty()) {
+ mProcessedSuggestedLocales.retainAll(mProcessedSupportedLocales);
+ mProcessedSupportedLocales.removeAll(mProcessedSuggestedLocales);
}
}
private void clearLocalesData() {
- mSuggestedLocales.clear();
- mSupportedLocales.clear();
+ mProcessedSuggestedLocales.clear();
+ mProcessedSupportedLocales.clear();
+ }
+
+ private Collection<Locale> getAppSupportedLocales() {
+ Collection<Locale> appSupportedLocales = new ArrayList<>();
+ LocaleList localeList = getPackageLocales();
+
+ if (localeList != null && localeList.size() > 0) {
+ for (int i = 0; i < localeList.size(); i++) {
+ appSupportedLocales.add(localeList.get(i));
+ }
+ } else {
+ String[] languages = getAssetLocales();
+ for (String language : languages) {
+ appSupportedLocales.add(Locale.forLanguageTag(language));
+ }
+ }
+ return appSupportedLocales;
}
/** Gets per app's default locale */
@@ -317,8 +359,8 @@
LocaleManager localeManager = context.getSystemService(LocaleManager.class);
try {
LocaleList localeList = (localeManager == null)
- ? new LocaleList() : localeManager.getApplicationLocales(packageName);
- return localeList.isEmpty() ? null : localeList.get(0);
+ ? null : localeManager.getApplicationLocales(packageName);
+ return localeList == null ? null : localeList.get(0);
} catch (IllegalArgumentException e) {
Log.w(TAG, "package name : " + packageName + " is not correct. " + e);
}
@@ -344,12 +386,17 @@
}
@VisibleForTesting
- LocaleList getCurrentSystemLocales() {
- return Resources.getSystem().getConfiguration().getLocales();
+ Collection<Locale> getCurrentSystemLocales() {
+ LocaleList localeList = Resources.getSystem().getConfiguration().getLocales();
+ Collection<Locale> systemLocales = new ArrayList<>();
+ for (int i = 0; i < localeList.size(); i++) {
+ systemLocales.add(localeList.get(i));
+ }
+ return systemLocales;
}
@VisibleForTesting
- String[] getAssetSystemLocales() {
+ String[] getAssetLocales() {
try {
PackageManager packageManager = mContext.getPackageManager();
return packageManager.getResourcesForApplication(
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
index ec3e11f..d80512e 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsMacAddressController.java
@@ -46,21 +46,22 @@
protected void init(PreferenceScreen screen) {
mFooterPreference = screen.findPreference(KEY_DEVICE_DETAILS_FOOTER);
mFooterPreference.setTitle(mContext.getString(
- R.string.bluetooth_device_mac_address, mCachedDevice.getAddress()));
+ R.string.bluetooth_device_mac_address, mCachedDevice.getIdentityAddress()));
}
@Override
protected void refresh() {
if (mCachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
StringBuilder title = new StringBuilder(mContext.getString(
- R.string.bluetooth_multuple_devices_mac_address, mCachedDevice.getAddress()));
+ R.string.bluetooth_multuple_devices_mac_address,
+ mCachedDevice.getIdentityAddress()));
for (CachedBluetoothDevice member: mCachedDevice.getMemberDevice()) {
- title.append("\n").append(member.getAddress());
+ title.append("\n").append(member.getIdentityAddress());
}
mFooterPreference.setTitle(title);
} else {
mFooterPreference.setTitle(mContext.getString(
- R.string.bluetooth_device_mac_address, mCachedDevice.getAddress()));
+ R.string.bluetooth_device_mac_address, mCachedDevice.getIdentityAddress()));
}
}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 2f0e8b3..ce3cab9 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -29,6 +29,7 @@
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard;
import com.android.settings.accessibility.CaptionPropertiesFragment;
+import com.android.settings.accessibility.TextReadingPreferenceFragmentForSetupWizard;
import com.android.settings.accessibility.ToggleColorInversionPreferenceFragment;
import com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment;
import com.android.settings.accessibility.ToggleReduceBrightColorsPreferenceFragment;
@@ -222,6 +223,7 @@
AccessibilityDetailsSettingsFragment.class.getName(),
AccessibilitySettings.class.getName(),
AccessibilitySettingsForSetupWizard.class.getName(),
+ TextReadingPreferenceFragmentForSetupWizard.class.getName(),
CaptionPropertiesFragment.class.getName(),
ToggleDaltonizerPreferenceFragment.class.getName(),
ToggleColorInversionPreferenceFragment.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index cdac3b9..8ad66d2 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -171,11 +171,13 @@
intent.setAction(action);
}
// Register the rule for injected apps.
- ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
- mContext,
- new ComponentName(tile.getPackageName(), tile.getComponentName()),
- action,
- true /* clearTop */);
+ if (fragment instanceof TopLevelSettings) {
+ ActivityEmbeddingRulesController.registerTwoPanePairRuleForSettingsHome(
+ mContext,
+ new ComponentName(tile.getPackageName(), tile.getComponentName()),
+ action,
+ true /* clearTop */);
+ }
pref.setOnPreferenceClickListener(preference -> {
TopLevelHighlightMixin highlightMixin = null;
if (fragment instanceof TopLevelSettings
@@ -442,11 +444,6 @@
ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory);
- //TODO(b/201970810): Add test cases.
- if (tile.isNewTask(mContext)) {
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
-
if (tile.userHandle == null || tile.isPrimaryProfileOnly()) {
activity.startActivity(intent);
} else if (tile.userHandle.size() == 1) {
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index cfdfdaa..8b1d633 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -53,6 +53,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -280,6 +281,11 @@
return null;
}
+ /** Returns all controllers of type T. */
+ protected <T extends AbstractPreferenceController> List<T> useAll(Class<T> clazz) {
+ return (List<T>) mPreferenceControllers.getOrDefault(clazz, Collections.emptyList());
+ }
+
protected void addPreferenceController(AbstractPreferenceController controller) {
if (mPreferenceControllers.get(controller.getClass()) == null) {
mPreferenceControllers.put(controller.getClass(), new ArrayList<>());
diff --git a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
index e0ba378..d3234dd 100644
--- a/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
+++ b/src/com/android/settings/dashboard/profileselector/ProfileSelectDialog.java
@@ -97,7 +97,7 @@
public void onClick(DialogInterface dialog, int which) {
final UserHandle user = mSelectedTile.userHandle.get(which);
// Show menu on top level items.
- final Intent intent = mSelectedTile.getIntent();
+ final Intent intent = new Intent(mSelectedTile.getIntent());
FeatureFactory.getFactory(getContext()).getMetricsFeatureProvider()
.logStartedIntentWithProfile(intent, mSourceMetricCategory,
which == 1 /* isWorkProfile */);
diff --git a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
index ceba8be..08e523c 100644
--- a/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
+++ b/src/com/android/settings/datausage/UnrestrictedDataAccessPreference.java
@@ -48,7 +48,6 @@
ApplicationsState applicationsState, DataSaverBackend dataSaverBackend,
DashboardFragment parentFragment) {
super(context);
- setWidgetLayoutResource(R.layout.restricted_switch_widget);
mHelper = new RestrictedPreferenceHelper(context, this, null);
mEntry = entry;
mDataUsageState = (AppStateDataUsageBridge.DataUsageState) mEntry.extraInfo;
@@ -131,10 +130,6 @@
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
- holder.findViewById(R.id.restricted_icon).setVisibility(
- disabledByAdmin ? View.VISIBLE : View.GONE);
- holder.findViewById(android.R.id.switch_widget).setVisibility(
- disabledByAdmin ? View.GONE : View.VISIBLE);
}
@Override
diff --git a/src/com/android/settings/display/AutoRotatePreferenceController.java b/src/com/android/settings/display/AutoRotatePreferenceController.java
index 5dc2286..90423fb 100644
--- a/src/com/android/settings/display/AutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/AutoRotatePreferenceController.java
@@ -74,6 +74,7 @@
@Override
public int getAvailabilityStatus() {
return RotationPolicy.isRotationLockToggleVisible(mContext)
+ && !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
diff --git a/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java b/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java
new file mode 100644
index 0000000..fb6d9f4
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragment.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.search.Indexable;
+import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import java.util.List;
+
+/** Fragment that shows all the available device state based auto-rotation preferences. */
+@SearchIndexable
+public class DeviceStateAutoRotateDetailsFragment extends DashboardFragment {
+
+ private static final String TAG = "DeviceStateAutoRotateDetailsFragment";
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.DISPLAY_AUTO_ROTATE_SETTINGS;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.device_state_auto_rotate_settings;
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ DeviceStateAutoRotationHelper.initControllers(
+ getLifecycle(),
+ useAll(DeviceStateAutoRotateSettingController.class)
+ );
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ return DeviceStateAutoRotationHelper.createPreferenceControllers(context);
+ }
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.device_state_auto_rotate_settings) {
+
+ @Override
+ public List<SearchIndexableRaw> getRawDataToIndex(Context context,
+ boolean enabled) {
+ return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled);
+ }
+ };
+}
diff --git a/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java b/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java
new file mode 100644
index 0000000..5e49bf3
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotateOverviewController.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.display;
+
+import android.content.Context;
+import android.text.TextUtils;
+
+import com.android.settings.core.BasePreferenceController;
+
+/**
+ * The top-level preference controller for device state based auto-rotation settings.
+ *
+ * It doesn't do anything on its own besides showing/hiding. The toggling of the settings will
+ * always be done in the details screen when device state based auto-rotation is enabled.
+ */
+public class DeviceStateAutoRotateOverviewController extends BasePreferenceController {
+
+ /** Preference key for when it is used in "accessibility_system_controls.xml". */
+ private static final String ACCESSIBILITY_PREF_KEY = "device_state_auto_rotate_accessibility";
+
+ public DeviceStateAutoRotateOverviewController(Context context, String key) {
+ super(context, key);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return isAvailableInternal() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+
+ private boolean isAvailableInternal() {
+ return isA11yPage()
+ ? DeviceStateAutoRotationHelper.isDeviceStateRotationEnabledForA11y(mContext)
+ : DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext);
+ }
+
+ private boolean isA11yPage() {
+ return TextUtils.equals(getPreferenceKey(), ACCESSIBILITY_PREF_KEY);
+ }
+}
diff --git a/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java b/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java
new file mode 100644
index 0000000..c8f6280
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotateSettingController.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static androidx.lifecycle.Lifecycle.Event.ON_START;
+import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import java.util.List;
+
+/** Controller for device state based auto rotation preferences. */
+public class DeviceStateAutoRotateSettingController extends TogglePreferenceController implements
+ LifecycleObserver {
+
+ private SwitchPreference mPreference;
+
+ private final DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager;
+ private final int mOrder;
+ private final DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
+ mDeviceStateRotationLockSettingsListener = () -> updateState(mPreference);
+ private final int mDeviceState;
+ private final String mDeviceStateDescription;
+ private final MetricsFeatureProvider mMetricsFeatureProvider;
+
+ public DeviceStateAutoRotateSettingController(Context context, int deviceState,
+ String deviceStateDescription, int order) {
+ super(context, getPreferenceKeyForDeviceState(deviceState));
+ mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+ mDeviceState = deviceState;
+ mDeviceStateDescription = deviceStateDescription;
+ mAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(context);
+ mOrder = order;
+ }
+
+ void init(Lifecycle lifecycle) {
+ lifecycle.addObserver(this);
+ }
+
+ @OnLifecycleEvent(ON_START)
+ void onStart() {
+ mAutoRotateSettingsManager.registerListener(mDeviceStateRotationLockSettingsListener);
+ }
+
+ @OnLifecycleEvent(ON_STOP)
+ void onStop() {
+ mAutoRotateSettingsManager.unregisterListener(mDeviceStateRotationLockSettingsListener);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mPreference = new SwitchPreference(mContext);
+ mPreference.setTitle(mDeviceStateDescription);
+ mPreference.setKey(getPreferenceKey());
+ mPreference.setOrder(mOrder);
+ screen.addPreference(mPreference);
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
+ ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return getPreferenceKeyForDeviceState(mDeviceState);
+ }
+
+ private static String getPreferenceKeyForDeviceState(int deviceState) {
+ return "auto_rotate_device_state_" + deviceState;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return !mAutoRotateSettingsManager.isRotationLocked(mDeviceState);
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ boolean isRotationLocked = !isChecked;
+ mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_ROTATION_LOCK,
+ isRotationLocked);
+ mAutoRotateSettingsManager.updateSetting(mDeviceState, isRotationLocked);
+ return true;
+ }
+
+ @Override
+ public void updateRawDataToIndex(List<SearchIndexableRaw> rawData) {
+ SearchIndexableRaw indexable = new SearchIndexableRaw(mContext);
+ indexable.key = getPreferenceKey();
+ indexable.title = mDeviceStateDescription;
+ // Maybe pass screen title as param?
+ indexable.screenTitle = mContext.getString(R.string.accelerometer_title);
+ rawData.add(indexable);
+ }
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_display;
+ }
+
+ @Override
+ public boolean isSliceable() {
+ return true; // Maybe set to false if in accessibility settings screen
+ }
+
+ @Override
+ public boolean isPublicSlice() {
+ return true;
+ }
+}
diff --git a/src/com/android/settings/display/DeviceStateAutoRotationHelper.java b/src/com/android/settings/display/DeviceStateAutoRotationHelper.java
new file mode 100644
index 0000000..223ef1a
--- /dev/null
+++ b/src/com/android/settings/display/DeviceStateAutoRotationHelper.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.lifecycle.Lifecycle;
+
+import com.android.internal.view.RotationPolicy;
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class with utility methods related to device state auto-rotation that can be used in
+ * auto-rotation settings fragments and controllers.
+ */
+public class DeviceStateAutoRotationHelper {
+
+ private static final String TAG = "DeviceStateAutoRotHelpr";
+
+ static void initControllers(Lifecycle lifecycle,
+ List<DeviceStateAutoRotateSettingController> controllers) {
+ for (DeviceStateAutoRotateSettingController controller : controllers) {
+ controller.init(lifecycle);
+ }
+ }
+
+ static ImmutableList<AbstractPreferenceController> createPreferenceControllers(
+ Context context) {
+ List<SettableDeviceState> settableDeviceStates = DeviceStateRotationLockSettingsManager
+ .getInstance(context).getSettableDeviceStates();
+ int numDeviceStates = settableDeviceStates.size();
+ if (numDeviceStates == 0) {
+ return ImmutableList.of();
+ }
+ String[] deviceStateSettingDescriptions = context.getResources().getStringArray(
+ R.array.config_settableAutoRotationDeviceStatesDescriptions);
+ if (numDeviceStates != deviceStateSettingDescriptions.length) {
+ Log.wtf(TAG,
+ "Mismatch between number of device states and device states descriptions.");
+ return ImmutableList.of();
+ }
+
+ ImmutableList.Builder<AbstractPreferenceController> controllers =
+ ImmutableList.builderWithExpectedSize(numDeviceStates);
+ for (int i = 0; i < numDeviceStates; i++) {
+ SettableDeviceState settableDeviceState = settableDeviceStates.get(i);
+ if (!settableDeviceState.isSettable()) {
+ continue;
+ }
+ // Preferences with a lower order will be showed first. Here we go below 0 to make sure
+ // we are shown before statically declared preferences in XML.
+ int order = -numDeviceStates + i;
+ controllers.add(new DeviceStateAutoRotateSettingController(
+ context,
+ settableDeviceState.getDeviceState(),
+ deviceStateSettingDescriptions[i],
+ order
+ ));
+ }
+ return controllers.build();
+ }
+
+ static List<SearchIndexableRaw> getRawDataToIndex(
+ Context context, boolean enabled) {
+ // Check what the "enabled" param is for
+ List<AbstractPreferenceController> controllers = createPreferenceControllers(context);
+ List<SearchIndexableRaw> rawData = new ArrayList<>();
+ for (AbstractPreferenceController controller : controllers) {
+ ((BasePreferenceController) controller).updateRawDataToIndex(rawData);
+ }
+ return rawData;
+ }
+
+ /** Returns whether the device state based auto-rotation settings are enabled. */
+ public static boolean isDeviceStateRotationEnabled(Context context) {
+ return RotationPolicy.isRotationLockToggleVisible(context)
+ && DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
+ }
+
+ /**
+ * Returns whether the device state based auto-rotation settings are enabled for the
+ * accessibility settings page.
+ */
+ public static boolean isDeviceStateRotationEnabledForA11y(Context context) {
+ return RotationPolicy.isRotationSupported(context)
+ && DeviceStateRotationLockSettingsManager.isDeviceStateRotationLockEnabled(context);
+ }
+}
diff --git a/src/com/android/settings/display/SmartAutoRotateController.java b/src/com/android/settings/display/SmartAutoRotateController.java
index 76a222a..d29a64e 100644
--- a/src/com/android/settings/display/SmartAutoRotateController.java
+++ b/src/com/android/settings/display/SmartAutoRotateController.java
@@ -47,6 +47,7 @@
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
/**
* SmartAutoRotateController controls whether auto rotation is enabled
@@ -54,6 +55,8 @@
public class SmartAutoRotateController extends TogglePreferenceController implements
Preference.OnPreferenceChangeListener, LifecycleObserver {
+ protected Preference mPreference;
+
private final MetricsFeatureProvider mMetricsFeatureProvider;
private final SensorPrivacyManager mPrivacyManager;
private final PowerManager mPowerManager;
@@ -63,7 +66,9 @@
updateState(mPreference);
}
};
- protected Preference mPreference;
+ private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager;
+ private final DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
+ mDeviceStateRotationLockSettingsListener = () -> updateState(mPreference);
private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
public SmartAutoRotateController(Context context, String preferenceKey) {
@@ -73,6 +78,8 @@
mPrivacyManager
.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> updateState(mPreference));
mPowerManager = context.getSystemService(PowerManager.class);
+ mDeviceStateAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance(
+ context);
}
public void init(Lifecycle lifecycle) {
@@ -89,6 +96,9 @@
}
protected boolean isRotationLocked() {
+ if (DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)) {
+ return mDeviceStateAutoRotateSettingsManager.isRotationLockedForAllStates();
+ }
return RotationPolicy.isRotationLocked(mContext);
}
@@ -127,6 +137,8 @@
};
}
RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener);
+ mDeviceStateAutoRotateSettingsManager.registerListener(
+ mDeviceStateRotationLockSettingsListener);
}
@OnLifecycleEvent(ON_STOP)
@@ -136,6 +148,8 @@
RotationPolicy.unregisterRotationPolicyListener(mContext, mRotationPolicyListener);
mRotationPolicyListener = null;
}
+ mDeviceStateAutoRotateSettingsManager.unregisterListener(
+ mDeviceStateRotationLockSettingsListener);
}
@Override
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
index bd8ee84..d02e336 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
@@ -77,6 +77,7 @@
@Override
public int getAvailabilityStatus() {
return RotationPolicy.isRotationLockToggleVisible(mContext)
+ && !DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(mContext)
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
index 4737336..9fda03c 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceFragment.java
@@ -34,10 +34,14 @@
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.SettingsMainSwitchBar;
+import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.widget.FooterPreference;
+import java.util.List;
+
/**
* Preference fragment used for auto rotation
*/
@@ -60,6 +64,15 @@
public void onAttach(Context context) {
super.onAttach(context);
use(SmartAutoRotateController.class).init(getLifecycle());
+ DeviceStateAutoRotationHelper.initControllers(
+ getLifecycle(),
+ useAll(DeviceStateAutoRotateSettingController.class)
+ );
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
+ return DeviceStateAutoRotationHelper.createPreferenceControllers(context);
}
@Override
@@ -79,7 +92,9 @@
@VisibleForTesting
void createHeader(SettingsActivity activity) {
- if (isRotationResolverServiceAvailable(activity)) {
+ boolean deviceStateRotationEnabled =
+ DeviceStateAutoRotationHelper.isDeviceStateRotationEnabled(activity);
+ if (isRotationResolverServiceAvailable(activity) && !deviceStateRotationEnabled) {
final SettingsMainSwitchBar switchBar = activity.getSwitchBar();
switchBar.setTitle(
getContext().getString(R.string.auto_rotate_settings_primary_switch_title));
@@ -127,5 +142,12 @@
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider(R.xml.auto_rotate_settings);
+ new BaseSearchIndexProvider(R.xml.auto_rotate_settings) {
+
+ @Override
+ public List<SearchIndexableRaw> getRawDataToIndex(
+ Context context, boolean enabled) {
+ return DeviceStateAutoRotationHelper.getRawDataToIndex(context, enabled);
+ }
+ };
}
diff --git a/src/com/android/settings/dream/AutoFitGridLayoutManager.java b/src/com/android/settings/dream/AutoFitGridLayoutManager.java
index 0e5d3e1..7de0eae 100644
--- a/src/com/android/settings/dream/AutoFitGridLayoutManager.java
+++ b/src/com/android/settings/dream/AutoFitGridLayoutManager.java
@@ -24,10 +24,10 @@
import com.android.settings.R;
/** Grid layout manager that calculates the number of columns for the screen size. */
-final class AutoFitGridLayoutManager extends GridLayoutManager {
+public final class AutoFitGridLayoutManager extends GridLayoutManager {
private final float mColumnWidth;
- AutoFitGridLayoutManager(Context context) {
+ public AutoFitGridLayoutManager(Context context) {
super(context, /* spanCount= */ 1);
this.mColumnWidth = context
.getResources()
diff --git a/src/com/android/settings/dream/DreamAdapter.java b/src/com/android/settings/dream/DreamAdapter.java
index e674546..4e16ccb 100644
--- a/src/com/android/settings/dream/DreamAdapter.java
+++ b/src/com/android/settings/dream/DreamAdapter.java
@@ -37,7 +37,7 @@
/**
* RecyclerView adapter which displays list of items for the user to select.
*/
-class DreamAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+public class DreamAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final List<IDreamItem> mItemList;
private int mLastSelectedPos = -1;
@@ -48,6 +48,7 @@
private final ImageView mIconView;
private final TextView mTitleView;
private final ImageView mPreviewView;
+ private final ImageView mPreviewPlaceholderView;
private final Button mCustomizeButton;
private final Context mContext;
@@ -55,6 +56,7 @@
super(view);
mContext = context;
mPreviewView = view.findViewById(R.id.preview);
+ mPreviewPlaceholderView = view.findViewById(R.id.preview_placeholder);
mIconView = view.findViewById(R.id.icon);
mTitleView = view.findViewById(R.id.title_text);
mCustomizeButton = view.findViewById(R.id.customize_button);
@@ -68,10 +70,9 @@
final Drawable previewImage = item.getPreviewImage();
if (previewImage != null) {
- mPreviewView.setVisibility(View.VISIBLE);
mPreviewView.setImageDrawable(previewImage);
- } else {
- mPreviewView.setVisibility(View.GONE);
+ mPreviewView.setClipToOutline(true);
+ mPreviewPlaceholderView.setVisibility(View.GONE);
}
final Drawable icon = item.isActive()
@@ -103,7 +104,7 @@
}
}
- DreamAdapter(List<IDreamItem> itemList) {
+ public DreamAdapter(List<IDreamItem> itemList) {
mItemList = itemList;
}
diff --git a/src/com/android/settings/dream/DreamComplicationPickerController.java b/src/com/android/settings/dream/DreamComplicationPickerController.java
deleted file mode 100644
index 09ed8da..0000000
--- a/src/com/android/settings/dream/DreamComplicationPickerController.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.dream;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-
-import androidx.preference.PreferenceScreen;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.dream.DreamBackend;
-import com.android.settingslib.widget.LayoutPreference;
-
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Controller for the component allowing a user to select overlays to show on top of dreams.
- */
-public class DreamComplicationPickerController extends BasePreferenceController {
- private static final String KEY = "dream_complication_picker";
-
- private final DreamBackend mBackend;
- private final Set<Integer> mSupportedComplications;
-
- private class ComplicationItem implements IDreamItem {
- private final int mComplicationType;
- private boolean mEnabled;
-
- ComplicationItem(@DreamBackend.ComplicationType int complicationType) {
- mComplicationType = complicationType;
- mEnabled = mBackend.isComplicationEnabled(mComplicationType);
- }
-
- @Override
- public CharSequence getTitle() {
- return mBackend.getComplicationTitle(mComplicationType);
- }
-
- @Override
- public Drawable getIcon() {
- // TODO(b/215703483): add icon for each complication
- return null;
- }
-
- @Override
- public void onItemClicked() {
- mEnabled = !mEnabled;
- mBackend.setComplicationEnabled(mComplicationType, mEnabled);
- }
-
- @Override
- public Drawable getPreviewImage() {
- // TODO(b/215703483): add preview image for each complication
- return null;
- }
-
- @Override
- public boolean isActive() {
- return mEnabled;
- }
- }
-
- public DreamComplicationPickerController(Context context) {
- super(context, KEY);
- mBackend = DreamBackend.getInstance(context);
- mSupportedComplications = mBackend.getSupportedComplications();
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY;
- }
-
- @Override
- public int getAvailabilityStatus() {
- return mSupportedComplications.size() > 0 ? AVAILABLE
- : CONDITIONALLY_UNAVAILABLE;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
-
- DreamAdapter adapter = new DreamAdapter(mSupportedComplications.stream()
- .map(ComplicationItem::new)
- .collect(Collectors.toList()));
-
- LayoutPreference pref = screen.findPreference(getPreferenceKey());
- if (pref != null) {
- final RecyclerView recyclerView = pref.findViewById(R.id.dream_list);
- recyclerView.setLayoutManager(new AutoFitGridLayoutManager(mContext));
- recyclerView.setHasFixedSize(true);
- recyclerView.setAdapter(adapter);
- }
- }
-}
diff --git a/src/com/android/settings/dream/DreamComplicationPreferenceController.java b/src/com/android/settings/dream/DreamComplicationPreferenceController.java
new file mode 100644
index 0000000..d9c4fb3
--- /dev/null
+++ b/src/com/android/settings/dream/DreamComplicationPreferenceController.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.dream;
+
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.dream.DreamBackend;
+
+/**
+ * Controller for the {@link androidx.preference.SwitchPreference} which controls if dream
+ * overlays should be enabled.
+ */
+public class DreamComplicationPreferenceController extends TogglePreferenceController {
+ private final DreamBackend mBackend;
+
+ public DreamComplicationPreferenceController(Context context, String key) {
+ super(context, key);
+ mBackend = DreamBackend.getInstance(context);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return mBackend.getSupportedComplications().isEmpty() ? CONDITIONALLY_UNAVAILABLE
+ : AVAILABLE;
+ }
+
+ @Override
+ public boolean isChecked() {
+ return mBackend.getEnabledComplications().containsAll(mBackend.getSupportedComplications());
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ for (int complication : mBackend.getSupportedComplications()) {
+ mBackend.setComplicationEnabled(complication, isChecked);
+ }
+ return true;
+ }
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_display;
+ }
+}
diff --git a/src/com/android/settings/dream/DreamPickerController.java b/src/com/android/settings/dream/DreamPickerController.java
index e4081ac..b7ba614 100644
--- a/src/com/android/settings/dream/DreamPickerController.java
+++ b/src/com/android/settings/dream/DreamPickerController.java
@@ -19,11 +19,9 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.view.View;
-import android.widget.Button;
import androidx.annotation.Nullable;
-import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
@@ -46,7 +44,6 @@
private final DreamBackend mBackend;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private final List<DreamInfo> mDreamInfos;
- private Button mPreviewButton;
@Nullable
private DreamInfo mActiveDream;
private DreamAdapter mAdapter;
@@ -74,29 +71,23 @@
}
@Override
- public void updateState(Preference preference) {
- super.updateState(preference);
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
mAdapter = new DreamAdapter(mDreamInfos.stream()
.map(DreamItem::new)
.collect(Collectors.toList()));
- final RecyclerView recyclerView =
- ((LayoutPreference) preference).findViewById(R.id.dream_list);
+ final LayoutPreference pref = screen.findPreference(getPreferenceKey());
+ if (pref == null) {
+ return;
+ }
+ final RecyclerView recyclerView = pref.findViewById(R.id.dream_list);
recyclerView.setLayoutManager(new AutoFitGridLayoutManager(mContext));
+ recyclerView.addItemDecoration(
+ new GridSpacingItemDecoration(mContext, R.dimen.dream_preference_card_padding));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(mAdapter);
-
- mPreviewButton = ((LayoutPreference) preference).findViewById(R.id.preview_button);
- mPreviewButton.setVisibility(View.VISIBLE);
- mPreviewButton.setOnClickListener(v -> mBackend.preview(mActiveDream));
- updatePreviewButtonState();
- }
-
- private void updatePreviewButtonState() {
- final boolean hasDream = mActiveDream != null;
- mPreviewButton.setClickable(hasDream);
- mPreviewButton.setEnabled(hasDream);
}
@Nullable
@@ -129,7 +120,6 @@
public void onItemClicked() {
mActiveDream = mDreamInfo;
mBackend.setActiveDream(mDreamInfo.componentName);
- updatePreviewButtonState();
mMetricsFeatureProvider.action(
mContext,
SettingsEnums.ACTION_DREAM_SELECT_TYPE,
diff --git a/src/com/android/settings/dream/DreamSettings.java b/src/com/android/settings/dream/DreamSettings.java
index 7ae364e..bfa19a9 100644
--- a/src/com/android/settings/dream/DreamSettings.java
+++ b/src/com/android/settings/dream/DreamSettings.java
@@ -23,20 +23,23 @@
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.Button;
import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.dream.DreamBackend;
import com.android.settingslib.dream.DreamBackend.WhenToDream;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
@SearchIndexable
@@ -47,7 +50,6 @@
static final String WHILE_DOCKED_ONLY = "while_docked_only";
static final String EITHER_CHARGING_OR_DOCKED = "either_charging_or_docked";
static final String NEVER_DREAM = "never";
- private static final String COMPLICATIONS_CATEGORY_KEY = "dream_complication_category";
@WhenToDream
static int getSettingFromPrefKey(String key) {
@@ -133,17 +135,30 @@
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
- final DreamComplicationPickerController complicationPickerController =
- new DreamComplicationPickerController(context);
-
- controllers.add(complicationPickerController);
- controllers.add(new WhenToDreamPreferenceController(context));
controllers.add(new DreamPickerController(context));
- controllers.add(new PreferenceCategoryController(context, COMPLICATIONS_CATEGORY_KEY)
- .setChildren(Collections.singletonList(complicationPickerController)));
+ controllers.add(new WhenToDreamPreferenceController(context));
return controllers;
}
+ @Override
+ public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
+ Bundle bundle) {
+
+ final ViewGroup root = getActivity().findViewById(android.R.id.content);
+ final Button previewButton = (Button) getActivity().getLayoutInflater().inflate(
+ R.layout.dream_preview_button, root, false);
+ root.addView(previewButton);
+
+ final DreamBackend dreamBackend = DreamBackend.getInstance(getContext());
+ previewButton.setOnClickListener(v -> dreamBackend.preview(dreamBackend.getActiveDream()));
+
+ final RecyclerView recyclerView = super.onCreateRecyclerView(inflater, parent, bundle);
+ previewButton.post(() -> {
+ recyclerView.setPadding(0, 0, 0, previewButton.getMeasuredHeight());
+ });
+ return recyclerView;
+ }
+
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER
= new BaseSearchIndexProvider(R.xml.dream_fragment_overview) {
diff --git a/src/com/android/settings/dream/DreamSetupActivity.java b/src/com/android/settings/dream/DreamSetupActivity.java
deleted file mode 100644
index 6a12671..0000000
--- a/src/com/android/settings/dream/DreamSetupActivity.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.dream;
-
-import android.app.settings.SettingsEnums;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settingslib.dream.DreamBackend;
-
-import com.google.android.setupcompat.template.FooterBarMixin;
-import com.google.android.setupcompat.template.FooterButton;
-import com.google.android.setupcompat.util.WizardManagerHelper;
-import com.google.android.setupdesign.GlifLayout;
-import com.google.android.setupdesign.util.ThemeHelper;
-import com.google.android.setupdesign.util.ThemeResolver;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * The setup activity for dreams which is displayed during setup wizard.
- */
-public class DreamSetupActivity extends SettingsActivity {
- @Override
- public Intent getIntent() {
- Intent modIntent = new Intent(super.getIntent());
- modIntent.putExtra(EXTRA_SHOW_FRAGMENT, DreamSetupFragment.class.getName());
- return modIntent;
- }
-
- @Override
- protected boolean isValidFragment(String fragmentName) {
- return DreamSetupFragment.class.getName().equals(fragmentName);
- }
-
- @Override
- protected void onCreate(Bundle savedInstance) {
- setTheme(ThemeResolver.getDefault().resolve(getIntent()));
- ThemeHelper.trySetDynamicColor(this);
- super.onCreate(savedInstance);
- }
-
- @Override
- protected boolean isToolbarEnabled() {
- return false;
- }
-
- /**
- * Fragment used to control the active dream.
- */
- public static class DreamSetupFragment extends SettingsPreferenceFragment {
- private DreamBackend mBackend;
- private DreamBackend.DreamInfo mActiveDream;
- private FooterButton mFooterButton;
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.DREAM;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return inflater.inflate(R.layout.dream_setup_layout, container, false);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- mBackend = DreamBackend.getInstance(getContext());
- final List<DreamBackend.DreamInfo> dreamInfos = mBackend.getDreamInfos();
- mActiveDream = dreamInfos.stream().filter(d -> d.isActive).findFirst().orElse(null);
- DreamAdapter dreamAdapter = new DreamAdapter(dreamInfos.stream()
- .map(DreamItem::new)
- .collect(Collectors.toList()));
-
- final RecyclerView recyclerView = view.findViewById(R.id.dream_setup_list);
- recyclerView.setLayoutManager(new AutoFitGridLayoutManager(getContext()));
- recyclerView.setHasFixedSize(true);
- recyclerView.setAdapter(dreamAdapter);
-
- final GlifLayout layout = view.findViewById(R.id.setup_wizard_layout);
- final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class);
- mFooterButton = new FooterButton.Builder(getContext())
- .setListener(this::onPrimaryButtonClicked)
- .setButtonType(FooterButton.ButtonType.NEXT)
- .setTheme(R.style.SudGlifButton_Primary)
- .build();
- updateFooterButtonText();
- mixin.setPrimaryButton(mFooterButton);
- }
-
- private void updateFooterButtonText() {
- final int res = canCustomizeDream() ? R.string.wizard_next : R.string.wizard_finish;
- mFooterButton.setText(getContext().getString(res));
- }
-
- private boolean canCustomizeDream() {
- return mActiveDream != null && mActiveDream.settingsComponentName != null;
- }
-
- private void onPrimaryButtonClicked(View view) {
- if (canCustomizeDream()) {
- final Intent intent = new Intent().setComponent(mActiveDream.settingsComponentName);
- WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
- startActivity(intent);
- }
-
- // Use RESULT_CANCELED here so that the user may go back and change this if they wish.
- setResult(RESULT_CANCELED);
- finish();
- }
-
- private class DreamItem implements IDreamItem {
- private final DreamBackend.DreamInfo mDreamInfo;
-
- private DreamItem(DreamBackend.DreamInfo dreamInfo) {
- mDreamInfo = dreamInfo;
- }
-
- @Override
- public CharSequence getTitle() {
- return mDreamInfo.caption;
- }
-
- @Override
- public Drawable getIcon() {
- return mDreamInfo.icon;
- }
-
- @Override
- public void onItemClicked() {
- mActiveDream = mDreamInfo;
- mBackend.setActiveDream(mDreamInfo.componentName);
- updateFooterButtonText();
- }
-
- @Override
- public Drawable getPreviewImage() {
- return mDreamInfo.previewImage;
- }
-
- @Override
- public boolean isActive() {
- if (mActiveDream == null) {
- return false;
- }
- return mDreamInfo.componentName.equals(mActiveDream.componentName);
- }
- }
- }
-}
diff --git a/src/com/android/settings/dream/GridSpacingItemDecoration.java b/src/com/android/settings/dream/GridSpacingItemDecoration.java
new file mode 100644
index 0000000..6e6a551
--- /dev/null
+++ b/src/com/android/settings/dream/GridSpacingItemDecoration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.dream;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.view.View;
+
+import androidx.annotation.DimenRes;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+/**
+ * RecyclerView item decorator to be used with {@link GridLayoutManager} for applying padding to
+ * only the inner elements of the grid.
+ */
+public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
+ private final int mSpacing;
+ private final boolean mRtl;
+
+ public GridSpacingItemDecoration(Context context, @DimenRes int spacingId) {
+ mSpacing = context.getResources().getDimensionPixelSize(spacingId);
+ mRtl = context.getResources().getConfiguration().getLayoutDirection()
+ == View.LAYOUT_DIRECTION_RTL;
+ }
+
+ @Override
+ public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
+ RecyclerView.State state) {
+ final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
+
+ if (!(layoutManager instanceof GridLayoutManager)) {
+ return;
+ }
+
+ final int spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
+ final int position = parent.getChildAdapterPosition(view);
+ final int column = position % spanCount;
+
+ final int startPadding = column * mSpacing / spanCount;
+ final int endPadding = mSpacing - (column + 1) * mSpacing / spanCount;
+
+ outRect.left = mRtl ? endPadding : startPadding;
+ outRect.right = mRtl ? startPadding : endPadding;
+ if (position >= spanCount) {
+ outRect.top = mSpacing;
+ }
+ }
+}
diff --git a/src/com/android/settings/dream/IDreamItem.java b/src/com/android/settings/dream/IDreamItem.java
index 6652857..c462fe2 100644
--- a/src/com/android/settings/dream/IDreamItem.java
+++ b/src/com/android/settings/dream/IDreamItem.java
@@ -18,7 +18,10 @@
import android.graphics.drawable.Drawable;
-interface IDreamItem {
+/**
+ * Interface representing a dream item to be displayed.
+ */
+public interface IDreamItem {
CharSequence getTitle();
Drawable getIcon();
diff --git a/packages/apps/Settings/src/com/android/settings/dream/OWNERS b/src/com/android/settings/dream/OWNERS
similarity index 100%
rename from packages/apps/Settings/src/com/android/settings/dream/OWNERS
rename to src/com/android/settings/dream/OWNERS
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 815f2fd..8dbce79 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -36,6 +36,7 @@
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.SparseArray;
+import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
@@ -64,6 +65,7 @@
*/
public class BatteryAppListPreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnDestroy {
+ private static final String TAG = "BatteryAppListPreferenceController";
@VisibleForTesting
static final boolean USE_FAKE_DATA = false;
private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 20;
@@ -103,9 +105,14 @@
PowerProfile powerProfile = new PowerProfile(context);
// Cheap hack to try to figure out if the power_profile.xml was populated.
- return powerProfile.getAveragePowerForOrdinal(
- PowerProfile.POWER_GROUP_DISPLAY_SCREEN_FULL, 0)
- >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP;
+ final double averagePowerForOrdinal = powerProfile.getAveragePowerForOrdinal(
+ PowerProfile.POWER_GROUP_DISPLAY_SCREEN_FULL, 0);
+ final boolean shouldShowBatteryAttributionList =
+ averagePowerForOrdinal >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP;
+ if (!shouldShowBatteryAttributionList) {
+ Log.w(TAG, "shouldShowBatteryAttributionList(): " + averagePowerForOrdinal);
+ }
+ return shouldShowBatteryAttributionList;
}
};
diff --git a/src/com/android/settings/gestures/OneHandedSettings.java b/src/com/android/settings/gestures/OneHandedSettings.java
index 3825896..0e6b402 100644
--- a/src/com/android/settings/gestures/OneHandedSettings.java
+++ b/src/com/android/settings/gestures/OneHandedSettings.java
@@ -26,6 +26,7 @@
import com.android.internal.accessibility.AccessibilityShortcutController;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
+import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import com.android.settings.accessibility.ShortcutPreference;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.widget.IllustrationPreference;
@@ -64,7 +65,7 @@
mainSwitchPreference.addOnSwitchChangeListener((switchView, isChecked) -> {
switchView.setChecked(isChecked);
if (isChecked) {
- showQuickSettingsTooltipIfNeeded();
+ showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_DIRECT_USE);
}
});
}
diff --git a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java
index e3379c7..75406f7 100644
--- a/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationAccessSeeAllPreferenceController.java
@@ -27,7 +27,9 @@
import com.android.settings.R;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.applications.RecentAppOpsAccess;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.widget.AppPreference;
import java.util.ArrayList;
@@ -37,8 +39,10 @@
public class RecentLocationAccessSeeAllPreferenceController
extends LocationBasePreferenceController {
- private PreferenceScreen mCategoryAllRecentLocationAccess;
private final RecentAppOpsAccess mRecentLocationAccesses;
+
+ private PreferenceScreen mCategoryAllRecentLocationAccess;
+ private MetricsFeatureProvider mMetricsFeatureProvider;
private boolean mShowSystem = false;
private Preference mPreference;
@@ -47,6 +51,7 @@
mShowSystem = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1;
mRecentLocationAccesses = RecentAppOpsAccess.createForLocation(context);
+ mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
@Override
@@ -99,6 +104,7 @@
mShowSystem = showSystem;
if (mPreference != null) {
updateState(mPreference);
+ mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory());
}
}
}
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
index 442af38..5c7c54e 100644
--- a/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
+++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java
@@ -97,23 +97,19 @@
public PrivateDnsModeDialogPreference(Context context) {
super(context);
- initialize();
}
public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- initialize();
}
public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- initialize();
}
public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- initialize();
}
private final AnnotationSpan.LinkInfo mUrlLinkInfo = new AnnotationSpan.LinkInfo(
@@ -131,12 +127,6 @@
}
});
- private void initialize() {
- // Add the "Restricted" icon resource so that if the preference is disabled by the
- // admin, an information button will be shown.
- setWidgetLayoutResource(R.layout.restricted_icon);
- }
-
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
@@ -146,13 +136,6 @@
// by the controller.
holder.itemView.setEnabled(true);
}
-
- final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
- if (restrictedIcon != null) {
- // Show the "Restricted" icon if, and only if, the preference was disabled by
- // the admin.
- restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
- }
}
@Override
diff --git a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
index c6d1ea0..0b39d6a 100644
--- a/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
+++ b/src/com/android/settings/network/SwitchToEuiccSubscriptionSidecar.java
@@ -21,14 +21,13 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.UiccCardInfo;
-import android.telephony.UiccSlotMapping;
import android.telephony.euicc.EuiccManager;
import android.util.Log;
import com.android.settings.SidecarFragment;
import com.android.settings.network.telephony.EuiccOperationSidecar;
-import java.util.Collection;
+import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@@ -95,11 +94,11 @@
// To check whether the esim slot's port is active. If yes, skip setSlotMapping. If no,
// set this slot+port into setSimSlotMapping.
- mPort = (port < 0) ? getTargetPortId(removedSubInfo, targetSlot) : port;
+ mPort = (port < 0) ? getTargetPortId(removedSubInfo) : port;
mRemovedSubInfo = removedSubInfo;
Log.d(TAG,
- String.format("set esim into the Slot%d SubId%d:Port%d",
- targetSlot, mSubId, mPort));
+ String.format("set esim into the SubId%d Slot%d:Port%d",
+ mSubId, targetSlot, mPort));
if (mTelephonyManager.isMultiSimEnabled() && removedSubInfo != null
&& removedSubInfo.isEmbedded()) {
@@ -115,7 +114,7 @@
}
}
- private int getTargetPortId(SubscriptionInfo removedSubInfo, int targetSlot) {
+ private int getTargetPortId(SubscriptionInfo removedSubInfo) {
if (!mTelephonyManager.isMultiSimEnabled() || !isMultipleEnabledProfilesSupported()) {
// In the 'SS mode' or 'DSDS+no MEP', the port is 0.
return 0;
@@ -128,20 +127,25 @@
}
// In DSDS+MEP mode, the removedSubInfo is psim or is null, it means this esim needs
- // another port in the esim slot.
- // To find another esim's port and value is from 0.
+ // a new corresponding port in the esim slot.
// For example:
// 1) If there is no enabled esim and the user add new esim. This new esim's port is 0.
- // 2) If there is one enabled esim and the user add new esim. This new esim's port is 1.
+ // 2) If there is one enabled esim in port0 and the user add new esim. This new esim's
+ // port is 1.
+ // 3) If there is one enabled esim in port1 and the user add new esim. This new esim's
+ // port is 0.
+
int port = 0;
- Collection<UiccSlotMapping> uiccSlotMappings = mTelephonyManager.getSimSlotMapping();
- for (UiccSlotMapping uiccSlotMapping :
- uiccSlotMappings.stream()
- .filter(
- uiccSlotMapping -> uiccSlotMapping.getPhysicalSlotIndex()
- == targetSlot)
- .collect(Collectors.toList())) {
- if (uiccSlotMapping.getPortIndex() == port) {
+ SubscriptionManager subscriptionManager = getContext().getSystemService(
+ SubscriptionManager.class);
+ List<SubscriptionInfo> activeEsimSubInfos =
+ SubscriptionUtil.getActiveSubscriptions(subscriptionManager)
+ .stream()
+ .filter(i -> i.isEmbedded())
+ .sorted(Comparator.comparingInt(SubscriptionInfo::getPortIndex))
+ .collect(Collectors.toList());
+ for (SubscriptionInfo subscriptionInfo : activeEsimSubInfos) {
+ if (subscriptionInfo.getPortIndex() == port) {
port++;
}
}
diff --git a/src/com/android/settings/nfc/PaymentBackend.java b/src/com/android/settings/nfc/PaymentBackend.java
index 0cfed20..021d673 100644
--- a/src/com/android/settings/nfc/PaymentBackend.java
+++ b/src/com/android/settings/nfc/PaymentBackend.java
@@ -133,7 +133,9 @@
appInfo.settingsComponent = null;
}
appInfo.description = service.getDescription();
- appInfo.icon = pm.getUserBadgedIcon(service.loadIcon(pm), appInfo.userHandle);
+ Drawable icon = (service.loadBanner(pm) != null)
+ ? service.loadBanner(pm) : service.loadIcon(pm);
+ appInfo.icon = pm.getUserBadgedIcon(icon, appInfo.userHandle);
appInfos.add(appInfo);
}
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index a888167..75746ce 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -58,7 +58,11 @@
ComponentName component = intent.getParcelableExtra(
CardEmulation.EXTRA_SERVICE_COMPONENT);
String category = intent.getStringExtra(CardEmulation.EXTRA_CATEGORY);
- int userId = intent.getIntExtra(CardEmulation.EXTRA_USERID, UserHandle.myUserId());
+ UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER);
+ if (userHandle == null) {
+ userHandle = UserHandle.CURRENT;
+ }
+ int userId = userHandle.getIdentifier();
setResult(RESULT_CANCELED);
if (!buildDialog(component, category, userId)) {
diff --git a/src/com/android/settings/notification/NotificationLockscreenPreference.java b/src/com/android/settings/notification/NotificationLockscreenPreference.java
deleted file mode 100644
index b236014..0000000
--- a/src/com/android/settings/notification/NotificationLockscreenPreference.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2016 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.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ListView;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AlertDialog.Builder;
-
-import com.android.settings.R;
-import com.android.settings.RestrictedListPreference;
-import com.android.settings.Utils;
-import com.android.settingslib.RestrictedLockUtils;
-
-public class NotificationLockscreenPreference extends RestrictedListPreference {
-
- private boolean mAllowRemoteInput;
- private Listener mListener;
- private boolean mShowRemoteInput;
- private boolean mRemoteInputCheckBoxEnabled = true;
- private int mUserId = UserHandle.myUserId();
- private RestrictedLockUtils.EnforcedAdmin mAdminRestrictingRemoteInput;
-
- public NotificationLockscreenPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void setRemoteInputCheckBoxEnabled(boolean enabled) {
- mRemoteInputCheckBoxEnabled = enabled;
- }
-
- public void setRemoteInputRestricted(RestrictedLockUtils.EnforcedAdmin admin) {
- mAdminRestrictingRemoteInput = admin;
- }
-
- @Override
- protected void onClick() {
- final Context context = getContext();
- if (!Utils.startQuietModeDialogIfNecessary(context, UserManager.get(context), mUserId)) {
- // Call super to create preference dialog only when work mode is on
- // startQuietModeDialogIfNecessary will return false if mUserId is not a managed user
- super.onClick();
- }
- }
-
- public void setUserId(int userId) {
- mUserId = userId;
- }
-
- @Override
- protected void onPrepareDialogBuilder(Builder builder,
- DialogInterface.OnClickListener innerListener) {
-
- mListener = new Listener(innerListener);
- builder.setSingleChoiceItems(createListAdapter(builder.getContext()), getSelectedValuePos(),
- mListener);
- mShowRemoteInput = getEntryValues().length == 3;
- mAllowRemoteInput = Settings.Secure.getInt(getContext().getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, 0) != 0;
- builder.setView(R.layout.lockscreen_remote_input);
- }
-
- @Override
- protected void onDialogCreated(Dialog dialog) {
- super.onDialogCreated(dialog);
- dialog.create();
- CheckBox checkbox = (CheckBox) dialog.findViewById(R.id.lockscreen_remote_input);
- checkbox.setChecked(!mAllowRemoteInput);
- checkbox.setOnCheckedChangeListener(mListener);
- checkbox.setEnabled(mAdminRestrictingRemoteInput == null);
-
- View restricted = dialog.findViewById(R.id.restricted_lock_icon_remote_input);
- restricted.setVisibility(mAdminRestrictingRemoteInput == null ? View.GONE : View.VISIBLE);
-
- if (mAdminRestrictingRemoteInput != null) {
- checkbox.setClickable(false);
- dialog.findViewById(com.android.internal.R.id.customPanel)
- .setOnClickListener(mListener);
- }
- }
-
- @Override
- protected void onDialogStateRestored(Dialog dialog, Bundle savedInstanceState) {
- super.onDialogStateRestored(dialog, savedInstanceState);
- ListView listView = ((AlertDialog) dialog).getListView();
- int selectedPosition = listView.getCheckedItemPosition();
-
- View panel = dialog.findViewById(com.android.internal.R.id.customPanel);
- panel.setVisibility(checkboxVisibilityForSelectedIndex(selectedPosition,
- mShowRemoteInput));
- mListener.setView(panel);
- }
-
- @Override
- protected void onDialogClosed(boolean positiveResult) {
- super.onDialogClosed(positiveResult);
- Settings.Secure.putInt(getContext().getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, mAllowRemoteInput ? 1 : 0);
- }
-
- @Override
- protected boolean isAutoClosePreference() {
- return false;
- }
-
- private int checkboxVisibilityForSelectedIndex(int selected,
- boolean showRemoteAtAll) {
- return selected == 1 && showRemoteAtAll && mRemoteInputCheckBoxEnabled ? View.VISIBLE
- : View.GONE;
- }
-
- private class Listener implements DialogInterface.OnClickListener,
- CompoundButton.OnCheckedChangeListener, View.OnClickListener {
-
- private final DialogInterface.OnClickListener mInner;
- private View mView;
-
- public Listener(DialogInterface.OnClickListener inner) {
- mInner = inner;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mInner.onClick(dialog, which);
- ListView listView = ((AlertDialog) dialog).getListView();
- int selectedPosition = listView.getCheckedItemPosition();
- if (mView != null) {
- mView.setVisibility(
- checkboxVisibilityForSelectedIndex(selectedPosition, mShowRemoteInput));
- }
- }
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- mAllowRemoteInput = !isChecked;
- }
-
- public void setView(View view) {
- mView = view;
- }
-
- @Override
- public void onClick(View v) {
- if (v.getId() == com.android.internal.R.id.customPanel) {
- RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
- mAdminRestrictingRemoteInput);
- }
- }
- }
-}
diff --git a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
index 55e8bba..0fd0c0d 100644
--- a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
+++ b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
@@ -33,15 +33,17 @@
return;
}
- ImmutableList<String> sourceIds =
- ImmutableList.copyOf(intent.getStringArrayExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS));
+ String[] sourceIdsExtra = intent.getStringArrayExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS);
+ if (sourceIdsExtra != null && sourceIdsExtra.length > 0) {
+ ImmutableList<String> sourceIds = ImmutableList.copyOf(sourceIdsExtra);
- if (sourceIds.contains(LockScreenSafetySource.SAFETY_SOURCE_ID)) {
- LockScreenSafetySource.sendSafetyData(context);
- }
+ if (sourceIds.contains(LockScreenSafetySource.SAFETY_SOURCE_ID)) {
+ LockScreenSafetySource.sendSafetyData(context);
+ }
- if (sourceIds.contains(BiometricsSafetySource.SAFETY_SOURCE_ID)) {
- BiometricsSafetySource.sendSafetyData(context);
+ if (sourceIds.contains(BiometricsSafetySource.SAFETY_SOURCE_ID)) {
+ BiometricsSafetySource.sendSafetyData(context);
+ }
}
}
}
diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
index 5439fef..4e54238 100644
--- a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
+++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
@@ -16,40 +16,32 @@
package com.android.settings.security;
-import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.storage.StorageManager;
import android.text.TextUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ChooseLockGeneric;
-import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.widget.GearPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.transition.SettingsTransitionHelper;
public class ChangeScreenLockPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, GearPreference.OnGearClickListener {
private static final String KEY_UNLOCK_SET_OR_CHANGE = "unlock_set_or_change";
- protected final DevicePolicyManager mDPM;
protected final SettingsPreferenceFragment mHost;
protected final UserManager mUm;
protected final LockPatternUtils mLockPatternUtils;
@@ -57,24 +49,26 @@
protected final int mUserId = UserHandle.myUserId();
protected final int mProfileChallengeUserId;
private final MetricsFeatureProvider mMetricsFeatureProvider;
+ private final ScreenLockPreferenceDetailsUtils mScreenLockPreferenceDetailUtils;
protected RestrictedPreference mPreference;
public ChangeScreenLockPreferenceController(Context context, SettingsPreferenceFragment host) {
super(context);
mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mHost = host;
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
+ mScreenLockPreferenceDetailUtils =
+ new ScreenLockPreferenceDetailsUtils(context, host.getMetricsCategory());
}
@Override
public boolean isAvailable() {
- return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change);
+ return mScreenLockPreferenceDetailUtils.isAvailable();
}
@Override
@@ -91,7 +85,7 @@
@Override
public void updateState(Preference preference) {
if (mPreference != null && mPreference instanceof GearPreference) {
- if (mLockPatternUtils.isSecure(mUserId)) {
+ if (mScreenLockPreferenceDetailUtils.shouldShowGearMenu()) {
((GearPreference) mPreference).setOnGearClickListener(this);
} else {
((GearPreference) mPreference).setOnGearClickListener(null);
@@ -112,10 +106,7 @@
if (TextUtils.equals(p.getKey(), getPreferenceKey())) {
mMetricsFeatureProvider.logClickedPreference(p,
p.getExtras().getInt(DashboardFragment.CATEGORY));
- new SubSettingLauncher(mContext)
- .setDestination(ScreenLockSettings.class.getName())
- .setSourceMetricsCategory(mHost.getMetricsCategory())
- .launch();
+ mScreenLockPreferenceDetailUtils.openScreenLockSettings();
}
}
@@ -124,51 +115,11 @@
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return super.handlePreferenceTreeClick(preference);
}
- // TODO(b/35930129): Remove once existing password can be passed into vold directly.
- // Currently we need this logic to ensure that the QUIET_MODE is off for any work
- // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
- // able to complete the operation due to the lack of (old) encryption key.
- if (mProfileChallengeUserId != UserHandle.USER_NULL
- && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
- && StorageManager.isFileEncryptedNativeOnly()) {
- if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
- return false;
- }
- }
-
- new SubSettingLauncher(mContext)
- .setDestination(ChooseLockGeneric.ChooseLockGenericFragment.class.getName())
- .setSourceMetricsCategory(mHost.getMetricsCategory())
- .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
- .launch();
- return true;
+ return mScreenLockPreferenceDetailUtils.openChooseLockGenericFragment();
}
protected void updateSummary(Preference preference, int userId) {
- if (!mLockPatternUtils.isSecure(userId)) {
- if (userId == mProfileChallengeUserId
- || mLockPatternUtils.isLockScreenDisabled(userId)) {
- preference.setSummary(R.string.unlock_set_unlock_mode_off);
- } else {
- preference.setSummary(R.string.unlock_set_unlock_mode_none);
- }
- } else {
- switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(userId)) {
- case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
- preference.setSummary(R.string.unlock_set_unlock_mode_pattern);
- break;
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
- preference.setSummary(R.string.unlock_set_unlock_mode_pin);
- break;
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
- case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
- preference.setSummary(R.string.unlock_set_unlock_mode_password);
- break;
- }
- }
+ preference.setSummary(mScreenLockPreferenceDetailUtils.getSummary(userId));
mPreference.setEnabled(true);
}
@@ -181,10 +132,7 @@
void disableIfPasswordQualityManaged(int userId) {
final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtilsInternal
.checkIfPasswordQualityIsSet(mContext, userId);
- final DevicePolicyManager dpm = (DevicePolicyManager) mContext
- .getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (admin != null && dpm.getPasswordQuality(admin.component, userId)
- == DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
+ if (mScreenLockPreferenceDetailUtils.isPasswordQualityManaged(userId, admin)) {
mPreference.setDisabledByAdmin(admin);
}
}
diff --git a/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java b/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java
new file mode 100644
index 0000000..abcacf0
--- /dev/null
+++ b/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+
+import androidx.annotation.StringRes;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.transition.SettingsTransitionHelper;
+
+/**
+ * Utilities for screen lock details shared between Security Settings and Safety Center.
+ */
+public class ScreenLockPreferenceDetailsUtils {
+
+ private final int mUserId = UserHandle.myUserId();
+ private final Context mContext;
+ private final LockPatternUtils mLockPatternUtils;
+ private final int mProfileChallengeUserId;
+ private final UserManager mUm;
+ private final int mSourceMetricsCategory;
+
+ public ScreenLockPreferenceDetailsUtils(Context context, int sourceMetricsCategory) {
+ mContext = context;
+ mUm = context.getSystemService(UserManager.class);
+ mLockPatternUtils = FeatureFactory.getFactory(context)
+ .getSecurityFeatureProvider()
+ .getLockPatternUtils(context);
+ mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
+ mSourceMetricsCategory = sourceMetricsCategory;
+ }
+
+ /**
+ * Returns whether the screen lock settings entity should be shown.
+ */
+ public boolean isAvailable() {
+ return mContext.getResources().getBoolean(R.bool.config_show_unlock_set_or_change);
+ }
+
+ /**
+ * Returns the summary of screen lock settings entity.
+ */
+ public String getSummary(int userId) {
+ final Integer summaryResId = getSummaryResId(userId);
+ return summaryResId != null ? mContext.getResources().getString(summaryResId) : null;
+ }
+
+ /**
+ * Returns whether the password quality is managed by device admin.
+ */
+ public boolean isPasswordQualityManaged(int userId, RestrictedLockUtils.EnforcedAdmin admin) {
+ final DevicePolicyManager dpm = (DevicePolicyManager) mContext
+ .getSystemService(Context.DEVICE_POLICY_SERVICE);
+ return admin != null && dpm.getPasswordQuality(admin.component, userId)
+ == DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
+ }
+
+ /**
+ * Returns whether the Gear Menu should be shown.
+ */
+ public boolean shouldShowGearMenu() {
+ return mLockPatternUtils.isSecure(mUserId);
+ }
+
+ /**
+ * Launches the {@link ScreenLockSettings}.
+ */
+ public void openScreenLockSettings() {
+ new SubSettingLauncher(mContext)
+ .setDestination(ScreenLockSettings.class.getName())
+ .setSourceMetricsCategory(mSourceMetricsCategory)
+ .launch();
+ }
+
+ /**
+ * Tries to launch the {@link ChooseLockGenericFragment} if Quiet Mode is not enabled
+ * for managed profile, otherwise shows a dialog to disable the Quiet Mode.
+ *
+ * @return true if the {@link ChooseLockGenericFragment} is launching.
+ */
+ public boolean openChooseLockGenericFragment() {
+ // TODO(b/35930129): Remove once existing password can be passed into vold directly.
+ // Currently we need this logic to ensure that the QUIET_MODE is off for any work
+ // profile with unified challenge on FBE-enabled devices. Otherwise, vold would not be
+ // able to complete the operation due to the lack of (old) encryption key.
+ if (mProfileChallengeUserId != UserHandle.USER_NULL
+ && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mProfileChallengeUserId)
+ && StorageManager.isFileEncryptedNativeOnly()) {
+ if (Utils.startQuietModeDialogIfNecessary(mContext, mUm, mProfileChallengeUserId)) {
+ return false;
+ }
+ }
+
+ new SubSettingLauncher(mContext)
+ .setDestination(ChooseLockGenericFragment.class.getName())
+ .setSourceMetricsCategory(mSourceMetricsCategory)
+ .setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
+ .launch();
+ return true;
+ }
+
+ @StringRes
+ private Integer getSummaryResId(int userId) {
+ if (!mLockPatternUtils.isSecure(userId)) {
+ if (userId == mProfileChallengeUserId
+ || mLockPatternUtils.isLockScreenDisabled(userId)) {
+ return R.string.unlock_set_unlock_mode_off;
+ } else {
+ return R.string.unlock_set_unlock_mode_none;
+ }
+ } else {
+ int keyguardStoredPasswordQuality =
+ mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);
+ switch (keyguardStoredPasswordQuality) {
+ case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
+ return R.string.unlock_set_unlock_mode_pattern;
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
+ return R.string.unlock_set_unlock_mode_pin;
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+ case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
+ return R.string.unlock_set_unlock_mode_password;
+ default:
+ return null;
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/widget/RestrictedAppPreference.java b/src/com/android/settings/widget/RestrictedAppPreference.java
index cd95357..f93b935 100644
--- a/src/com/android/settings/widget/RestrictedAppPreference.java
+++ b/src/com/android/settings/widget/RestrictedAppPreference.java
@@ -20,12 +20,10 @@
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.view.View;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
-import com.android.settings.R;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper;
import com.android.settingslib.widget.AppPreference;
@@ -55,7 +53,6 @@
}
private void initialize(AttributeSet attrs, String userRestriction) {
- setWidgetLayoutResource(R.layout.restricted_icon);
mHelper = new RestrictedPreferenceHelper(getContext(), this, attrs);
this.userRestriction = userRestriction;
}
@@ -64,10 +61,6 @@
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
- final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
- if (restrictedIcon != null) {
- restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
- }
}
@Override
diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
index dd0c20a..6f26826 100644
--- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
+++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java
@@ -100,7 +100,6 @@
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- setIfOnlyAvailableForAdmins(true);
mIsUiRestricted = isUiRestricted();
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java
index be67977..3fec81a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java
@@ -53,6 +53,7 @@
private PopupWindow.OnDismissListener mMockOnDismissListener;
private static final String TEST_PACKAGE_NAME = "com.test.package";
+ private static final int TEST_RES_ID = 1234;
private final Context mContext = ApplicationProvider.getApplicationContext();
private AccessibilityQuickSettingsTooltipWindow mTooltipView;
private View mView;
@@ -66,8 +67,8 @@
@Test
public void initTooltipView_atMostAvailableTextWidth() {
final String quickSettingsTooltipsContent = mContext.getString(
- R.string.accessibility_service_quick_settings_tooltips_content, TEST_PACKAGE_NAME);
- mTooltipView.setup(quickSettingsTooltipsContent);
+ R.string.accessibility_service_qs_tooltips_content, TEST_PACKAGE_NAME);
+ mTooltipView.setup(quickSettingsTooltipsContent, TEST_RES_ID);
final int getMaxWidth = mTooltipView.getAvailableWindowWidth();
assertThat(mTooltipView.getWidth()).isAtMost(getMaxWidth);
@@ -75,7 +76,7 @@
@Test
public void showTooltipView_success() {
- mTooltipView.setup(TEST_PACKAGE_NAME);
+ mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
assertThat(getLatestPopupWindow()).isNull();
mTooltipView.showAtTopCenter(mView);
@@ -85,7 +86,7 @@
@Test
public void accessibilityClickActionOnTooltipViewShown_shouldInvokeCallbackAndNotShowing() {
- mTooltipView.setup(TEST_PACKAGE_NAME);
+ mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
mTooltipView.setOnDismissListener(mMockOnDismissListener);
mTooltipView.showAtTopCenter(mView);
@@ -101,7 +102,7 @@
@Test
public void dismiss_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
- mTooltipView.setup(TEST_PACKAGE_NAME);
+ mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID);
mTooltipView.setOnDismissListener(mMockOnDismissListener);
mTooltipView.showAtTopCenter(mView);
@@ -113,7 +114,7 @@
@Test
public void waitAutoCloseDelayTime_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
- mTooltipView.setup(TEST_PACKAGE_NAME, /* closeDelayTimeMillis= */ 1);
+ mTooltipView.setup(TEST_PACKAGE_NAME, TEST_RES_ID, /* closeDelayTimeMillis= */ 1);
mTooltipView.setOnDismissListener(mMockOnDismissListener);
mTooltipView.showAtTopCenter(mView);
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
index ea0f317..d05600a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragmentTest.java
@@ -18,6 +18,7 @@
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_QS_TOOLTIP_RESHOW;
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE;
+import static com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType;
import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import static com.google.common.truth.Truth.assertThat;
@@ -204,7 +205,7 @@
@Config(shadows = ShadowFragment.class)
public void restoreValueFromSavedInstanceState_showTooltipView() {
mContext.setTheme(R.style.Theme_AppCompat);
- mFragment.showQuickSettingsTooltipIfNeeded();
+ mFragment.showQuickSettingsTooltipIfNeeded(QuickSettingsTooltipType.GUIDE_TO_EDIT);
assertThat(getLatestPopupWindow().isShowing()).isTrue();
final Bundle savedInstanceState = new Bundle();
diff --git a/tests/robotests/src/com/android/settings/accessibility/CaptionAppearancePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/CaptionAppearancePreferenceControllerTest.java
new file mode 100644
index 0000000..cfa683ba
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/CaptionAppearancePreferenceControllerTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.view.accessibility.CaptioningManager;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowCaptioningManager;
+
+/** Tests for {@link CaptionAppearancePreferenceController}. */
+@RunWith(RobolectricTestRunner.class)
+public class CaptionAppearancePreferenceControllerTest {
+
+ private static final String TEST_KEY = "test_key";
+ private static final int DEFAULT_PRESET_INDEX = 1;
+ private static final int DEFAULT_FONT_SCALE_INDEX = 2;
+
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private CaptionAppearancePreferenceController mController;
+ private ShadowCaptioningManager mShadowCaptioningManager;
+
+ @Before
+ public void setUp() {
+ CaptioningManager captioningManager = mContext.getSystemService(CaptioningManager.class);
+ mShadowCaptioningManager = Shadow.extract(captioningManager);
+ mController = new CaptionAppearancePreferenceController(mContext, TEST_KEY);
+ }
+
+ @Test
+ public void getAvailabilityStatus_shouldReturnAvailable() {
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void getSummary_noScale_shouldReturnDefaultSummary() {
+ final String expectedSummary =
+ getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, DEFAULT_PRESET_INDEX);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_smallestScale_shouldReturnExpectedSummary() {
+ mShadowCaptioningManager.setFontScale(0.25f);
+
+ final String expectedSummary =
+ getSummaryCombo(/* fontScaleIndex= */ 0, DEFAULT_PRESET_INDEX);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_smallScale_shouldReturnExpectedSummary() {
+ mShadowCaptioningManager.setFontScale(0.5f);
+
+ final String expectedSummary =
+ getSummaryCombo(/* fontScaleIndex= */ 1, DEFAULT_PRESET_INDEX);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_mediumScale_shouldReturnExpectedSummary() {
+ mShadowCaptioningManager.setFontScale(1.0f);
+
+ final String expectedSummary =
+ getSummaryCombo(/* fontScaleIndex= */ 2, DEFAULT_PRESET_INDEX);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_largeScale_shouldReturnExpectedSummary() {
+ mShadowCaptioningManager.setFontScale(1.5f);
+
+ final String expectedSummary =
+ getSummaryCombo(/* fontScaleIndex= */ 3, DEFAULT_PRESET_INDEX);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_largestScale_shouldReturnExpectedSummary() {
+ mShadowCaptioningManager.setFontScale(2.0f);
+
+ final String expectedSummary =
+ getSummaryCombo(/* fontScaleIndex= */ 4, DEFAULT_PRESET_INDEX);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_setByAppPreset_shouldReturnExpectedSummary() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 4);
+
+ final String expectedSummary =
+ getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 0);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_whiteOnBlackPreset_shouldReturnExpectedSummary() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 0);
+
+ final String expectedSummary =
+ getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 1);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_blackOnWhitePreset_shouldReturnExpectedSummary() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 1);
+
+ final String expectedSummary =
+ getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 2);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_yellowOnBlackPreset_shouldReturnExpectedSummary() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 2);
+
+ final String expectedSummary =
+ getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 3);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_yellowOnBluePreset_shouldReturnExpectedSummary() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, 3);
+
+ final String expectedSummary =
+ getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 4);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ @Test
+ public void getSummary_customPreset_shouldReturnExpectedSummary() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, -1);
+
+ final String expectedSummary =
+ getSummaryCombo(DEFAULT_FONT_SCALE_INDEX, /* presetIndex= */ 5);
+ assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary);
+ }
+
+ private String getSummaryCombo(int fontScaleIndex, int presetIndex) {
+ final String[] fontScaleArray = mContext.getResources().getStringArray(
+ R.array.captioning_font_size_selector_titles);
+ final String[] presetArray = mContext.getResources().getStringArray(
+ R.array.captioning_preset_selector_titles);
+ return mContext.getString(R.string.preference_summary_default_combination,
+ fontScaleArray[fontScaleIndex], presetArray[presetIndex]);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java
similarity index 89%
rename from tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
rename to tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java
index 96756ecd..0bb227e 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextAndDisplayFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ColorAndMotionFragmentTest.java
@@ -32,17 +32,17 @@
import java.util.List;
@RunWith(RobolectricTestRunner.class)
-public class TextAndDisplayFragmentTest {
+public class ColorAndMotionFragmentTest {
private Context mContext = ApplicationProvider.getApplicationContext();
@Test
public void getNonIndexableKeys_existInXmlLayout() {
- final List<String> niks = TextAndDisplayFragment.SEARCH_INDEX_DATA_PROVIDER
+ final List<String> niks = ColorAndMotionFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
- R.xml.accessibility_text_and_display);
+ R.xml.accessibility_color_and_motion);
assertThat(keys).containsAtLeastElementsIn(niks);
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java
index ef8f569..f908b8a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/LockScreenRotationPreferenceControllerTest.java
@@ -26,6 +26,7 @@
import com.android.internal.view.RotationPolicy;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowRotationPolicy;
import org.junit.Before;
@@ -50,7 +51,10 @@
}
@Test
- @Config(shadows = {ShadowRotationPolicy.class})
+ @Config(shadows = {
+ ShadowRotationPolicy.class,
+ ShadowDeviceStateRotationLockSettingsManager.class
+ })
public void getAvailabilityStatus_supportedRotation_shouldReturnAvailable() {
ShadowRotationPolicy.setRotationSupported(true /* supported */);
@@ -59,8 +63,23 @@
}
@Test
- @Config(shadows = {ShadowRotationPolicy.class})
- public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
+ @Config(shadows = {
+ ShadowRotationPolicy.class,
+ ShadowDeviceStateRotationLockSettingsManager.class
+ })
+ public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
+ ShadowRotationPolicy.setRotationSupported(true /* supported */);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ @Config(shadows = {
+ ShadowRotationPolicy.class,
+ ShadowDeviceStateRotationLockSettingsManager.class
+ }) public void getAvailabilityStatus_unsupportedRotation_shouldReturnUnsupportedOnDevice() {
ShadowRotationPolicy.setRotationSupported(false /* supported */);
assertThat(mController.getAvailabilityStatus()).isEqualTo(
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
index 5ea4edc..34a2f5b 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
@@ -51,6 +51,7 @@
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import com.android.settings.testutils.shadow.ShadowFragment;
+import com.android.settingslib.widget.TopIntroPreference;
import org.junit.Before;
import org.junit.Test;
@@ -81,6 +82,7 @@
private static final String PLACEHOLDER_DIALOG_TITLE = "title";
private static final String DEFAULT_SUMMARY = "default summary";
private static final String DEFAULT_DESCRIPTION = "default description";
+ private static final String DEFAULT_TOP_INTRO = "default top intro";
private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
@@ -294,6 +296,23 @@
}
@Test
+ public void initTopIntroPreference_hasTopIntroTitle_shouldSetAsExpectedValue() {
+ mFragment.mTopIntroTitle = DEFAULT_TOP_INTRO;
+ mFragment.initTopIntroPreference();
+
+ TopIntroPreference topIntroPreference =
+ (TopIntroPreference) mFragment.getPreferenceScreen().getPreference(/* index= */ 0);
+ assertThat(topIntroPreference.getTitle().toString()).isEqualTo(DEFAULT_TOP_INTRO);
+ }
+
+ @Test
+ public void initTopIntroPreference_topIntroTitleIsNull_shouldNotAdded() {
+ mFragment.initTopIntroPreference();
+
+ assertThat(mFragment.getPreferenceScreen().getPreferenceCount()).isEqualTo(0);
+ }
+
+ @Test
public void createFooterPreference_shouldSetAsExpectedValue() {
mFragment.createFooterPreference(mFragment.getPreferenceScreen(),
DEFAULT_SUMMARY, DEFAULT_DESCRIPTION);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
index 31687c6..6087ef2 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java
@@ -99,6 +99,7 @@
mController.mBluetoothAdapter = mBluetoothAdapter;
when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mCachedDevice.getAddress()).thenReturn(MAC_ADDRESS);
+ when(mCachedDevice.getIdentityAddress()).thenReturn(MAC_ADDRESS);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
index 6401388..6ecbf2e 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsControllerTestBase.java
@@ -155,6 +155,7 @@
mDevice = mBluetoothAdapter.getRemoteDevice(config.getAddress());
when(mCachedDevice.getDevice()).thenReturn(mDevice);
when(mCachedDevice.getAddress()).thenReturn(config.getAddress());
+ when(mCachedDevice.getIdentityAddress()).thenReturn(config.getAddress());
}
/**
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
index ce41a8d..fac8b58 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDeviceDetailsFragmentTest.java
@@ -89,6 +89,7 @@
when(fragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
+ when(mCachedDevice.getIdentityAddress()).thenReturn(TEST_ADDRESS);
Bundle args = new Bundle();
args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, TEST_ADDRESS);
mFragment.setArguments(args);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
index ea841fa..bac868f 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothPairingDetailTest.java
@@ -305,6 +305,7 @@
when(cachedDevice.isConnected()).thenReturn(true);
when(cachedDevice.getDevice()).thenReturn(device2);
when(cachedDevice.getAddress()).thenReturn(TEST_DEVICE_ADDRESS_B);
+ when(cachedDevice.getIdentityAddress()).thenReturn(TEST_DEVICE_ADDRESS_B);
mFragment.onProfileConnectionStateChanged(cachedDevice, BluetoothProfile.A2DP,
BluetoothAdapter.STATE_CONNECTED);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
index 5c23238..9c266c1 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java
@@ -73,6 +73,7 @@
FakeFeatureFactory.setupForTest();
String deviceAddress = "55:66:77:88:99:AA";
when(mCachedDevice.getAddress()).thenReturn(deviceAddress);
+ when(mCachedDevice.getIdentityAddress()).thenReturn(deviceAddress);
when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice);
when(mCachedDevice.getName()).thenReturn(DEVICE_NAME);
mFragment = spy(ForgetDeviceDialogFragment.newInstance(deviceAddress));
diff --git a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
index c8467b2..ad5b70c 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/RemoteDeviceNameDialogFragmentTest.java
@@ -62,6 +62,7 @@
String deviceAddress = "55:66:77:88:99:AA";
when(mCachedDevice.getAddress()).thenReturn(deviceAddress);
+ when(mCachedDevice.getIdentityAddress()).thenReturn(deviceAddress);
mFragment = spy(RemoteDeviceNameDialogFragment.newInstance(mCachedDevice));
doReturn(mCachedDevice).when(mFragment).getDevice(any());
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
index fd1c8ff..aa5f980 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -144,6 +144,21 @@
}
@Test
+ public void useAll_returnsAllControllersOfType() {
+ final TestPreferenceController controller1 = new TestPreferenceController(mContext);
+ final TestPreferenceController controller2 = new TestPreferenceController(mContext);
+ final SubTestPreferenceController controller3 = new SubTestPreferenceController(mContext);
+ mTestFragment.addPreferenceController(controller1);
+ mTestFragment.addPreferenceController(controller2);
+ mTestFragment.addPreferenceController(controller3);
+
+ final List<TestPreferenceController> retrievedControllers = mTestFragment.useAll(
+ TestPreferenceController.class);
+
+ assertThat(retrievedControllers).containsExactly(controller1, controller2);
+ }
+
+ @Test
public void displayTilesAsPreference_shouldAddTilesWithIntent() {
when(mFakeFeatureFactory.dashboardFeatureProvider
.getTilesForCategory(nullable(String.class)))
@@ -360,6 +375,13 @@
}
}
+ public static class SubTestPreferenceController extends TestPreferenceController {
+
+ private SubTestPreferenceController(Context context) {
+ super(context);
+ }
+ }
+
private static class TestFragment extends DashboardFragment {
private final PreferenceManager mPreferenceManager;
diff --git a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
index 1d175de..54e6b99 100644
--- a/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AutoRotatePreferenceControllerTest.java
@@ -30,6 +30,7 @@
import androidx.preference.SwitchPreference;
+import com.android.internal.R;
import com.android.internal.view.RotationPolicy;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -64,6 +65,7 @@
mPreference = new SwitchPreference(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ disableDeviceStateRotation();
mController = new AutoRotatePreferenceController(mContext, "auto_rotate");
}
@@ -112,6 +114,26 @@
}
@Test
+ public void getAvailabilityStatus_deviceRotationDisabled_returnsAvailable() {
+ enableAutoRotationPreference();
+ disableDeviceStateRotation();
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_deviceRotationEnabled_returnsUnsupported() {
+ enableAutoRotationPreference();
+ enableDeviceStateRotation();
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
public void testIsCheck() {
assertThat(mController.isChecked()).isFalse();
@@ -180,4 +202,15 @@
Settings.System.putIntForUser(mContentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT);
}
+
+ private void enableDeviceStateRotation() {
+ when(mContext.getResources().getStringArray(
+ R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+ new String[]{"0:0", "1:1", "2:2"});
+ }
+
+ private void disableDeviceStateRotation() {
+ when(mContext.getResources().getStringArray(
+ R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(new String[]{});
+ }
}
diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java
new file mode 100644
index 0000000..b773657
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateDetailsFragmentTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.res.Resources;
+
+import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class DeviceStateAutoRotateDetailsFragmentTest {
+
+ private final DeviceStateAutoRotateDetailsFragment mFragment =
+ spy(new DeviceStateAutoRotateDetailsFragment());
+ private final Context mContext = spy(RuntimeEnvironment.application);
+ private final Resources mResources = spy(mContext.getResources());
+
+ @Before
+ public void setUp() throws Exception {
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getApplicationContext()).thenReturn(mContext);
+ when(mFragment.getContext()).thenReturn(mContext);
+ when(mFragment.getResources()).thenReturn(mResources);
+ }
+
+ @Test
+ public void getMetricsCategory_returnsAutoRotateSettings() {
+ assertThat(mFragment.getMetricsCategory()).isEqualTo(
+ SettingsEnums.DISPLAY_AUTO_ROTATE_SETTINGS);
+ }
+
+ @Test
+ public void getPreferenceScreenResId_returnsDeviceStateAutoRotationSettings() {
+ assertThat(mFragment.getPreferenceScreenResId()).isEqualTo(
+ R.xml.device_state_auto_rotate_settings);
+ }
+
+ @Test
+ public void createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers() {
+ enableDeviceStateSettableRotationStates(new String[]{"0:1", "1:1"},
+ new String[]{"Folded", "Unfolded"});
+
+ List<AbstractPreferenceController> preferenceControllers =
+ mFragment.createPreferenceControllers(mContext);
+
+ assertThat(preferenceControllers).hasSize(2);
+ assertThat(preferenceControllers.get(0)).isInstanceOf(
+ DeviceStateAutoRotateSettingController.class);
+ assertThat(preferenceControllers.get(1)).isInstanceOf(
+ DeviceStateAutoRotateSettingController.class);
+ }
+
+ @Test
+ public void createPreferenceControllers_noSettableDeviceStates_returnsEmptyList() {
+ enableDeviceStateSettableRotationStates(new String[]{}, new String[]{});
+
+ List<AbstractPreferenceController> preferenceControllers =
+ mFragment.createPreferenceControllers(mContext);
+
+ assertThat(preferenceControllers).isEmpty();
+ }
+
+ private void enableDeviceStateSettableRotationStates(String[] settableStates,
+ String[] settableStatesDescriptions) {
+ when(mResources.getStringArray(
+ com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+ settableStates);
+ when(mResources.getStringArray(
+ R.array.config_settableAutoRotationDeviceStatesDescriptions)).thenReturn(
+ settableStatesDescriptions);
+ DeviceStateRotationLockSettingsManager.resetInstance();
+ DeviceStateRotationLockSettingsManager.getInstance(mContext)
+ .resetStateForTesting(mResources);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java
new file mode 100644
index 0000000..a5416e7
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateOverviewControllerTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {ShadowRotationPolicy.class, ShadowDeviceStateRotationLockSettingsManager.class})
+public class DeviceStateAutoRotateOverviewControllerTest {
+
+ private final DeviceStateAutoRotateOverviewController mController =
+ new DeviceStateAutoRotateOverviewController(
+ RuntimeEnvironment.application, "device_state_auto_rotate");
+
+ @Test
+ public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
+ ShadowRotationPolicy.setRotationSupported(true);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_rotationNotSupported_returnsUnsupportedOnDevice() {
+ ShadowRotationPolicy.setRotationSupported(false);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_deviceStateRotationNotSupported_returnsUnsupportedOnDevice() {
+ ShadowRotationPolicy.setRotationSupported(true);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java
new file mode 100644
index 0000000..28a071a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/DeviceStateAutoRotateSettingControllerTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.display;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+import com.android.settingslib.search.SearchIndexableRaw;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+ ShadowRotationPolicy.class,
+ ShadowDeviceStateRotationLockSettingsManager.class
+})
+public class DeviceStateAutoRotateSettingControllerTest {
+
+ private static final int DEFAULT_DEVICE_STATE = 1;
+ private static final String DEFAULT_DEVICE_STATE_DESCRIPTION = "Device state description";
+ private static final int DEFAULT_ORDER = -10;
+
+ private final Context mContext = RuntimeEnvironment.application;
+ private final DeviceStateAutoRotateSettingController mController =
+ new DeviceStateAutoRotateSettingController(mContext, DEFAULT_DEVICE_STATE,
+ DEFAULT_DEVICE_STATE_DESCRIPTION, DEFAULT_ORDER);
+ private final DeviceStateRotationLockSettingsManager mAutoRotateSettingsManager =
+ DeviceStateRotationLockSettingsManager.getInstance(mContext);
+
+ @Test
+ public void displayPreference_addsPreferenceToPreferenceScreen() {
+ PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+
+ mController.displayPreference(screen);
+
+ assertThat(screen.getPreferenceCount()).isEqualTo(1);
+ Preference preference = screen.getPreference(0);
+ assertThat(preference.getTitle().toString()).isEqualTo(DEFAULT_DEVICE_STATE_DESCRIPTION);
+ assertThat(preference.getOrder()).isEqualTo(DEFAULT_ORDER);
+ assertThat(preference.getKey()).isEqualTo(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void getAvailabilityStatus_rotationAndDeviceStateRotationEnabled_returnsAvailable() {
+ ShadowRotationPolicy.setRotationSupported(true);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_deviceStateRotationDisabled_returnsUnsupported() {
+ ShadowRotationPolicy.setRotationSupported(true);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_rotationDisabled_returnsUnsupported() {
+ ShadowRotationPolicy.setRotationSupported(false);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+ int availability = mController.getAvailabilityStatus();
+
+ assertThat(availability).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getPreferenceKey_returnsKeyBasedOnDeviceState() {
+ String key = mController.getPreferenceKey();
+
+ String expectedKey = "auto_rotate_device_state_" + DEFAULT_DEVICE_STATE;
+ assertThat(key).isEqualTo(expectedKey);
+ }
+
+ @Test
+ public void isChecked_settingForStateIsUnlocked_returnsTrue() {
+ mAutoRotateSettingsManager.updateSetting(DEFAULT_DEVICE_STATE, /* rotationLocked= */ false);
+
+ assertThat(mController.isChecked()).isTrue();
+ }
+
+ @Test
+ public void isChecked_settingForStateIsLocked_returnsFalse() {
+ mAutoRotateSettingsManager.updateSetting(DEFAULT_DEVICE_STATE, /* rotationLocked= */ true);
+
+ assertThat(mController.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setChecked_true_deviceStateSettingIsUnlocked() {
+ mController.setChecked(true);
+
+ boolean rotationLocked = mAutoRotateSettingsManager.isRotationLocked(DEFAULT_DEVICE_STATE);
+
+ assertThat(rotationLocked).isFalse();
+ }
+
+ @Test
+ public void setChecked_false_deviceStateSettingIsLocked() {
+ mController.setChecked(false);
+
+ boolean rotationLocked = mAutoRotateSettingsManager.isRotationLocked(DEFAULT_DEVICE_STATE);
+
+ assertThat(rotationLocked).isTrue();
+ }
+
+ @Test
+ public void updateRawDataToIndex_addsItemToList() {
+ List<SearchIndexableRaw> rawData = new ArrayList<>();
+
+ mController.updateRawDataToIndex(rawData);
+
+ assertThat(rawData).hasSize(1);
+ SearchIndexableRaw item = rawData.get(0);
+ assertThat(item.key).isEqualTo(mController.getPreferenceKey());
+ assertThat(item.title).isEqualTo(DEFAULT_DEVICE_STATE_DESCRIPTION);
+ assertThat(item.screenTitle).isEqualTo(mContext.getString(R.string.accelerometer_title));
+ }
+
+ @Test
+ public void getSliceHighlightMenuRes_returnsMenuKeyDisplay() {
+ int sliceHighlightMenuRes = mController.getSliceHighlightMenuRes();
+
+ assertThat(sliceHighlightMenuRes).isEqualTo(R.string.menu_key_display);
+ }
+
+ @Test
+ public void isSliceable_returnsTrue() {
+ assertThat(mController.isSliceable()).isTrue();
+ }
+
+ @Test
+ public void isPublicSlice_returnsTrue() {
+ assertThat(mController.isPublicSlice()).isTrue();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
index 778721a..4fec38b 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotateControllerTest.java
@@ -39,7 +39,10 @@
import androidx.preference.Preference;
import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import org.junit.Before;
import org.junit.Test;
@@ -63,6 +66,8 @@
@Mock
private Preference mPreference;
private ContentResolver mContentResolver;
+ private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager =
+ DeviceStateRotationLockSettingsManager.getInstance(RuntimeEnvironment.application);
@Before
public void setUp() {
@@ -122,6 +127,34 @@
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
}
+ @Test
+ @Config(shadows = {
+ ShadowDeviceStateRotationLockSettingsManager.class,
+ ShadowRotationPolicy.class
+ })
+ public void getAvailabilityStatus_deviceStateRotationLocked_returnDisableDependentSetting() {
+ enableDeviceStateRotation();
+ lockDeviceStateRotation();
+
+ int availabilityStatus = mController.getAvailabilityStatus();
+
+ assertThat(availabilityStatus).isEqualTo(DISABLED_DEPENDENT_SETTING);
+ }
+
+ @Test
+ @Config(shadows = {
+ ShadowDeviceStateRotationLockSettingsManager.class,
+ ShadowRotationPolicy.class
+ })
+ public void getAvailabilityStatus_deviceStateRotationUnlocked_returnAvailable() {
+ enableDeviceStateRotation();
+ unlockDeviceStateRotation();
+
+ int availabilityStatus = mController.getAvailabilityStatus();
+
+ assertThat(availabilityStatus).isEqualTo(AVAILABLE);
+ }
+
private void enableAutoRotation() {
Settings.System.putIntForUser(mContentResolver,
Settings.System.ACCELEROMETER_ROTATION, 1, UserHandle.USER_CURRENT);
@@ -131,4 +164,23 @@
Settings.System.putIntForUser(mContentResolver,
Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT);
}
+
+ private void enableDeviceStateRotation() {
+ ShadowRotationPolicy.setRotationSupported(true);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+ }
+
+ private void lockDeviceStateRotation() {
+ mDeviceStateAutoRotateSettingsManager.updateSetting(
+ /* deviceState= */0, /* rotationLocked= */ true);
+ mDeviceStateAutoRotateSettingsManager.updateSetting(
+ /* deviceState= */1, /* rotationLocked= */ true);
+ }
+
+ private void unlockDeviceStateRotation() {
+ mDeviceStateAutoRotateSettingsManager.updateSetting(
+ /* deviceState= */0, /* rotationLocked= */ false);
+ mDeviceStateAutoRotateSettingsManager.updateSetting(
+ /* deviceState= */1, /* rotationLocked= */ true);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
index 068de34..39fdb04 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
@@ -40,6 +40,7 @@
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
import org.junit.Before;
@@ -53,7 +54,10 @@
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = ShadowSensorPrivacyManager.class)
+@Config(shadows = {
+ ShadowSensorPrivacyManager.class,
+ ShadowDeviceStateRotationLockSettingsManager.class
+})
public class SmartAutoRotatePreferenceControllerTest {
private static final String PACKAGE_NAME = "package_name";
@@ -95,6 +99,7 @@
new SmartAutoRotatePreferenceController(mContext, "smart_auto_rotate"));
when(mController.isCameraLocked()).thenReturn(false);
when(mController.isPowerSaveMode()).thenReturn(false);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
}
@Test
@@ -199,6 +204,16 @@
.UNSUPPORTED_ON_DEVICE);
}
+
+ @Test
+ public void getAvailabilityStatus_deviceStateRotationEnabled_returnsUnsupported() {
+ enableAutoRotationPreference();
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(
+ BasePreferenceController.UNSUPPORTED_ON_DEVICE);
+ }
+
@Test
public void isSliceableCorrectKey_returnsTrue() {
final AutoRotatePreferenceController controller =
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java
index 877d2c1..942fed6 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceFragmentTest.java
@@ -18,6 +18,8 @@
import static com.android.settings.display.SmartAutoRotatePreferenceFragment.AUTO_ROTATE_SWITCH_PREFERENCE_ID;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -33,6 +35,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
import android.view.View;
import androidx.preference.Preference;
@@ -40,7 +43,11 @@
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowDeviceStateRotationLockSettingsManager;
+import com.android.settings.testutils.shadow.ShadowRotationPolicy;
import com.android.settings.widget.SettingsMainSwitchBar;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
import org.junit.Before;
import org.junit.Test;
@@ -49,8 +56,15 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = {
+ ShadowDeviceStateRotationLockSettingsManager.class,
+ ShadowRotationPolicy.class
+})
public class SmartAutoRotatePreferenceFragmentTest {
private static final String PACKAGE_NAME = "package_name";
@@ -70,19 +84,24 @@
@Mock
private Preference mRotateSwitchPreference;
+ private Resources mResources;
+ private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- final Context context = spy(RuntimeEnvironment.application);
+ mContext = spy(RuntimeEnvironment.application);
ContentResolver mContentResolver = RuntimeEnvironment.application.getContentResolver();
- when(context.getPackageManager()).thenReturn(mPackageManager);
- when(context.getContentResolver()).thenReturn(mContentResolver);
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName();
doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
Manifest.permission.CAMERA, PACKAGE_NAME);
+ mResources = spy(mContext.getResources());
+ when(mContext.getResources()).thenReturn(mResources);
+
final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
resolveInfo.serviceInfo = new ServiceInfo();
when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo);
@@ -90,15 +109,16 @@
mFragment = spy(new SmartAutoRotatePreferenceFragment());
when(mActivity.getPackageManager()).thenReturn(mPackageManager);
when(mFragment.getActivity()).thenReturn(mActivity);
- when(mFragment.getContext()).thenReturn(context);
+ when(mFragment.getContext()).thenReturn(mContext);
doReturn(mView).when(mFragment).getView();
when(mFragment.findPreference(AUTO_ROTATE_SWITCH_PREFERENCE_ID)).thenReturn(
mRotateSwitchPreference);
- mSwitchBar = spy(new SettingsMainSwitchBar(context));
+ mSwitchBar = spy(new SettingsMainSwitchBar(mContext));
when(mActivity.getSwitchBar()).thenReturn(mSwitchBar);
doReturn(mSwitchBar).when(mView).findViewById(R.id.switch_bar);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(false);
}
@@ -111,6 +131,17 @@
}
@Test
+ public void createHeader_deviceStateRotationSupported_switchBarIsDisabled() {
+ ShadowRotationPolicy.setRotationSupported(true);
+ ShadowDeviceStateRotationLockSettingsManager.setDeviceStateRotationLockEnabled(true);
+
+ mFragment.createHeader(mActivity);
+
+ verify(mSwitchBar, never()).show();
+ verify(mRotateSwitchPreference, never()).setVisible(false);
+ }
+
+ @Test
public void createHeader_faceDetectionUnSupported_switchBarIsDisabled() {
doReturn(null).when(mPackageManager).getRotationResolverPackageName();
@@ -120,4 +151,41 @@
verify(mRotateSwitchPreference, never()).setVisible(false);
}
+ @Test
+ public void createPreferenceControllers_noSettableDeviceStates_returnsEmptyList() {
+ enableDeviceStateSettableRotationStates(new String[]{}, new String[]{});
+
+ List<AbstractPreferenceController> preferenceControllers =
+ mFragment.createPreferenceControllers(mContext);
+
+ assertThat(preferenceControllers).isEmpty();
+ }
+
+ @Test
+ public void createPreferenceControllers_settableDeviceStates_returnsDeviceStateControllers() {
+ enableDeviceStateSettableRotationStates(new String[]{"0:1", "1:1"},
+ new String[]{"Folded", "Unfolded"});
+
+ List<AbstractPreferenceController> preferenceControllers =
+ mFragment.createPreferenceControllers(mContext);
+
+ assertThat(preferenceControllers).hasSize(2);
+ assertThat(preferenceControllers.get(0)).isInstanceOf(
+ DeviceStateAutoRotateSettingController.class);
+ assertThat(preferenceControllers.get(1)).isInstanceOf(
+ DeviceStateAutoRotateSettingController.class);
+ }
+
+ private void enableDeviceStateSettableRotationStates(String[] settableStates,
+ String[] settableStatesDescriptions) {
+ when(mResources.getStringArray(
+ com.android.internal.R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+ settableStates);
+ when(mResources.getStringArray(
+ R.array.config_settableAutoRotationDeviceStatesDescriptions)).thenReturn(
+ settableStatesDescriptions);
+ DeviceStateRotationLockSettingsManager.resetInstance();
+ DeviceStateRotationLockSettingsManager.getInstance(mContext)
+ .resetStateForTesting(mResources);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java b/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java
index 043fc55..401ffe0 100644
--- a/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java
+++ b/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java
@@ -19,12 +19,9 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.ComponentName;
import android.content.Context;
-import android.widget.Button;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
@@ -93,19 +90,4 @@
RecyclerView view = mPreference.findViewById(R.id.dream_list);
assertThat(view.getAdapter().getItemCount()).isEqualTo(1);
}
-
- @Test
- public void testPreviewButton() {
- final DreamInfo mockDreamInfo = new DreamInfo();
- mockDreamInfo.componentName = new ComponentName("package", "class");
- mockDreamInfo.isActive = true;
-
- when(mBackend.getDreamInfos()).thenReturn(Collections.singletonList(mockDreamInfo));
- final DreamPickerController controller = buildController();
- controller.updateState(mPreference);
-
- Button view = mPreference.findViewById(R.id.preview_button);
- view.performClick();
- verify(mBackend).preview(mockDreamInfo);
- }
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
index e63dd80..64dbbb2 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
@@ -24,20 +24,26 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
+import android.app.Activity;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
import android.net.Uri;
+import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.SliceProvider;
import androidx.slice.widget.SliceLiveData;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+import com.android.settings.R;
import com.android.settings.slices.CustomSliceRegistry;
-import com.android.settings.wifi.slice.ContextualWifiSlice;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -48,6 +54,7 @@
private Context mContext;
private EligibleCardChecker mEligibleCardChecker;
+ private Activity mActivity;
@Before
public void setUp() {
@@ -55,22 +62,19 @@
mEligibleCardChecker =
spy(new EligibleCardChecker(mContext, getContextualCard(TEST_SLICE_URI)));
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ mActivity = Robolectric.buildActivity(Activity.class).create().get();
}
@Test
- @Ignore
public void isSliceToggleable_cardWithToggle_returnTrue() {
- final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
- final Slice slice = wifiSlice.getSlice();
+ final Slice slice = buildSlice();
assertThat(mEligibleCardChecker.isSliceToggleable(slice)).isTrue();
}
@Test
- @Ignore
public void isCardEligibleToDisplay_toggleSlice_hasInlineActionShouldBeTrue() {
- final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
- final Slice slice = wifiSlice.getSlice();
+ final Slice slice = buildSlice();
doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
@@ -118,10 +122,8 @@
}
@Test
- @Ignore
public void isCardEligibleToDisplay_sliceNotNull_cacheSliceToCard() {
- final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
- final Slice slice = wifiSlice.getSlice();
+ final Slice slice = buildSlice();
doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
@@ -137,4 +139,23 @@
.setSliceUri(sliceUri)
.build();
}
+
+ private Slice buildSlice() {
+ final String title = "test_title";
+ final IconCompat icon = IconCompat.createWithResource(mActivity, R.drawable.empty_icon);
+ final PendingIntent pendingIntent = PendingIntent.getActivity(
+ mActivity,
+ title.hashCode() /* requestCode */,
+ new Intent("test action"),
+ PendingIntent.FLAG_IMMUTABLE);
+ final SliceAction action
+ = SliceAction.createDeeplink(pendingIntent, icon, ListBuilder.SMALL_IMAGE, title);
+ return new ListBuilder(mActivity, TEST_SLICE_URI, ListBuilder.INFINITY)
+ .addRow(new ListBuilder.RowBuilder()
+ .addEndItem(icon, ListBuilder.ICON_IMAGE)
+ .setTitle(title)
+ .setPrimaryAction(action))
+ .addAction(SliceAction.createToggle(pendingIntent, null /* actionTitle */, true))
+ .build();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
index fc6481b..dcf086c 100644
--- a/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
+++ b/tests/robotests/src/com/android/settings/network/MobileNetworkSummaryControllerTest.java
@@ -44,6 +44,8 @@
import androidx.preference.PreferenceScreen;
import com.android.settings.Settings.MobileNetworkActivity;
+import com.android.settings.network.helper.SubscriptionAnnotation;
+import com.android.settings.network.helper.SubscriptionGrouping;
import com.android.settings.widget.AddPreference;
import com.android.settingslib.RestrictedLockUtils;
@@ -123,7 +125,6 @@
@Test
- @Ignore
public void getSummary_noSubscriptions_correctSummaryAndClickHandler() {
mController.displayPreference(mPreferenceScreen);
mController.onResume();
@@ -212,23 +213,6 @@
}
@Test
- @Ignore
- public void getSummary_providerModel_Enabled() {
- final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
- final SubscriptionInfo sub2 = mock(SubscriptionInfo.class);
- when(sub1.getSubscriptionId()).thenReturn(1);
- when(sub2.getSubscriptionId()).thenReturn(2);
- when(sub1.getDisplayName()).thenReturn("sub1");
- when(sub2.getDisplayName()).thenReturn("sub2");
-
- SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1, sub2));
- SubscriptionUtil.setActiveSubscriptionsForTesting(Arrays.asList(sub1, sub2));
- mController.displayPreference(mPreferenceScreen);
- mController.onResume();
- assertThat(mController.getSummary()).isEqualTo("sub1, sub2");
- }
-
- @Test
public void addButton_noSubscriptionsNoEuiccMgr_noAddClickListener() {
when(mEuiccManager.isEnabled()).thenReturn(false);
mController.displayPreference(mPreferenceScreen);
@@ -319,7 +303,6 @@
}
@Test
- @Ignore
public void onAirplaneModeChanged_oneSubscriptionAirplaneModeGetsTurnedOn_isDisabled() {
final SubscriptionInfo sub1 = mock(SubscriptionInfo.class);
SubscriptionUtil.setAvailableSubscriptionsForTesting(Arrays.asList(sub1));
diff --git a/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
index bf9606d..60df553 100644
--- a/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/ChangeScreenLockPreferenceControllerTest.java
@@ -21,6 +21,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -35,6 +36,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settings.widget.GearPreference;
@@ -54,6 +56,8 @@
@Ignore
public class ChangeScreenLockPreferenceControllerTest {
+ private static final int METRICS_CATEGORY = 1;
+
@Mock
private LockPatternUtils mLockPatternUtils;
@Mock
@@ -80,7 +84,9 @@
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
.thenReturn(mDevicePolicyManager);
- mController = new ChangeScreenLockPreferenceController(mContext, null /* Host */ );
+ final SettingsPreferenceFragment host = mock(SettingsPreferenceFragment.class);
+ when(host.getMetricsCategory()).thenReturn(METRICS_CATEGORY);
+ mController = new ChangeScreenLockPreferenceController(mContext, host);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java
new file mode 100644
index 0000000..72df3cc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDeviceStateRotationLockSettingsManager.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.testutils.shadow;
+
+import android.content.Context;
+
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(DeviceStateRotationLockSettingsManager.class)
+public class ShadowDeviceStateRotationLockSettingsManager {
+
+ private static boolean sDeviceStateRotationLockEnabled;
+
+ @Implementation
+ public static boolean isDeviceStateRotationLockEnabled(Context context) {
+ return sDeviceStateRotationLockEnabled;
+ }
+
+ public static void setDeviceStateRotationLockEnabled(boolean enabled) {
+ sDeviceStateRotationLockEnabled = enabled;
+ }
+}
diff --git a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
index ed4c127..0f9d54b 100644
--- a/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
+++ b/tests/unit/src/com/android/settings/applications/appinfo/AppLocaleDetailsTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.LocaleManager;
@@ -32,7 +33,7 @@
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import com.google.common.collect.Iterables;
+import com.android.settingslib.widget.RadioButtonPreference;
import org.junit.Before;
import org.junit.Test;
@@ -40,8 +41,14 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Locale;
+/**
+ * Unittest for ApplocaleDetails
+ * TODO Need to add a unittest for the UI preference component.
+ */
@RunWith(AndroidJUnit4.class)
public class AppLocaleDetailsTest {
private static final String APP_PACKAGE_NAME = "app_package_name";
@@ -52,7 +59,7 @@
private LocaleManager mLocaleManager;
private Context mContext;
- private LocaleList mSystemLocales;
+ private Collection<Locale> mSystemLocales;
private LocaleList mAppLocale;
private String[] mAssetLocales;
private LocaleList mPackageLocales;
@@ -69,12 +76,48 @@
when(mContext.getSystemService(LocaleManager.class)).thenReturn(mLocaleManager);
setupInitialLocales(
- /* appLocale= */ "en",
+ /* appLocale= */ "en-gb",
/* simCountry= */ "tw",
/* networkCountry= */ "jp",
- /* systemLocales= */ "en, uk, jp, ne",
- /* packageLocales= */ "pa, cn, tw, en",
- /* assetLocales= */ new String[]{"en", "ne", "ms", "pa"});
+ /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+ /* packageLocales= */ "pa, cn, zh-tw, en-gb, ja-jp",
+ /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"});
+ }
+
+ @Test
+ @UiThreadTest
+ public void onRadioButtonClicked_setCurrentLocaleToSystem() {
+ AppLocaleDetails appLocaleDetails = new AppLocaleDetails() {
+ @Override
+ void refreshUiInternal() {}
+ };
+ DummyAppLocaleDetailsHelper helper =
+ spy(new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME));
+ appLocaleDetails.mAppLocaleDetailsHelper = helper;
+ RadioButtonPreference pref = new RadioButtonPreference(mContext);
+ pref.setKey(AppLocaleDetails.KEY_SYSTEM_DEFAULT_LOCALE);
+
+ appLocaleDetails.onRadioButtonClicked(pref);
+
+ verify(helper).setAppDefaultLocale(LocaleList.forLanguageTags(""));
+ }
+
+ @Test
+ @UiThreadTest
+ public void onRadioButtonClicked_setCurrentLocaleForUserSelected() {
+ AppLocaleDetails appLocaleDetails = new AppLocaleDetails() {
+ @Override
+ void refreshUiInternal() {}
+ };
+ DummyAppLocaleDetailsHelper helper =
+ spy(new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME));
+ appLocaleDetails.mAppLocaleDetailsHelper = helper;
+ RadioButtonPreference pref = new RadioButtonPreference(mContext);
+ pref.setKey("en");
+
+ appLocaleDetails.onRadioButtonClicked(pref);
+
+ verify(helper).setAppDefaultLocale("en");
}
@Test
@@ -90,7 +133,7 @@
@Test
@UiThreadTest
- public void handleAllLocalesData_1stLocaleOfSuggestedLocaleListIsAppLocale() {
+ public void handleAllLocalesData_1stLocaleIsAppLocaleAndHasSimAndNetwork() {
Locale simCountryLocale = new Locale("zh", "TW");
Locale networkCountryLocale = new Locale("ja", "JP");
DummyAppLocaleDetailsHelper helper =
@@ -98,36 +141,122 @@
helper.handleAllLocalesData();
- Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ Locale locale = suggestedLocales.iterator().next();
assertTrue(locale.equals(mAppLocale.get(0)));
- assertTrue(helper.getSuggestedLocales().contains(simCountryLocale));
- assertTrue(helper.getSuggestedLocales().contains(networkCountryLocale));
+ assertTrue(suggestedLocales.contains(simCountryLocale));
+ assertTrue(suggestedLocales.contains(networkCountryLocale));
}
@Test
@UiThreadTest
- public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsSimCountryLocale() {
- Locale simCountryLocale = new Locale("zh", "TW");
+ public void
+ handleAllLocalesData_noAppAndNoSupportedSimLocale_1stSuggestedLocaleIsAssetLocale() {
+ Locale firstAssetLocale = new Locale("en", "GB");
setupInitialLocales(
/* appLocale= */ "",
/* simCountry= */ "tw",
/* networkCountry= */ "",
- /* systemLocales= */ "en, uk, jp, ne",
+ /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
/* packageLocales= */ "",
- /* assetLocales= */ new String[]{});
+ /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp"});
DummyAppLocaleDetailsHelper helper =
new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
helper.handleAllLocalesData();
- Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
- assertTrue(locale.equals(simCountryLocale));
- assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0)));
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ Locale locale = suggestedLocales.iterator().next();
+ assertTrue(locale.equals(firstAssetLocale));
}
@Test
@UiThreadTest
- public void handleAllLocalesData_withoutAppLocale_1stSuggestedLocaleIsNetworkCountryLocale() {
+ public void handleAllLocalesData_noAppButHasSupportedSimLocale_1stSuggestedLocaleIsSim() {
+ Locale simLocale = new Locale("zh", "tw");
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "tw",
+ /* networkCountry= */ "",
+ /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+ /* packageLocales= */ "",
+ /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp", "zh-tw"});
+ DummyAppLocaleDetailsHelper helper =
+ new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+
+ helper.handleAllLocalesData();
+
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ Locale locale = suggestedLocales.iterator().next();
+ assertTrue(locale.equals(simLocale));
+ }
+
+ @Test
+ @UiThreadTest
+ public void
+ handleAllLocalesData_noAppButHasSupportedNetworkLocale_1stSuggestedLocaleIsNetwork() {
+ Locale networkLocale = new Locale("ja", "JP");
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "",
+ /* networkCountry= */ "jp",
+ /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+ /* packageLocales= */ "",
+ /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "ja-jp"});
+ DummyAppLocaleDetailsHelper helper =
+ new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+
+ helper.handleAllLocalesData();
+
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ Locale locale = suggestedLocales.iterator().next();
+ assertTrue(locale.equals(networkLocale));
+ }
+
+ @Test
+ @UiThreadTest
+ public void handleAllLocalesData_noAppSimOrNetworkLocale_suggestedLocalesHasSystemLocale() {
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "",
+ /* networkCountry= */ "",
+ /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+ /* packageLocales= */ "",
+ /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"});
+ DummyAppLocaleDetailsHelper helper =
+ new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+ helper.handleAllLocalesData();
+
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ assertTrue(suggestedLocales.contains(Locale.forLanguageTag("ne")));
+ // ru language is not present in the asset locales
+ assertFalse(suggestedLocales.contains(Locale.forLanguageTag("ru")));
+ }
+
+ @Test
+ @UiThreadTest
+ public void handleAllLocalesData_noAppButHasSimAndNetworkLocale_1stLocaleIsSimLocale() {
+ Locale simCountryLocale = new Locale("zh", "TW");
+ setupInitialLocales(
+ /* appLocale= */ "",
+ /* simCountry= */ "tw",
+ /* networkCountry= */ "jp",
+ /* systemLocales= */ "en-gb, ru, ja-jp, ne, zh-tw",
+ /* packageLocales= */ "",
+ /* assetLocales= */ new String[]{"en-gb", "ne", "ms", "pa", "zh-tw", "ja-jp"});
+
+ DummyAppLocaleDetailsHelper helper =
+ new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
+ helper.handleAllLocalesData();
+
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ Locale locale = suggestedLocales.iterator().next();
+ assertTrue(locale.equals(simCountryLocale));
+ }
+
+ @Test
+ @UiThreadTest
+ public void handleAllLocalesData_noSupportedLocale_noSuggestedLocales() {
Locale networkCountryLocale = new Locale("en", "GB");
setupInitialLocales(
/* appLocale= */ "",
@@ -141,28 +270,8 @@
helper.handleAllLocalesData();
- Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
- assertTrue(locale.equals(networkCountryLocale));
- assertFalse(helper.getSuggestedLocales().contains(mAppLocale.get(0)));
- }
-
- @Test
- @UiThreadTest
- public void handleAllLocalesData_noAppAndSimNetworkLocale_1stLocaleIsFirstOneInSystemLocales() {
- setupInitialLocales(
- /* appLocale= */ "",
- /* simCountry= */ "",
- /* networkCountry= */ "",
- /* systemLocales= */ "en, uk, jp, ne",
- /* packageLocales= */ "",
- /* assetLocales= */ new String[]{});
- DummyAppLocaleDetailsHelper helper =
- new DummyAppLocaleDetailsHelper(mContext, APP_PACKAGE_NAME);
-
- helper.handleAllLocalesData();
-
- Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
- assertTrue(locale.equals(mSystemLocales.get(0)));
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ assertTrue(suggestedLocales.size() == 0);
}
@Test
@@ -180,8 +289,10 @@
helper.handleAllLocalesData();
- Locale locale = Iterables.get(helper.getSuggestedLocales(), 0);
- assertTrue(locale.equals(mSystemLocales.get(0)));
+ Collection<Locale> suggestedLocales = helper.getSuggestedLocales();
+ Locale locale = suggestedLocales.iterator().next();
+ Locale systemLocale = mSystemLocales.iterator().next();
+ assertTrue(locale.equals(systemLocale));
}
@Test
@@ -248,15 +359,23 @@
String packageLocales,
String[] assetLocales) {
mAppLocale = LocaleList.forLanguageTags(appLocale);
- mSystemLocales = LocaleList.forLanguageTags(systemLocales);
+ // forLanguageTags does not filter space to the input string. If there is any space included
+ // in string, this will make locale fail to generate.
+ systemLocales = systemLocales.replaceAll("\\s+", "");
+ LocaleList listOfSystemLocales = LocaleList.forLanguageTags(systemLocales);
+ mSystemLocales = new ArrayList<>();
+ for (int i = 0; i < listOfSystemLocales.size(); i++) {
+ mSystemLocales.add(listOfSystemLocales.get(i));
+ }
mAssetLocales = assetLocales;
+ packageLocales = packageLocales.replaceAll("\\s+", "");
mPackageLocales = LocaleList.forLanguageTags(packageLocales);
when(mTelephonyManager.getSimCountryIso()).thenReturn(simCountry);
when(mTelephonyManager.getNetworkCountryIso()).thenReturn(networkCountry);
when(mLocaleManager.getApplicationLocales(anyString())).thenReturn(mAppLocale);
}
- private class DummyAppLocaleDetailsHelper
+ public class DummyAppLocaleDetailsHelper
extends AppLocaleDetails.AppLocaleDetailsHelper {
DummyAppLocaleDetailsHelper(Context context, String packageName) {
@@ -264,12 +383,12 @@
}
@Override
- String[] getAssetSystemLocales() {
+ String[] getAssetLocales() {
return mAssetLocales;
}
@Override
- LocaleList getCurrentSystemLocales() {
+ Collection<Locale> getCurrentSystemLocales() {
return mSystemLocales;
}
diff --git a/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
index 581286b..8806e50 100644
--- a/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
+++ b/tests/unit/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiverTest.java
@@ -80,6 +80,16 @@
}
@Test
+ public void sendSafetyData_whenSafetyCenterIsEnabled_withNullSourceIds_sendsNoData() {
+ when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
+ Intent intent = new Intent();
+
+ new SafetySourceBroadcastReceiver().onReceive(mApplicationContext, intent);
+
+ verify(mSafetyCenterManagerWrapper, never()).sendSafetyCenterUpdate(any(), any());
+ }
+
+ @Test
public void sendSafetyData_whenSafetyCenterIsEnabled_withNoSourceIds_sendsNoData() {
when(mSafetyCenterStatusHolder.isEnabled(mApplicationContext)).thenReturn(true);
Intent intent = new Intent().putExtra(EXTRA_REFRESH_SAFETY_SOURCE_IDS, new String[]{});
diff --git a/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java b/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java
new file mode 100644
index 0000000..3d13b48
--- /dev/null
+++ b/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.security;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.SettingsActivity;
+import com.android.settings.password.ChooseLockGeneric;
+import com.android.settings.security.screenlock.ScreenLockSettings;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.ResourcesUtils;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class ScreenLockPreferenceDetailsUtilsTest {
+
+ private static final int SOURCE_METRICS_CATEGORY = 10;
+ private static final int USER_ID = 11;
+
+ @Mock
+ private LockPatternUtils mLockPatternUtils;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private DevicePolicyManager mDevicePolicyManager;
+ @Mock
+ private Resources mResources;
+ @Mock
+ private StorageManager mStorageManager;
+
+ private Context mContext;
+
+ private ScreenLockPreferenceDetailsUtils mScreenLockPreferenceDetailsUtils;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mContext.getSystemService(StorageManager.class)).thenReturn(mStorageManager);
+ when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
+ .thenReturn(mDevicePolicyManager);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ doNothing().when(mContext).startActivity(any());
+ when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {});
+
+ final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
+ when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
+ .thenReturn(mLockPatternUtils);
+
+ mScreenLockPreferenceDetailsUtils =
+ new ScreenLockPreferenceDetailsUtils(mContext, SOURCE_METRICS_CATEGORY);
+ }
+
+ @Test
+ public void isAvailable_whenEnabled_shouldReturnTrue() {
+ whenConfigShowUnlockSetOrChangeIsEnabled(true);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_whenDisabled_shouldReturnFalse() {
+ whenConfigShowUnlockSetOrChangeIsEnabled(false);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.isAvailable()).isFalse();
+ }
+
+ @Test
+ public void getSummary_unsecureAndDisabledPattern_shouldReturnUnlockModeOff() {
+ final String summary = prepareString("unlock_set_unlock_mode_off", "unlockModeOff");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(false);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_unsecurePattern_shouldReturnUnlockModeNone() {
+ final String summary =
+ prepareString("unlock_set_unlock_mode_none", "unlockModeNone");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(false);
+ when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_passwordQualitySomething_shouldUnlockModePattern() {
+ final String summary =
+ prepareString("unlock_set_unlock_mode_pattern", "unlockModePattern");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_passwordQualityNumeric_shouldUnlockModePin() {
+ final String summary =
+ prepareString("unlock_set_unlock_mode_pin", "unlockModePin");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_passwordQualityNumericComplex_shouldUnlockModePin() {
+ final String summary = prepareString("unlock_set_unlock_mode_pin", "unlockModePin");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_passwordQualityAlphabetic_shouldUnlockModePassword() {
+ final String summary =
+ prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_passwordQualityAlphanumeric_shouldUnlockModePassword() {
+ final String summary =
+ prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_passwordQualityComplex_shouldUnlockModePassword() {
+ final String summary =
+ prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+ @Test
+ public void getSummary_passwordQualityManaged_shouldUnlockModePassword() {
+ final String summary =
+ prepareString("unlock_set_unlock_mode_password", "unlockModePassword");
+
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_MANAGED);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID)).isEqualTo(summary);
+ }
+
+
+ @Test
+ public void getSummary_unsupportedPasswordQuality_shouldReturnNull() {
+ when(mLockPatternUtils.isSecure(USER_ID)).thenReturn(true);
+ when(mLockPatternUtils.getKeyguardStoredPasswordQuality(USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+
+ assertNull(mScreenLockPreferenceDetailsUtils.getSummary(USER_ID));
+ }
+
+ @Test
+ public void isPasswordQualityManaged_withoutAdmin_shouldReturnFalse() {
+ final RestrictedLockUtils.EnforcedAdmin admin = null;
+
+ assertThat(mScreenLockPreferenceDetailsUtils.isPasswordQualityManaged(USER_ID, admin))
+ .isFalse();
+ }
+
+ @Test
+ public void isPasswordQualityManaged_passwordQualityIsManaged_shouldReturnTrue() {
+ final RestrictedLockUtils.EnforcedAdmin admin = new RestrictedLockUtils.EnforcedAdmin();
+
+ when(mDevicePolicyManager.getPasswordQuality(admin.component, USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_MANAGED);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.isPasswordQualityManaged(USER_ID, admin))
+ .isTrue();
+ }
+
+ @Test
+ public void isPasswordQualityManaged_passwordQualityIsNotManaged_shouldReturnFalse() {
+ final RestrictedLockUtils.EnforcedAdmin admin = new RestrictedLockUtils.EnforcedAdmin();
+
+ when(mDevicePolicyManager.getPasswordQuality(admin.component, USER_ID))
+ .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.isPasswordQualityManaged(USER_ID, admin))
+ .isFalse();
+ }
+
+ @Test
+ public void shouldShowGearMenu_patternIsSecure_shouldReturnTrue() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isTrue();
+ }
+
+ @Test
+ public void shouldShowGearMenu_patternIsNotSecure_shouldReturnFalse() {
+ when(mLockPatternUtils.isSecure(anyInt())).thenReturn(false);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).isFalse();
+ }
+
+ @Test
+ public void openScreenLockSettings_shouldSendIntent() {
+ mScreenLockPreferenceDetailsUtils.openScreenLockSettings();
+
+ assertFragmentLaunchRequested(ScreenLockSettings.class.getName());
+ }
+
+ @Test
+ public void openChooseLockGenericFragment_noQuietMode_shouldSendIntent_shouldReturnTrue() {
+ when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
+
+ assertThat(mScreenLockPreferenceDetailsUtils.openChooseLockGenericFragment()).isTrue();
+ assertFragmentLaunchRequested(ChooseLockGeneric.ChooseLockGenericFragment.class.getName());
+ }
+
+ private void whenConfigShowUnlockSetOrChangeIsEnabled(boolean enabled) {
+ final int resId = ResourcesUtils.getResourcesId(
+ ApplicationProvider.getApplicationContext(), "bool",
+ "config_show_unlock_set_or_change");
+ when(mResources.getBoolean(resId)).thenReturn(enabled);
+ }
+
+ private String prepareString(String stringResName, String string) {
+ final int stringResId = ResourcesUtils.getResourcesId(
+ ApplicationProvider.getApplicationContext(), "string", stringResName);
+ when(mResources.getString(stringResId)).thenReturn(string);
+ return string;
+ }
+
+ private void assertFragmentLaunchRequested(String fragmentClassName) {
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mContext).startActivity(intentCaptor.capture());
+
+ Intent intent = intentCaptor.getValue();
+ assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
+ .isEqualTo(fragmentClassName);
+ assertThat(intent.getIntExtra(
+ MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1 /* defaultValue */))
+ .isEqualTo(SOURCE_METRICS_CATEGORY);
+ }
+}