Merge "[Settings] Code refactor for modulization"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9c6b97a..8b8426d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1423,8 +1423,7 @@
<activity
android:name=".datausage.AppDataUsageActivity"
android:exported="true"
- android:noHistory="true"
- android:permission="android.permission.QUERY_ALL_PACKAGES">
+ android:noHistory="true">
<intent-filter android:priority="1">
<action android:name="android.settings.IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
@@ -1494,7 +1493,6 @@
<activity-alias android:name=".applications.InstalledAppDetails"
android:label="@string/application_info_label"
android:exported="true"
- android:permission="android.permission.QUERY_ALL_PACKAGES"
android:targetActivity=".applications.InstalledAppDetailsTop">
<intent-filter android:priority="1">
<action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" />
@@ -1506,8 +1504,7 @@
<activity android:name=".applications.InstalledAppOpenByDefaultActivity"
android:label="@string/application_info_label"
- android:exported="true"
- android:permission="android.permission.QUERY_ALL_PACKAGES">
+ android:exported="true">
<intent-filter android:priority="1">
<action android:name="android.settings.APP_OPEN_BY_DEFAULT_SETTINGS" />
<!-- Also catch legacy "com." prefixed action. -->
@@ -1864,8 +1861,7 @@
<activity
android:name="Settings$AppUsageAccessSettingsActivity"
android:exported="true"
- android:label="@string/usage_access_title"
- android:permission="android.permission.QUERY_ALL_PACKAGES">
+ android:label="@string/usage_access_title">
<intent-filter>
<action android:name="android.settings.USAGE_ACCESS_SETTINGS"/>
<category android:name="android.intent.category.DEFAULT"/>
@@ -2857,25 +2853,6 @@
android:value="@string/menu_key_accounts"/>
</activity>
- <activity android:name=".CryptKeeper"
- androidprv:systemUserOnly="true"
- android:immersive="true"
- android:launchMode="singleTop"
- android:excludeFromRecents="true"
- android:theme="@style/Theme.CryptKeeper"
- android:configChanges="mnc|mcc|keyboard|keyboardHidden|uiMode"
- android:windowSoftInputMode="adjustResize"
- android:screenOrientation="nosensor"
- android:taskAffinity="com.android.settings.CryptKeeper"
- android:exported="true"
- android:process=":CryptKeeper">
- <intent-filter android:priority="10">
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.HOME" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity>
-
<!-- Triggered when user-selected home app isn't encryption aware -->
<activity android:name=".FallbackHome"
android:excludeFromRecents="true"
@@ -2891,32 +2868,6 @@
</intent-filter>
</activity>
- <activity android:name=".CryptKeeper$FadeToBlack"
- android:immersive="true"
- android:launchMode="singleTop"
- android:theme="@style/CryptKeeperBlankTheme"
- />
-
- <activity android:name=".CryptKeeperConfirm$Blank"
- android:immersive="true"
- android:launchMode="singleTop"
- android:theme="@style/CryptKeeperBlankTheme"
- />
-
- <!-- Pseudo-activity used to provide an intent-filter entry point to encryption settings -->
- <activity android:name="Settings$CryptKeeperSettingsActivity"
- android:exported="true"
- android:label="@string/crypt_keeper_encrypt_title">
- <intent-filter android:priority="1">
- <action android:name="android.app.action.START_ENCRYPTION" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
- android:value="com.android.settings.security.CryptKeeperSettings" />
- <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
- android:value="@string/menu_key_security"/>
- </activity>
-
<activity
android:name="Settings$DataUsageSummaryActivity"
android:label="@string/data_usage_summary_title"
@@ -3980,7 +3931,7 @@
android:theme="@style/Transparent"
android:permission="android.permission.DUMP"
android:excludeFromRecents="true"
- android:enabled="@bool/config_has_help" />
+ android:enabled="@*android:bool/config_settingsHelpLinksEnabled" />
<activity android:name=".applications.autofill.AutofillPickerActivity"
android:excludeFromRecents="true"
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 38e3e20..559a589 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -21,6 +21,38 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <solid android:color="#BCEDDF"/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/accessibility_qs_tooltips_background.xml"
+ line="22"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <solid android:color="#BCEDDF"/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/accessibility_qs_tooltips_background.xml"
+ line="35"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:startColor="#4D000000""
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -85,22 +117,6 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" <color name="crypt_keeper_clock_background">#ff9a9a9a</color>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/values/colors.xml"
- line="20"
- column="5"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <color name="homepage_accessibility_background">#783BE5</color>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -117,22 +133,6 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" <color name="crypt_keeper_clock_foreground">#ff666666</color>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/values/colors.xml"
- line="21"
- column="5"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <color name="homepage_support_background">#3F5FBD</color>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -149,38 +149,6 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" <color name="crypt_keeper_clock_am_pm">#ff9a9a9a</color>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/values/colors.xml"
- line="22"
- column="5"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" <color name="crypt_keeper_password_background">#70606060</color>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/values/colors.xml"
- line="23"
- column="5"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" <color name="divider_color">#20ffffff</color>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -2149,86 +2117,6 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" android:textColor="#FFFFFF""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/layout/crypt_keeper_emergency_button.xml"
- line="35"
- column="9"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" android:background="@color/crypt_keeper_password_background">"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/layout/crypt_keeper_password_entry.xml"
- line="34"
- column="9"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" android:background="@color/lock_pattern_background" />"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/layout/crypt_keeper_pattern_field.xml"
- line="27"
- column="8"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" android:background="@color/crypt_keeper_password_background">"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/layout/crypt_keeper_pin_entry.xml"
- line="34"
- column="9"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" android:textColor="#B3FFFFFF""
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/layout/crypt_keeper_status.xml"
- line="55"
- column="9"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:tint="@color/face_enroll_icon_color">"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -2968,6 +2856,22 @@
errorLine1=" android:color="@color/accessibility_feature_background"/>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
+ file="res/drawable/ic_adaptive_font_download.xml"
+ line="23"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" android:color="@color/accessibility_feature_background"/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
file="res/drawable/ic_audio_adjustment.xml"
line="22"
column="13"/>
@@ -3221,22 +3125,6 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
- errorLine1=" android:color="@color/accessibility_feature_background"/>"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="res/drawable/ic_adaptive_font_download.xml"
- line="23"
- column="13"/>
- </issue>
-
- <issue
- id="HardCodedColor"
- severity="Error"
- message="Avoid using hardcoded color"
- category="Correctness"
- priority="4"
- summary="Using hardcoded color"
- explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:color="@color/homepage_about_background" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
@@ -4633,7 +4521,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rAU/strings.xml"
- line="3092"
+ line="3104"
column="64"/>
</issue>
@@ -4649,7 +4537,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rCA/strings.xml"
- line="3092"
+ line="3104"
column="64"/>
</issue>
@@ -4665,7 +4553,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rGB/strings.xml"
- line="3092"
+ line="3104"
column="64"/>
</issue>
@@ -4681,7 +4569,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rIN/strings.xml"
- line="3092"
+ line="3104"
column="64"/>
</issue>
@@ -4697,7 +4585,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values-en-rXC/strings.xml"
- line="3092"
+ line="3104"
column="170"/>
</issue>
@@ -4713,7 +4601,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~">
<location
file="res/values/strings.xml"
- line="7103"
+ line="7142"
column="36"/>
</issue>
@@ -4745,7 +4633,7 @@
errorLine2=" ^">
<location
file="res/values-night/themes.xml"
- line="37"
+ line="33"
column="41"/>
</issue>
@@ -4761,7 +4649,7 @@
errorLine2=" ^">
<location
file="res/values-night/themes.xml"
- line="37"
+ line="33"
column="41"/>
</issue>
@@ -4841,7 +4729,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="185"
+ line="192"
column="45"/>
</issue>
@@ -4857,7 +4745,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="186"
+ line="193"
column="49"/>
</issue>
@@ -4873,7 +4761,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="194"
+ line="201"
column="45"/>
</issue>
@@ -4889,7 +4777,7 @@
errorLine2=" ^">
<location
file="res/values/themes.xml"
- line="195"
+ line="202"
column="49"/>
</issue>
diff --git a/libs/window_ext_lib.aar b/libs/window_ext_lib.aar
index ca58b36..d34afbd 100644
--- a/libs/window_ext_lib.aar
+++ b/libs/window_ext_lib.aar
Binary files differ
diff --git a/res/drawable-hdpi/encroid_progress.png b/res/drawable-hdpi/encroid_progress.png
deleted file mode 100644
index f4fb961..0000000
--- a/res/drawable-hdpi/encroid_progress.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/encroid_waiting.png b/res/drawable-hdpi/encroid_waiting.png
deleted file mode 100644
index 1143cb7..0000000
--- a/res/drawable-hdpi/encroid_waiting.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/encroid_progress.png b/res/drawable-mdpi/encroid_progress.png
deleted file mode 100644
index e832c2a..0000000
--- a/res/drawable-mdpi/encroid_progress.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/encroid_waiting.png b/res/drawable-mdpi/encroid_waiting.png
deleted file mode 100644
index a9ac2f7..0000000
--- a/res/drawable-mdpi/encroid_waiting.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/encroid_progress.png b/res/drawable-xhdpi/encroid_progress.png
deleted file mode 100644
index ed9d10f..0000000
--- a/res/drawable-xhdpi/encroid_progress.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/encroid_waiting.png b/res/drawable-xhdpi/encroid_waiting.png
deleted file mode 100644
index aea5d57..0000000
--- a/res/drawable-xhdpi/encroid_waiting.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/accessibility_qs_tooltips_background.xml b/res/drawable/accessibility_qs_tooltips_background.xml
new file mode 100644
index 0000000..a704b2e
--- /dev/null
+++ b/res/drawable/accessibility_qs_tooltips_background.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+
+<layer-list
+ xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:top="8dp">
+ <shape
+ android:shape="rectangle">
+ <solid android:color="#BCEDDF"/>
+ <corners android:radius="28dp" />
+ <padding android:top="8dp" />
+ </shape>
+ </item>
+
+ <item
+ android:width="12dp"
+ android:height="12dp"
+ android:gravity="top|center_horizontal"
+ android:top="-6dp">
+ <rotate android:fromDegrees="45">
+ <shape android:shape="rectangle">
+ <solid android:color="#BCEDDF"/>
+ </shape>
+ </rotate>
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/accessibility_qs_tooltips_illustration.xml b/res/drawable/accessibility_qs_tooltips_illustration.xml
new file mode 100644
index 0000000..64245f1
--- /dev/null
+++ b/res/drawable/accessibility_qs_tooltips_illustration.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="181dp"
+ android:height="86dp"
+ android:viewportWidth="181"
+ android:viewportHeight="86">
+ <group>
+ <clip-path
+ android:pathData="M0,0h181v86h-181z"/>
+ <path
+ android:pathData="M17.388,4.007L162.381,4.007A13,13 0,0 1,175.381 17.007L175.381,323.989A13,13 0,0 1,162.381 336.989L17.388,336.989A13,13 0,0 1,4.388 323.989L4.388,17.007A13,13 0,0 1,17.388 4.007z"
+ android:strokeWidth="6"
+ android:fillColor="#ffffff"
+ android:strokeColor="#EDEDED"/>
+ </group>
+ <path
+ android:pathData="M21.548,23.014L158.221,23.014A3.078,3.078 0,0 1,161.299 26.092L161.299,26.092A3.078,3.078 0,0 1,158.221 29.17L21.548,29.17A3.078,3.078 0,0 1,18.469 26.092L18.469,26.092A3.078,3.078 0,0 1,21.548 23.014z"
+ android:fillColor="#EDEDED"/>
+ <path
+ android:pathData="M24.469,43.946L78.959,43.946A6,6 0,0 1,84.959 49.946L84.959,68.728A6,6 0,0 1,78.959 74.728L24.469,74.728A6,6 0,0 1,18.469 68.728L18.469,49.946A6,6 0,0 1,24.469 43.946z"
+ android:fillColor="#EDEDED"/>
+ <path
+ android:pathData="M100.81,43.946L155.299,43.946A6,6 0,0 1,161.299 49.946L161.299,68.728A6,6 0,0 1,155.299 74.728L100.81,74.728A6,6 0,0 1,94.81 68.728L94.81,49.946A6,6 0,0 1,100.81 43.946z"
+ android:fillColor="#E0DCDC"/>
+ <path
+ android:pathData="M100.81,43.946L155.299,43.946A6,6 0,0 1,161.299 49.946L161.299,68.728A6,6 0,0 1,155.299 74.728L100.81,74.728A6,6 0,0 1,94.81 68.728L94.81,49.946A6,6 0,0 1,100.81 43.946z"
+ android:fillColor="#797272"/>
+ <path
+ android:pathData="M104.197,55.027L110.047,55.027A2,2 0,0 1,112.047 57.027L112.047,62.878A2,2 0,0 1,110.047 64.878L104.197,64.878A2,2 0,0 1,102.197 62.878L102.197,57.027A2,2 0,0 1,104.197 55.027z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M117.588,53.796L139.751,53.796A1.847,1.847 0,0 1,141.598 55.643L141.598,55.643A1.847,1.847 0,0 1,139.751 57.49L117.588,57.49A1.847,1.847 0,0 1,115.741 55.643L115.741,55.643A1.847,1.847 0,0 1,117.588 53.796z"
+ android:fillColor="#ffffff"/>
+ <path
+ android:pathData="M117.588,62.415L152.064,62.415A1.847,1.847 0,0 1,153.911 64.262L153.911,64.262A1.847,1.847 0,0 1,152.064 66.109L117.588,66.109A1.847,1.847 0,0 1,115.741 64.262L115.741,64.262A1.847,1.847 0,0 1,117.588 62.415z"
+ android:fillColor="#C8C5C5"/>
+</vector>
diff --git a/res/layout-land/crypt_keeper_progress.xml b/res/layout-land/crypt_keeper_progress.xml
deleted file mode 100644
index 7c182cb..0000000
--- a/res/layout-land/crypt_keeper_progress.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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="match_parent"
- android:padding="16dip"
- android:orientation="vertical"
->
-
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:minHeight="48dip"
- android:layout_alignParentStart="true"
- android:layout_centerVertical="true"
- android:textSize="30dip"
- android:textColor="@color/title_color"
- android:text="@string/crypt_keeper_setup_title"
- android:gravity="bottom"
- />
-
- <!-- Divider -->
- <RelativeLayout
- android:id="@+id/top_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- >
- <ProgressBar
- android:id="@+id/progress_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/progressBarStyleHorizontal"
- />
- </RelativeLayout>
-
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:orientation="horizontal"
- >
- <TextView
- android:id="@+id/status"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- />
-
- <ImageView
- android:id="@+id/encroid"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/encroid_waiting"
- android:contentDescription="@null"
- />
-
- <Button
- android:id="@+id/factory_reset"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="32dip"
- android:text="@string/main_clear_button_text"
- android:visibility="gone"
- />
- </LinearLayout>
-
-</LinearLayout>
-
diff --git a/res/layout-sw600dp/crypt_keeper_pattern_entry.xml b/res/layout-sw600dp/crypt_keeper_pattern_entry.xml
deleted file mode 100644
index 3937008..0000000
--- a/res/layout-sw600dp/crypt_keeper_pattern_entry.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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="match_parent"
- android:orientation="vertical"
- android:layout_marginTop="@dimen/crypt_keeper_pattern_top_margin">
-
- <include layout="@layout/crypt_keeper_status" />
-
- <LinearLayout
- android:layout_width="@dimen/crypt_keeper_pattern_size"
- android:layout_height="@dimen/crypt_keeper_pattern_size"
- android:orientation="horizontal"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="@dimen/crypt_keeper_pattern_separator">
-
- <include layout="@layout/crypt_keeper_pattern_field" />
-
- </LinearLayout>
-
- <include layout="@layout/crypt_keeper_emergency_button" />
-
-</LinearLayout>
diff --git a/res/layout-sw600dp/crypt_keeper_progress.xml b/res/layout-sw600dp/crypt_keeper_progress.xml
deleted file mode 100644
index 025d895..0000000
--- a/res/layout-sw600dp/crypt_keeper_progress.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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="match_parent"
->
- <RelativeLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:padding="64dip"
- >
- <ImageView
- android:id="@+id/encroid"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_alignParentBottom="true"
- android:paddingEnd="65dip"
- android:src="@drawable/encroid_waiting"
- android:contentDescription="@null"
- />
-
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:minHeight="48dip"
- android:layout_alignParentTop="true"
- android:layout_alignParentStart="true"
- android:layout_marginStart="16dip"
- android:layout_marginEnd="16dip"
- android:textSize="30dip"
- android:textColor="@color/title_color"
- android:text="@string/crypt_keeper_setup_title"
- android:gravity="bottom"
- />
-
- <!-- Divider -->
- <RelativeLayout
- android:id="@+id/top_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@+id/title"
- >
- <ProgressBar
- android:id="@+id/progress_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/progressBarStyleHorizontal"
- />
- </RelativeLayout>
-
- <TextView
- android:id="@+id/status"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@+id/top_divider"
- android:paddingTop="21dip"
- android:layout_marginStart="16dip"
- android:layout_marginEnd="16dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- />
-
- <!-- Divider -->
- <RelativeLayout
- android:id="@+id/bottom_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_above="@+id/factory_reset"
- android:visibility="gone"
- >
- <ProgressBar
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/progressBarStyleHorizontal"
- />
- </RelativeLayout>
-
- <Button
- android:id="@+id/factory_reset"
- android:layout_width="208dip"
- android:layout_height="48dip"
- android:layout_alignParentEnd="true"
- android:layout_alignParentBottom="true"
- android:layout_marginBottom="80dip"
- android:layout_marginEnd="16dip"
- android:text="@string/main_clear_button_text"
- android:visibility="gone"
- />
-
- </RelativeLayout>
-</FrameLayout>
diff --git a/res/layout/accessibility_qs_tooltips.xml b/res/layout/accessibility_qs_tooltips.xml
new file mode 100644
index 0000000..85d9c52
--- /dev/null
+++ b/res/layout/accessibility_qs_tooltips.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:background="@drawable/accessibility_qs_tooltips_background">
+
+ <ImageView
+ 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" />
+
+ <TextView
+ android:id="@+id/qs_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/accessibility_qs_tooltips_margin"
+ android:textColor="@android:color/black"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+ android:textSize="16sp" />
+
+</LinearLayout>
diff --git a/res/layout/crypt_keeper_blank.xml b/res/layout/crypt_keeper_blank.xml
deleted file mode 100644
index 2cd9c91..0000000
--- a/res/layout/crypt_keeper_blank.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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="match_parent"
- android:orientation="vertical"
- android:gravity="center_vertical"
->
-
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@drawable/encroid_progress"
- android:contentDescription="@null"
- />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_confirm.xml b/res/layout/crypt_keeper_confirm.xml
deleted file mode 100644
index 1b64909..0000000
--- a/res/layout/crypt_keeper_confirm.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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="match_parent"
- android:orientation="vertical"
- >
-
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
- android:layout_marginTop="16dp"
- android:layout_weight="1"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dip"
- android:layout_marginBottom="16dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/crypt_keeper_final_desc"
- />
- </ScrollView>
-
- <Button android:id="@+id/execute_encrypt"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="16dip"
- android:layout_marginBottom="16dip"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/crypt_keeper_button_text"
- android:gravity="center" />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_emergency_button.xml b/res/layout/crypt_keeper_emergency_button.xml
deleted file mode 100644
index 6efcf5a..0000000
--- a/res/layout/crypt_keeper_emergency_button.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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.
-*/
--->
-
-<!-- Emergency call button.
- Text is set by CryptKeeper.updateEmergencyCallButtonState() -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:orientation="vertical">
- <Button
- android:id="@+id/emergencyCallButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:textSize="14sp"
- android:fontFamily="sans-serif"
- android:textColor="#FFFFFF"
- style="?android:attr/borderlessButtonStyle" />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_password_entry.xml b/res/layout/crypt_keeper_password_entry.xml
deleted file mode 100644
index a7fecba..0000000
--- a/res/layout/crypt_keeper_password_entry.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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="match_parent"
- android:orientation="vertical"
- android:layout_marginTop="@dimen/crypt_keeper_password_top_margin">
-
- <include layout="@layout/crypt_keeper_status" />
-
- <LinearLayout
- android:layout_width="@dimen/crypt_keeper_password_width"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="16dip"
- android:layout_gravity="center_horizontal"
- android:background="@color/crypt_keeper_password_background">
-
- <include layout="@layout/crypt_keeper_password_field" />
-
- </LinearLayout>
-
- <include layout="@layout/crypt_keeper_emergency_button" />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_password_field.xml b/res/layout/crypt_keeper_password_field.xml
deleted file mode 100644
index 849c365..0000000
--- a/res/layout/crypt_keeper_password_field.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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.
-*/
--->
-
-<!-- Contents of the password entry field for CryptKeeper. Comes with an IME
- switcher, if necessary. Assumed to be in a horizontal LinearLayout. -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Note that crypt_keeper_pin_field.xml also has ImeAwareEditText with the same ID. -->
- <ImeAwareEditText android:id="@+id/passwordEntry"
- android:layout_height="wrap_content"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:inputType="textPassword"
- android:imeOptions="flagForceAscii"
- android:textSize="16sp"
- android:padding="10sp"
- android:maxLength="500"
- style="@style/TextAppearance.CryptKeeper_PasswordEntry" />
-
- <include layout="@layout/crypt_keeper_switch_input_method" />
-
-</merge>
diff --git a/res/layout/crypt_keeper_pattern_entry.xml b/res/layout/crypt_keeper_pattern_entry.xml
deleted file mode 100644
index 00d3d6e..0000000
--- a/res/layout/crypt_keeper_pattern_entry.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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="match_parent"
- android:orientation="vertical"
- android:layout_marginTop="@dimen/crypt_keeper_pattern_top_margin">
-
- <include layout="@layout/crypt_keeper_status" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/crypt_keeper_pattern_margin"
- android:layout_marginEnd="@dimen/crypt_keeper_pattern_margin"
- android:orientation="horizontal">
-
- <include layout="@layout/crypt_keeper_pattern_field" />
-
- </LinearLayout>
-
- <include layout="@layout/crypt_keeper_emergency_button" />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_pattern_field.xml b/res/layout/crypt_keeper_pattern_field.xml
deleted file mode 100644
index e12f77b..0000000
--- a/res/layout/crypt_keeper_pattern_field.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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.
-*/
--->
-
-<!-- Contents of the password entry field for CryptKeeper. Comes with an IME
- switcher, if necessary. Assumed to be in a horizontal LinearLayout. -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
- <com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/lock_pattern_background" />
-
- <include layout="@layout/crypt_keeper_switch_input_method" />
-
-</merge>
diff --git a/res/layout/crypt_keeper_pin_entry.xml b/res/layout/crypt_keeper_pin_entry.xml
deleted file mode 100644
index 3926ab0..0000000
--- a/res/layout/crypt_keeper_pin_entry.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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="match_parent"
- android:orientation="vertical"
- android:layout_marginTop="@dimen/crypt_keeper_password_top_margin">
-
- <include layout="@layout/crypt_keeper_status" />
-
- <LinearLayout
- android:layout_width="@dimen/crypt_keeper_password_width"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dip"
- android:orientation="horizontal"
- android:layout_gravity="center_horizontal"
- android:background="@color/crypt_keeper_password_background">
-
- <include layout="@layout/crypt_keeper_pin_field" />
-
- </LinearLayout>
-
- <include layout="@layout/crypt_keeper_emergency_button" />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_pin_field.xml b/res/layout/crypt_keeper_pin_field.xml
deleted file mode 100644
index d39d14d..0000000
--- a/res/layout/crypt_keeper_pin_field.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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.
-*/
--->
-
-<!-- Contents of the password entry field for CryptKeeper. Comes with an IME
- switcher, if necessary. Assumed to be in a horizontal LinearLayout. -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Note that crypt_keeper_password_field.xml also has ImeAwareEditText with the same ID. -->
- <ImeAwareEditText android:id="@+id/passwordEntry"
- android:layout_height="wrap_content"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:inputType="numberPassword"
- android:textSize="28sp"
- android:padding="4sp"
- android:maxLength="500"
- style="@style/TextAppearance.CryptKeeper_PasswordEntry" />
-
- <include layout="@layout/crypt_keeper_switch_input_method" />
-
-</merge>
diff --git a/res/layout/crypt_keeper_progress.xml b/res/layout/crypt_keeper_progress.xml
deleted file mode 100644
index 16cc7a1..0000000
--- a/res/layout/crypt_keeper_progress.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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="match_parent"
- android:padding="16dip"
- android:orientation="vertical"
->
-
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:minHeight="48dip"
- android:layout_alignParentStart="true"
- android:layout_centerVertical="true"
- android:textSize="30dip"
- android:textColor="@color/title_color"
- android:text="@string/crypt_keeper_setup_title"
- android:gravity="bottom"
- />
-
- <!-- Divider -->
- <RelativeLayout
- android:id="@+id/top_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- >
- <ProgressBar
- android:id="@+id/progress_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/progressBarStyleHorizontal"
- />
- </RelativeLayout>
-
-
- <TextView
- android:id="@+id/status"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- />
-
- <ImageView
- android:id="@+id/encroid"
- android:layout_width="wrap_content"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:layout_gravity="bottom|end"
- android:src="@drawable/encroid_waiting"
- android:contentDescription="@null"
- />
-
- <Button
- android:id="@+id/factory_reset"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_margin="32dip"
- android:layout_gravity="center"
- android:text="@string/main_clear_button_text"
- android:visibility="gone"
- />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_settings.xml b/res/layout/crypt_keeper_settings.xml
deleted file mode 100644
index 6b33e00..0000000
--- a/res/layout/crypt_keeper_settings.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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="match_parent"
- android:paddingStart="@dimen/preference_no_icon_padding_start"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:orientation="vertical">
- <ScrollView
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_marginTop="16dp"
- android:layout_weight="1">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dip"
- android:layout_marginBottom="16dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/crypt_keeper_desc" />
- <TextView
- android:id="@+id/warning_low_charge"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textStyle="bold"
- android:text="@string/crypt_keeper_low_charge_text"
- android:visibility="gone" />
- <TextView
- android:id="@+id/warning_unplugged"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="16dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:textStyle="bold"
- android:text="@string/crypt_keeper_unplugged_text"
- android:visibility="gone" />
- </LinearLayout>
- </ScrollView>
- <Button
- android:id="@+id/initiate_encrypt"
- style="@style/ActionPrimaryButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="end"
- android:text="@string/crypt_keeper_button_text" />
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_status.xml b/res/layout/crypt_keeper_status.xml
deleted file mode 100644
index bddff1a..0000000
--- a/res/layout/crypt_keeper_status.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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.
-*/
--->
-
-<!-- Status to show on the left side of lock screen -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal">
-
- <!-- We need android:gravity="center_horizontal" to make multi line
- status strings look good -->
- <TextView
- android:id="@+id/status"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dip"
- android:layout_marginEnd="8dip"
- android:textSize="16sp"
- android:fontFamily="sans-serif"
- android:textColor="@android:color/white"
- android:text="@string/enter_password"
- android:layout_gravity="center_horizontal"
- android:gravity="center_horizontal" />
-
- <TextView
- android:id="@+id/owner_info"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dip"
- android:layout_marginStart="8dip"
- android:layout_marginEnd="8dip"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:marqueeRepeatLimit ="marquee_forever"
- android:textSize="16sp"
- android:fontFamily="sans-serif"
- android:textColor="#B3FFFFFF"
- android:gravity="center_horizontal" />
-
-</LinearLayout>
diff --git a/res/layout/crypt_keeper_switch_input_method.xml b/res/layout/crypt_keeper_switch_input_method.xml
deleted file mode 100644
index 3fae593..0000000
--- a/res/layout/crypt_keeper_switch_input_method.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2014, 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.
-*/
--->
-
-<ImageView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/switch_ime_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@*android:drawable/ic_lockscreen_ime"
- android:clickable="true"
- android:contentDescription="@string/crypt_keeper_switch_input_method"
- android:padding="@dimen/crypt_keeper_edit_text_ime_padding"
- android:layout_gravity="center"
- android:background="?android:attr/selectableItemBackground"
- android:visibility="gone" />
diff --git a/res/layout/enable_accessibility_service_dialog_content.xml b/res/layout/enable_accessibility_service_dialog_content.xml
index 6b3220b..3fe932c 100644
--- a/res/layout/enable_accessibility_service_dialog_content.xml
+++ b/res/layout/enable_accessibility_service_dialog_content.xml
@@ -43,14 +43,6 @@
style="@style/AccessibilityDialogTitle" />
<TextView
- android:id="@+id/encryption_warning"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="10dip"
- android:textAlignment="viewStart"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
-
- <TextView
android:id="@+id/permissionDialog_description"
android:text="@string/accessibility_service_warning_description"
style="@style/AccessibilityDialogDescription" />
diff --git a/res/layout/storage_internal_format.xml b/res/layout/storage_internal_format.xml
index 08434b0..0b49d7e 100644
--- a/res/layout/storage_internal_format.xml
+++ b/res/layout/storage_internal_format.xml
@@ -20,7 +20,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <ScrollView
+ <androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
@@ -35,7 +35,7 @@
android:lineSpacingExtra="@dimen/sud_description_line_spacing_extra"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
android:textColor="?android:attr/textColorPrimary" />
- </ScrollView>
+ </androidx.core.widget.NestedScrollView>
<FrameLayout
android:layout_width="match_parent"
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
index afdcd0e..4e4a1d3 100755
--- a/res/values-sw600dp-land/dimens.xml
+++ b/res/values-sw600dp-land/dimens.xml
@@ -19,12 +19,6 @@
<dimen name="screen_margin_top">72dip</dimen>
<dimen name="screen_margin_bottom">48dip</dimen>
- <!-- CryptKeeper top margin for password/pin screen -->
- <dimen name="crypt_keeper_password_top_margin">116dip</dimen>
-
- <!-- CryptKeeper top margin for pattern screen -->
- <dimen name="crypt_keeper_pattern_top_margin">128dip</dimen>
-
<dimen name="captioning_preview_height">150dp</dimen>
<dimen name="confirm_credentials_top_padding">20dp</dimen>
diff --git a/res/values-sw600dp/bools.xml b/res/values-sw600dp/bools.xml
index 6443cc7..1454800 100644
--- a/res/values-sw600dp/bools.xml
+++ b/res/values-sw600dp/bools.xml
@@ -17,8 +17,5 @@
<resources>
<!-- Whether there is a silent mode checkbox -->
<bool name="has_silent_mode">false</bool>
-
- <!-- CryptKeeper allow rotation -->
- <bool name="crypt_keeper_allow_rotation">true</bool>
</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index b357758..db1fbbc 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -23,24 +23,11 @@
<dimen name="screen_margin_bottom">48dip</dimen>
<dimen name="content_margin_left">16dip</dimen>
<dimen name="description_margin_top">26dip</dimen>
- <dimen name="crypt_clock_size">120sp</dimen>
<!-- ActionBar contentInsetStart -->
<dimen name="actionbar_contentInsetStart">24dp</dimen>
<dimen name="actionbar_subsettings_contentInsetStart">80dp</dimen>
- <!-- CryptKeeper top margin for password/pin screen -->
- <dimen name="crypt_keeper_password_top_margin">256dip</dimen>
-
- <!-- CryptKeeper top margin for pattern screen -->
- <dimen name="crypt_keeper_pattern_top_margin">256dip</dimen>
-
- <!-- CryptKeeper separation between status and pattern -->
- <dimen name="crypt_keeper_pattern_separator">100dip</dimen>
-
- <!-- CryptKeeper password/pin width -->
- <dimen name="crypt_keeper_password_width">512dip</dimen>
-
<!-- SwitchBar margin start / end -->
<dimen name="switchbar_margin_start">24dp</dimen>
<dimen name="switchbar_margin_end">24dp</dimen>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 579ac35..e4822d8 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -103,6 +103,11 @@
<attr name="iconBackgroundColor" format="reference|color" />
</declare-styleable>
+ <!-- For AppGridView -->
+ <declare-styleable name="AppGridView">
+ <attr name="appCount" format="integer" />
+ </declare-styleable>
+
<attr name="switchBarTheme" format="reference" />
<attr name="switchBarMarginStart" format="dimension" />
<attr name="switchBarMarginEnd" format="dimension" />
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 9de420e..fef8419 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -17,11 +17,6 @@
<resources
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <color name="crypt_keeper_clock_background">#ff9a9a9a</color>
- <color name="crypt_keeper_clock_foreground">#ff666666</color>
- <color name="crypt_keeper_clock_am_pm">#ff9a9a9a</color>
- <color name="crypt_keeper_password_background">#70606060</color>
-
<color name="divider_color">#20ffffff</color>
<color name="title_color">@android:color/holo_blue_light</color>
<color name="setup_wizard_wifi_color_dark">#89ffffff</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 48d698c..fe9f42d 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -312,9 +312,6 @@
<!-- Whether swipe security option is hidden or not -->
<bool name="config_hide_swipe_security_option">false</bool>
- <!--Whether help links are defined. -->
- <bool name="config_has_help">false</bool>
-
<!-- Whether Wi-Fi settings should be shown or not.
This also controls whether Wi-fi related sub-settings (e.g. Wi-Fi preferences) will
surface in search results or not.-->
@@ -560,4 +557,7 @@
<!-- Whether to aggregate for network selection list-->
<bool name="config_network_selection_list_aggregation_enabled">false</bool>
+
+ <!-- Whether to give option to add restricted profiles -->
+ <bool name="config_offer_restricted_profiles">false</bool>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 94de83b..00372cb 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -41,8 +41,6 @@
<dimen name="balance_seekbar_center_marker_height">14dp</dimen>
<dimen name="balance_seekbar_center_marker_width">1dp</dimen>
- <dimen name="crypt_clock_size">100sp</dimen>
-
<dimen name="divider_height">3dip</dimen>
<dimen name="divider_margin_top">6dip</dimen>
<dimen name="divider_margin_bottom">7dip</dimen>
@@ -154,27 +152,6 @@
<dimen name="wifi_assistant_image_top">32dp</dimen>
<dimen name="wifi_assistant_image_start">24dp</dimen>
- <!-- CryptKeeper top margin for password/pin screen -->
- <dimen name="crypt_keeper_password_top_margin">88dip</dimen>
-
- <!-- CryptKeeper top margin for pattern screen -->
- <dimen name="crypt_keeper_pattern_top_margin">88dip</dimen>
-
- <!-- CryptKeeper password/pin width -->
- <dimen name="crypt_keeper_password_width">280dip</dimen>
-
- <!-- CryptKeeper emergency call button dimensions -->
- <dimen name="crypt_keeper_emergency_call_space_above">16dip</dimen>
-
- <!-- CryptKeeper edit text ime icon padding -->
- <dimen name="crypt_keeper_edit_text_ime_padding">8dip</dimen>
-
- <!-- CryptKeeper pattern margin on phone -->
- <dimen name="crypt_keeper_pattern_margin">8dip</dimen>
-
- <!-- CryptKeeper pattern size for tablet -->
- <dimen name="crypt_keeper_pattern_size">354dip</dimen>
-
<!-- SIM Dialog Margin top -->
<dimen name="sim_dialog_margin_top">8dip</dimen>
<!-- SIM Dialog Margin bottom -->
@@ -297,6 +274,10 @@
<dimen name="accessibility_icon_size">32dp</dimen>
<dimen name="accessibility_icon_foreground_size">18dp</dimen>
+ <!-- Accessibility quick settings tooltips -->
+ <dimen name="accessibility_qs_tooltips_margin">20dp</dimen>
+ <dimen name="accessibility_qs_tooltips_margin_top">27dp</dimen>
+
<!-- Restricted icon in switch bar -->
<dimen name="restricted_icon_margin_end">16dp</dimen>
<!-- Restricted icon size in switch bar -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6240175..73a0de8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -723,12 +723,12 @@
<string name="security_settings_title">Security</string>
<!-- Security Settings screen setting option title for the item to take you to the encryption and credential screen -->
<string name="encryption_and_credential_settings_title">Encryption & credentials</string>
- <!-- Security Settings screen Encryption and crendential summary -->
+ <!-- Security Settings screen Encryption and credential summary -->
<string name="encryption_and_credential_settings_summary" product="default">Phone encrypted</string>
- <string name="decryption_settings_summary" product="default">Phone not encrypted</string>
- <!-- Security Settings screen Encryption and crendential summary -->
+ <string name="not_encrypted_summary" product="default">Phone not encrypted</string>
+ <!-- Security Settings screen Encryption and credential summary -->
<string name="encryption_and_credential_settings_summary" product="tablet">Device encrypted</string>
- <string name="decryption_settings_summary" product="tablet">Device not encrypted</string>
+ <string name="not_encrypted_summary" product="tablet">Device not encrypted</string>
<!-- Screen title for a list of settings controlling what to show on user's lockscreen [CHAR LIMIT=60] -->
<string name="lockscreen_settings_title">Lock screen</string>
<!-- Category title for the settings that control what lockscreen shows. [CHAR LIMIT=30] -->
@@ -1281,135 +1281,15 @@
<string name="fingerprint_last_delete_confirm">Yes, remove</string>
<!-- Title of the preferences category for preference items to control encryption -->
- <string name="crypt_keeper_settings_title">Encryption</string>
+ <string name="encryption_settings_title">Encryption</string>
<!-- Title of the preferences item to control encryption -->
- <string name="crypt_keeper_encrypt_title" product="tablet">Encrypt tablet</string>
+ <string name="encrypt_title" product="tablet">Encrypt tablet</string>
<!-- Title of the preferences item to control encryption -->
- <string name="crypt_keeper_encrypt_title" product="default">Encrypt phone</string>
+ <string name="encrypt_title" product="default">Encrypt phone</string>
<!-- Summary of the preferences item to control encryption, when encryption is active -->
- <string name="crypt_keeper_encrypted_summary">Encrypted</string>
-
- <!-- Informational text in the first confirmation screen before starting device encryption -->
- <string name="crypt_keeper_desc" product="tablet">
- You can encrypt your accounts, settings, downloaded apps and their data,
- media, and other files. After you encrypt your tablet, assuming you\u2019ve set up a screen lock
- (that is, a pattern or numeric PIN or password), you\u2019ll need to unlock the screen to decrypt
- the tablet every time you power it on. The only other way to decrypt is to perform a factory
- data reset, erasing all your data.\n\nEncryption takes an hour or more. You must start with
- a charged battery and keep your tablet plugged in throughout the process. If you interrupt it,
- you\u2019ll lose some or all of your data</string>
- <!-- Informational text in the first confirmation screen before starting device encryption -->
- <string name="crypt_keeper_desc" product="default">
- You can encrypt your accounts, settings, downloaded apps and their data,
- media, and other files. After you encrypt your phone, assuming you\u2019ve set up a screen lock
- (that is, a pattern or numeric PIN or password), you\u2019ll need to unlock the screen to decrypt
- the phone every time you power it on. The only other way to decrypt is to perform a factory
- data reset, erasing all your data.\n\nEncryption takes an hour or more. You must start with
- a charged battery and keep your phone plugged in throughout the process. If you interrupt it,
- you\u2019ll lose some or all of your data.</string>
-
- <!-- Button text to start encryption process -->
- <string name="crypt_keeper_button_text" product="tablet">Encrypt tablet</string>
- <!-- Button text to start encryption process -->
- <string name="crypt_keeper_button_text" product="default">Encrypt phone</string>
-
- <!-- Warning string that will be displayed when encryption cannot be started -->
- <string name="crypt_keeper_low_charge_text">Charge your battery and try again.</string>
- <!-- Warning string that will be displayed when encryption cannot be started -->
- <string name="crypt_keeper_unplugged_text">Plug in your charger and try again.</string>
-
- <!-- Dialog title, shown when encryption cannot proceed because a PIN/Password is needed -->
- <string name="crypt_keeper_dialog_need_password_title">No lock screen PIN or password</string>
- <!-- Dialog message, shown when encryption cannot proceed because a PIN/Password is needed -->
- <string name="crypt_keeper_dialog_need_password_message">You need to set a lock screen PIN or
- password before you can start encryption.</string>
-
- <!-- Title of the final confirmation screen before starting device encryption -->
- <string name="crypt_keeper_confirm_title">Encrypt?</string>
- <!-- Warning text in the final confirmation screen before starting device encryption -->
- <string name="crypt_keeper_final_desc" product="tablet">
- The encryption operation is irreversible and if you interrupt it, you\u2019ll lose data.
- Encryption takes an hour or more, during which the tablet will restart several times.
- </string>
- <!-- Warning text in the final confirmation screen before starting device encryption -->
- <string name="crypt_keeper_final_desc" product="default">
- The encryption operation is irreversible and if you interrupt it, you\u2019ll lose data.
- Encryption takes an hour or more, during which the phone will restart several times.
- </string>
-
- <!-- Title of the progress screen while encrypting the device -->
- <string name="crypt_keeper_setup_title">Encrypting</string>
-
- <!-- Informational text on the progress screen while encrypting the device -->
- <string name="crypt_keeper_setup_description" product="tablet">Wait while your tablet
- is being encrypted. <xliff:g id="percent" example="50">^1</xliff:g>% complete.</string>
- <!-- Informational text on the progress screen while encrypting the device -->
- <string name="crypt_keeper_setup_description" product="default">Wait while your phone
- is being encrypted. <xliff:g id="percent" example="50">^1</xliff:g>% complete.</string>
- <string name="crypt_keeper_setup_time_remaining" product="tablet">Wait while your tablet
- is being encrypted. Time remaining: <xliff:g id="duration" example="1:23">^1</xliff:g></string>
- <string name="crypt_keeper_setup_time_remaining" product="default">Wait while your phone
- is being encrypted. Time remaining: <xliff:g id="duration" example="1:23">^1</xliff:g></string>
-
- <string name="crypt_keeper_force_power_cycle" product="tablet">To unlock your tablet, turn it off and then on.</string>
- <string name="crypt_keeper_force_power_cycle" product="default">To unlock your phone, turn it off and then on.</string>
-
-
- <!-- Warn user their device will be wiped if they make x more failed attempts -->
- <string name="crypt_keeper_warn_wipe">Warning: Your device will be wiped after
- <xliff:g id="count" example="7">^1</xliff:g> more failed attempts to be unlocked!
- </string>
-
- <!-- Informational text on the password entry screen prompting the user for their password -->
- <string name="crypt_keeper_enter_password">Type your password</string>
-
- <!-- Title of the encryption screen when encrypting the device failed -->
- <string name="crypt_keeper_failed_title">Encryption unsuccessful</string>
-
- <!-- Informational text when encryption fails -->
- <string name="crypt_keeper_failed_summary" product="tablet">
- Encryption was interrupted and can\u2019t complete. As a result, the data on
- your tablet is no longer accessible.
- \n\n
- To resume using your tablet, you need to perform a factory reset.
- When you set up your tablet after the reset, you\u2019ll have an opportunity
- to restore any data that was backed up to your Google Account.
- </string>
-
- <!-- Informational text when encryption fails -->
- <string name="crypt_keeper_failed_summary" product="default">
- Encryption was interrupted and can\u2019t complete. As a result, the data on
- your phone is no longer accessible.
- \n\nTo resume using your phone, you need to perform a factory reset.
- When you set up your phone after the reset, you\u2019ll have an opportunity
- to restore any data that was backed up to your Google Account.
- </string>
-
- <!-- Title of the encryption screen when decrypting the device failed -->
- <string name="crypt_keeper_data_corrupt_title">Decryption unsuccessful</string>
-
- <!-- Informational text when encryption fails -->
- <string name="crypt_keeper_data_corrupt_summary" product="tablet">
- The password you entered is correct, but unfortunately your data is
- corrupt.
- \n\nTo resume using your tablet, you need to perform a factory reset.
- When you set up your tablet after the reset, you\u2019ll have an opportunity
- to restore any data that was backed up to your Google Account.
- </string>
-
- <!-- Informational text when encryption fails -->
- <string name="crypt_keeper_data_corrupt_summary" product="default">
- The password you entered is correct, but unfortunately your data is
- corrupt.
- \n\nTo resume using your phone, you need to perform a factory reset.
- When you set up your phone after the reset, you\u2019ll have an opportunity
- to restore any data that was backed up to your Google Account.
- </string>
-
- <!-- Image button description to switch input method -->
- <string name="crypt_keeper_switch_input_method">Switch input method</string>
+ <string name="encrypted_summary">Encrypted</string>
<!-- Unlock Picker Settings --><skip />
@@ -2445,6 +2325,8 @@
<string name="wifi_do_not_provide_eap_user_cert">Do not provide</string>
<!-- Menu option for not validating the EAP server -->
<string name="wifi_do_not_validate_eap_server">Do not validate</string>
+ <!-- Menu option for Trust On First Use[CHAR_LIMIT=64] -->
+ <string name="wifi_trust_on_first_use">Trust on First Use</string>
<!-- Warning message displayed if network name (ssid) is too long -->
<string name="wifi_ssid_too_long">Network name is too long.</string>
<!-- Warning message displayed if user does not specify a domain for the CA certificate.
@@ -5565,8 +5447,10 @@
<string name="accessibility_autoclick_longer_desc">Longer</string>
<!-- Description for the seekbar that adjust auto click time. [CHAR_LIMIT=NONE] -->
<string name="accessibility_autoclick_seekbar_desc">Auto click time</string>
- <!-- Title for accessibility preference screen for configuring vibrations. -->
+ <!-- Title for preference screen for configuring vibrations. [CHAR LIMIT=NONE] -->
<string name="accessibility_vibration_settings_title">Vibration & haptics</string>
+ <!-- Summary for preference screen for configuring vibrations. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_vibration_settings_summary">Control the vibration strength for different usages</string>
<!-- Title for the category of preferences to configure device vibrations related to calls. [CHAR LIMIT=NONE] -->
<string name="accessibility_call_vibration_category_title">Calls</string>
<!-- Title for the category of preferences to configure device vibrations related to notifications and alarms. [CHAR LIMIT=NONE] -->
@@ -5583,6 +5467,8 @@
<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. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_service_quick_settings_tooltips_content">Swipe down to quickly turn <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> on or off in quick settings</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] -->
@@ -5734,33 +5620,6 @@
<item quantity="other"><xliff:g id="click_delay_label">%1$s</xliff:g> seconds</item>
</plurals>
- <!-- Summary for vibration settings preference when notification vibration and haptic feedback intensity are set. [CHAR LIMIT=50] -->
- <string name="accessibility_vibration_summary">Ring <xliff:g id="summary_ring" example="Medium">%1$s</xliff:g>, notification <xliff:g id="summary_notification" example="Low">%2$s</xliff:g>, touch <xliff:g id="summary_touch" example="High">%3$s</xliff:g></string>
-
- <!-- Summary for vibration settings preference when ring & notification are set to off-->
- <string name="accessibility_vibration_summary_off">Ring & notification set to off</string>
-
- <!-- Summary for vibration settings preference when ring & notification are set to low-->
- <string name="accessibility_vibration_summary_low">Ring & notification set to low</string>
-
- <!-- Summary for vibration settings preference when ring & notification are set to medium-->
- <string name="accessibility_vibration_summary_medium">Ring & notification set to medium</string>
-
- <!-- Summary for vibration settings preference when ring & notification are set to high-->
- <string name="accessibility_vibration_summary_high">Ring & notification set to high</string>
-
- <!-- Label describing an option turning vibrations off. [CHAR LIMIT=15] -->
- <string name="accessibility_vibration_intensity_off">Off</string>
-
- <!-- Label describing a low intensity vibration option. [CHAR LIMIT=15] -->
- <string name="accessibility_vibration_intensity_low">Low</string>
-
- <!-- Label describing a medium intensity vibration option. [CHAR LIMIT=15] -->
- <string name="accessibility_vibration_intensity_medium">Medium</string>
-
- <!-- Label describing a high intensity vibration option. [CHAR LIMIT=15] -->
- <string name="accessibility_vibration_intensity_high">High</string>
-
<!-- Title for accessibility menu item to launch a settings activity. [CHAR LIMIT=15] -->
<string name="accessibility_menu_item_settings">Settings</string>
@@ -5847,30 +5706,6 @@
can't verify user consent. [CHAR LIMIT=NONE] -->
<string name="touch_filtered_warning">Because an app is obscuring a permission request, Settings
can’t verify your response.</string>
- <!-- Warning that the device data will not be encrypted with password or PIN if
- enabling an accessibility service and there is a secure lock setup. [CHAR LIMIT=NONE] -->
- <string name="enable_service_encryption_warning">If you turn on <xliff:g id="service"
- example="TalkBack">%1$s</xliff:g>, your device won’t use your screen lock to enhance
- data encryption.</string>
- <!-- Warning that the device data will not be encrypted with password or PIN if
- choosing a secure lock and there is an enabled accessibility service. [CHAR LIMIT=NONE] -->
- <string name="secure_lock_encryption_warning">Because you\u2019ve turned on an accessibility service,
- your device won’t use your screen lock to enhance data encryption.</string>
-
- <!-- Message to the users to enter their pattern before enabling an accessibility service. [CHAR LIMIT=NONE] -->
- <string name="enable_service_pattern_reason">Because turning on <xliff:g id="service"
- example="TalkBack">%1$s</xliff:g> affects data encryption, you need to confirm your pattern.
- </string>
-
- <!-- Message to the users to enter their PIN before enabling an accessibility service. [CHAR LIMIT=NONE] -->
- <string name="enable_service_pin_reason">Because turning on <xliff:g id="service"
- example="TalkBack">%1$s</xliff:g> affects data encryption, you need to confirm your PIN.
- </string>
-
- <!-- Message to the users to enter their password before enabling an accessibility service. [CHAR LIMIT=NONE] -->
- <string name="enable_service_password_reason">Because turning on <xliff:g id="service"
- example="TalkBack">%1$s</xliff:g> affects data encryption, you need to confirm your password.
- </string>
<!-- Warning that explains that accessibility services have a lot of access to user data [CHAR LIMIT=NONE] -->
<string name="accessibility_service_warning"><xliff:g id="service"
@@ -7169,26 +7004,6 @@
<!-- Messaage shown in dialog when you can't manually sync -->
<string name="cant_sync_dialog_message">Sync for this item is currently disabled. To change this setting, temporarily turn on background data and automatic sync.</string>
- <!-- This is displayed to the user when the device needs to be decrypted -->
- <string name="enter_password">To start Android, enter your password</string>
- <!-- Informational text on the pin entry screen prompting the user for their pin -->
- <string name="enter_pin">To start Android, enter your PIN</string>
- <!-- Informational text on the pattern entry screen prompting the user for their pattern -->
- <string name="enter_pattern">To start Android, draw your pattern</string>
-
- <!-- Message shown when user enters wrong pattern -->
- <string name="cryptkeeper_wrong_pattern">Wrong Pattern</string>
- <!-- Message shown when user enters wrong password -->
- <string name="cryptkeeper_wrong_password">Wrong Password</string>
- <!-- Message shown when user enters wrong PIN -->
- <string name="cryptkeeper_wrong_pin">Wrong PIN</string>
-
- <!-- Shown when a password has been entered, and we're checking it -->
- <string name="checking_decryption">Checking\u2026</string>
- <!-- Shown when password is correct, and we're starting Android -->
- <string name="starting_android">Starting Android\u2026</string>
-
-
<!-- the following are for Settings Storage screen -->
<!-- Menu item/button 'delete' -->
<string name="delete">Delete</string>
@@ -7402,11 +7217,6 @@
<!-- Disclaimer string for data usage measured by device. [CHAR LIMIT=80] -->
<string name="data_usage_disclaimer">Carrier data accounting may differ from your device.</string>
- <!-- Button at the bottom of the CryptKeeper screen to make an emergency call. -->
- <string name="cryptkeeper_emergency_call">Emergency call</string>
- <!-- Button at the bottom of the CryptKeeper screen that lets the user return to a call -->
- <string name="cryptkeeper_return_to_call">Return to call</string>
-
<!-- Input label for the name of a VPN profile. [CHAR LIMIT=40] -->
<string name="vpn_name">Name</string>
<!-- Input label for the type of a VPN profile. [CHAR LIMIT=40] -->
@@ -8425,6 +8235,8 @@
<string name="keywords_touch_vibration">haptics, vibrate, screen, sensitivity</string>
<!-- List of synonyms for ring vibration setting (changes whether your phone vibrates when it rings), used to match in settings search [CHAR LIMIT=NONE] -->
<string name="keywords_ring_vibration">haptics, vibrate, phone, call, sensitivity, ring</string>
+ <!-- List of synonyms for ring vibration setting (changes whether your phone vibrates when it rings), used to match in settings search [CHAR LIMIT=NONE] -->
+ <string name="keywords_ramping_ringer_vibration">haptics, vibrate, phone, call, ring, gradually</string>
<!-- List of synonyms for notification vibration setting (changes whether your phone vibrates when it shows a notification), used to match in settings search [CHAR LIMIT=NONE] -->
<string name="keywords_notification_vibration">haptics, vibrate, sensitivity</string>
<!-- List of synonyms for vibration and haptics setting, used to match in settings search [CHAR LIMIT=NONE] -->
@@ -13366,7 +13178,7 @@
<string name="lockscreen_privacy_wallet_summary">Allow access to wallet from lock screen and quick settings</string>
<!-- QR Code Scanner toggle name [CHAR LIMIT=60] -->
- <string name="lockscreen_privacy_qr_code_scanner_setting_toggle">Show QR Scanner</string>
+ <string name="lockscreen_privacy_qr_code_scanner_setting_toggle">Show QR scanner</string>
<!-- QR Code Scanner summary [CHAR LIMIT=NONE] -->
<string name="lockscreen_privacy_qr_code_scanner_summary">Allow access to QR scanner from lock screen</string>
@@ -13549,6 +13361,8 @@
<string name="mobile_data_disable_message">You won\’t have access to data or the internet through <xliff:g id="carrier" example="T-Mobile">%s</xliff:g>. Internet will only be available via Wi\u2011Fi.</string>
<!-- Text used to refer to the user's current carrier in mobile_data_disable_message if the users's mobile network carrier name is not available [CHAR LIMIT=NONE] -->
<string name="mobile_data_disable_message_default_carrier">your carrier</string>
+ <!-- Summary for enterprise restriction not allow to use [CHAR LIMIT=NONE] -->
+ <string name="not_allowed_by_ent">Not allowed by your organization</string>
<!-- Summary for preference when Bedtime mode is on [CHAR LIMIT=NONE] -->
<string name="aware_summary_when_bedtime_on">Unavailable because bedtime mode is on</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 21581cb..838d63b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -198,10 +198,6 @@
<item name="android:activityOpenExitAnimation">@anim/confirm_credential_open_exit</item>
</style>
- <style name="CryptKeeperBlankTheme" parent="@android:style/Theme.Material.NoActionBar">
- <item name="android:background">#ff000000</item>
- </style>
-
<style name="SetupWizardButton.Negative" parent="@style/SudGlifButton.Secondary">
<!-- Negative margin to offset for padding of the button itself. We want the label to be
aligned with the text above it -->
@@ -281,14 +277,6 @@
<item name="android:textSize">24sp</item>
</style>
- <style name="TextAppearance.CryptKeeper_PasswordEntry" parent="android:TextAppearance.DeviceDefault">
- <item name="android:gravity">center_horizontal</item>
- <item name="android:background">@null</item>
- <item name="android:textCursorDrawable">@null</item>
- <item name="android:singleLine">true</item>
- <item name="android:imeOptions">flagForceAscii|actionDone</item>
- </style>
-
<style name="TextAppearance.Medium" parent="@android:style/TextAppearance.DeviceDefault.Medium"/>
<style name="TextAppearance.Small" parent="@android:style/TextAppearance.DeviceDefault.Small"/>
<style name="TextAppearance.Switch"
diff --git a/res/values/themes.xml b/res/values/themes.xml
index aae158b..3328b6c 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -117,15 +117,6 @@
<item name="android:minWidth">@dimen/min_tap_target_size</item>
</style>
- <style name="Theme.CryptKeeper" parent="@android:style/Theme.Material.NoActionBar">
- <item name="android:windowTranslucentStatus">false</item>
- <item name="android:windowTranslucentNavigation">false</item>
- <item name="android:windowDrawsSystemBarBackgrounds">false</item>
- <item name="android:background">@android:color/black</item>
-
- <item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
- </style>
-
<style name="ThemeOverlay.AlertDialog" parent="@android:style/ThemeOverlay.Material.Dialog.Alert">
<item name="android:windowSoftInputMode">adjustResize</item>
</style>
diff --git a/res/xml/accessibility_notification_vibration_settings.xml b/res/xml/accessibility_notification_vibration_settings.xml
deleted file mode 100644
index b37d363..0000000
--- a/res/xml/accessibility_notification_vibration_settings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/accessibility_notification_vibration_title" />
diff --git a/res/xml/accessibility_ring_vibration_settings.xml b/res/xml/accessibility_ring_vibration_settings.xml
deleted file mode 100644
index 078f76c..0000000
--- a/res/xml/accessibility_ring_vibration_settings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/accessibility_ring_vibration_title" />
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index d836e24..dcf3fc2 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -110,7 +110,8 @@
android:persistent="false"
android:title="@string/accessibility_vibration_settings_title"
settings:controller="com.android.settings.accessibility.VibrationPreferenceController"
- settings:keywords="@string/keywords_vibration"/>
+ settings:keywords="@string/keywords_vibration"
+ android:summary="@string/accessibility_vibration_settings_summary"/>
</PreferenceCategory>
diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml
index ced5e79..4bc9317 100644
--- a/res/xml/accessibility_text_reading_options.xml
+++ b/res/xml/accessibility_text_reading_options.xml
@@ -17,6 +17,20 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
android:persistent="false"
android:title="@string/accessibility_text_reading_options_title">
+
+ <SwitchPreference
+ android:key="toggle_force_bold_text"
+ android:persistent="false"
+ android:title="@string/force_bold_text"
+ settings:keywords="@string/keywords_bold_text"
+ settings:controller="com.android.settings.accessibility.FontWeightAdjustmentPreferenceController"/>
+
+ <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"/>
</PreferenceScreen>
diff --git a/res/xml/accessibility_touch_vibration_settings.xml b/res/xml/accessibility_touch_vibration_settings.xml
deleted file mode 100644
index ed8f550..0000000
--- a/res/xml/accessibility_touch_vibration_settings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/accessibility_touch_vibration_title" />
diff --git a/res/xml/accessibility_vibration_intensity_settings.xml b/res/xml/accessibility_vibration_intensity_settings.xml
new file mode 100644
index 0000000..d9a97f0
--- /dev/null
+++ b/res/xml/accessibility_vibration_intensity_settings.xml
@@ -0,0 +1,64 @@
+<?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"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:title="@string/accessibility_vibration_settings_title">
+
+ <PreferenceCategory
+ android:key="accessibility_call_vibration_category"
+ android:title="@string/accessibility_call_vibration_category_title">
+
+ <com.android.settings.widget.SeekBarPreference
+ android:key="ring_vibration_preference_screen"
+ android:title="@string/accessibility_ring_vibration_title"
+ app:keywords="@string/keywords_ring_vibration"
+ app:controller="com.android.settings.accessibility.RingVibrationIntensityPreferenceController" />
+
+ <SwitchPreference
+ android:key="ramping_ringer"
+ android:title="@string/vibrate_when_ringing_option_ramping_ringer"
+ app:keywords="@string/keywords_ramping_ringer_vibration"
+ app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:key="accessibility_notification_alarm_vibration_category"
+ android:title="@string/accessibility_notification_alarm_vibration_category_title">
+
+ <com.android.settings.widget.SeekBarPreference
+ android:key="notification_vibration_preference_screen"
+ android:title="@string/accessibility_notification_vibration_title"
+ app:keywords="@string/keywords_notification_vibration"
+ app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />
+
+ </PreferenceCategory>
+
+ <PreferenceCategory
+ android:key="accessibility_interactive_haptics_category"
+ android:title="@string/accessibility_interactive_haptics_category_title">
+
+ <com.android.settings.widget.SeekBarPreference
+ android:key="touch_vibration_preference_screen"
+ android:title="@string/accessibility_touch_vibration_title"
+ app:keywords="@string/keywords_touch_vibration"
+ app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />
+
+ </PreferenceCategory>
+
+</PreferenceScreen>
diff --git a/res/xml/accessibility_vibration_settings.xml b/res/xml/accessibility_vibration_settings.xml
index ff10611..18cd718 100644
--- a/res/xml/accessibility_vibration_settings.xml
+++ b/res/xml/accessibility_vibration_settings.xml
@@ -17,25 +17,23 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/accessibility_vibration_settings_title">
<PreferenceCategory
android:key="accessibility_call_vibration_category"
android:title="@string/accessibility_call_vibration_category_title">
- <Preference
- android:fragment="com.android.settings.accessibility.RingVibrationPreferenceFragment"
+ <SwitchPreference
android:key="ring_vibration_preference_screen"
android:title="@string/accessibility_ring_vibration_title"
- settings:keywords="@string/keywords_ring_vibration"
- app:controller="com.android.settings.accessibility.RingVibrationIntensityPreferenceController" />
+ app:keywords="@string/keywords_ring_vibration"
+ app:controller="com.android.settings.accessibility.RingVibrationTogglePreferenceController" />
- <Preference
- android:fragment="com.android.settings.sound.VibrateForCallsPreferenceFragment"
- android:key="vibrate_for_calls"
- android:title="@string/vibrate_when_ringing_title"
- settings:controller="com.android.settings.sound.VibrateForCallsPreferenceController"/>
+ <SwitchPreference
+ android:key="ramping_ringer"
+ android:title="@string/vibrate_when_ringing_option_ramping_ringer"
+ app:keywords="@string/keywords_ramping_ringer_vibration"
+ app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>
</PreferenceCategory>
@@ -43,12 +41,11 @@
android:key="accessibility_notification_alarm_vibration_category"
android:title="@string/accessibility_notification_alarm_vibration_category_title">
- <Preference
- android:fragment="com.android.settings.accessibility.NotificationVibrationPreferenceFragment"
+ <SwitchPreference
android:key="notification_vibration_preference_screen"
android:title="@string/accessibility_notification_vibration_title"
- settings:keywords="@string/keywords_notification_vibration"
- app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />
+ app:keywords="@string/keywords_notification_vibration"
+ app:controller="com.android.settings.accessibility.NotificationVibrationTogglePreferenceController" />
</PreferenceCategory>
@@ -56,12 +53,11 @@
android:key="accessibility_interactive_haptics_category"
android:title="@string/accessibility_interactive_haptics_category_title">
- <Preference
- android:fragment="com.android.settings.accessibility.TouchVibrationPreferenceFragment"
+ <SwitchPreference
android:key="touch_vibration_preference_screen"
android:title="@string/accessibility_touch_vibration_title"
- settings:keywords="@string/keywords_touch_vibration"
- app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />
+ app:keywords="@string/keywords_touch_vibration"
+ app:controller="com.android.settings.accessibility.HapticFeedbackTogglePreferenceController" />
</PreferenceCategory>
diff --git a/res/xml/encryption_and_credential.xml b/res/xml/encryption_and_credential.xml
index beaccce..cc8210a 100644
--- a/res/xml/encryption_and_credential.xml
+++ b/res/xml/encryption_and_credential.xml
@@ -21,12 +21,11 @@
<PreferenceCategory
android:key="encryption_and_credentials_status_category"
- android:title="@string/crypt_keeper_settings_title">
+ android:title="@string/encryption_settings_title">
<Preference
android:key="encryption_and_credentials_encryption_status"
- android:title="@string/crypt_keeper_encrypt_title"
- android:fragment="com.android.settings.security.CryptKeeperSettings"
+ android:title="@string/encrypt_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.security.EncryptionStatusPreferenceController"/>
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
deleted file mode 100644
index 7e75ee2..0000000
--- a/src/com/android/settings/CryptKeeper.java
+++ /dev/null
@@ -1,1034 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.app.Activity;
-import android.app.StatusBarManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Resources.NotFoundException;
-import android.media.AudioManager;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.os.storage.IStorageManager;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
-import android.sysprop.VoldProperties;
-import android.telecom.TelecomManager;
-import android.telephony.TelephonyManager;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.format.DateUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnKeyListener;
-import android.view.View.OnTouchListener;
-import android.view.WindowManager;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.widget.Button;
-import android.widget.ImeAwareEditText;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockPatternView;
-import com.android.internal.widget.LockPatternView.Cell;
-import com.android.internal.widget.LockPatternView.DisplayMode;
-
-import java.util.List;
-
-/**
- * Settings screens to show the UI flows for encrypting/decrypting the device.
- *
- * This may be started via adb for debugging the UI layout, without having to go through
- * encryption flows everytime. It should be noted that starting the activity in this manner
- * is only useful for verifying UI-correctness - the behavior will not be identical.
- * <pre>
- * $ adb shell pm enable com.android.settings/.CryptKeeper
- * $ adb shell am start \
- * -e "com.android.settings.CryptKeeper.DEBUG_FORCE_VIEW" "progress" \
- * -n com.android.settings/.CryptKeeper
- * </pre>
- */
-public class CryptKeeper extends Activity implements TextView.OnEditorActionListener,
- OnKeyListener, OnTouchListener, TextWatcher {
- private static final String TAG = "CryptKeeper";
-
- private static final String DECRYPT_STATE = "trigger_restart_framework";
-
- /** Message sent to us to indicate encryption update progress. */
- private static final int MESSAGE_UPDATE_PROGRESS = 1;
- /** Message sent to us to indicate alerting the user that we are waiting for password entry */
- private static final int MESSAGE_NOTIFY = 2;
-
- // Constants used to control policy.
- private static final int MAX_FAILED_ATTEMPTS = 30;
- private static final int COOL_DOWN_ATTEMPTS = 10;
-
- // Intent action for launching the Emergency Dialer activity.
- static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
-
- // Debug Intent extras so that this Activity may be started via adb for debugging UI layouts
- private static final String EXTRA_FORCE_VIEW =
- "com.android.settings.CryptKeeper.DEBUG_FORCE_VIEW";
- private static final String FORCE_VIEW_PROGRESS = "progress";
- private static final String FORCE_VIEW_ERROR = "error";
- private static final String FORCE_VIEW_PASSWORD = "password";
-
- private static final String STATE_COOLDOWN = "cooldown";
-
- /** When encryption is detected, this flag indicates whether or not we've checked for errors. */
- private boolean mValidationComplete;
- private boolean mValidationRequested;
- /** A flag to indicate that the volume is in a bad state (e.g. partially encrypted). */
- private boolean mEncryptionGoneBad;
- /** If gone bad, should we show encryption failed (false) or corrupt (true)*/
- private boolean mCorrupt;
- /** A flag to indicate when the back event should be ignored */
- /** When set, blocks unlocking. Set every COOL_DOWN_ATTEMPTS attempts, only cleared
- by power cycling phone. */
- private boolean mCooldown = false;
-
- PowerManager.WakeLock mWakeLock;
- private ImeAwareEditText mPasswordEntry;
- private LockPatternView mLockPatternView;
- /** Number of calls to {@link #notifyUser()} to ignore before notifying. */
- private int mNotificationCountdown = 0;
- /** Number of calls to {@link #notifyUser()} before we release the wakelock */
- private int mReleaseWakeLockCountdown = 0;
- private int mStatusString = R.string.enter_password;
-
- // how long we wait to clear a wrong pattern
- private static final int WRONG_PATTERN_CLEAR_TIMEOUT_MS = 1500;
-
- // how long we wait to clear a right pattern
- private static final int RIGHT_PATTERN_CLEAR_TIMEOUT_MS = 500;
-
- // When the user enters a short pin/password, run this to show an error,
- // but don't count it against attempts.
- private final Runnable mFakeUnlockAttemptRunnable = new Runnable() {
- @Override
- public void run() {
- handleBadAttempt(1 /* failedAttempt */);
- }
- };
-
- // TODO: this should be tuned to match minimum decryption timeout
- private static final int FAKE_ATTEMPT_DELAY = 1000;
-
- private final Runnable mClearPatternRunnable = new Runnable() {
- @Override
- public void run() {
- mLockPatternView.clearPattern();
- }
- };
-
- /**
- * Used to propagate state through configuration changes (e.g. screen rotation)
- */
- private static class NonConfigurationInstanceState {
- final PowerManager.WakeLock wakelock;
-
- NonConfigurationInstanceState(PowerManager.WakeLock _wakelock) {
- wakelock = _wakelock;
- }
- }
-
- private class DecryptTask extends AsyncTask<String, Void, Integer> {
- private void hide(int id) {
- View view = findViewById(id);
- if (view != null) {
- view.setVisibility(View.GONE);
- }
- }
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- beginAttempt();
- }
-
- @Override
- protected Integer doInBackground(String... params) {
- final IStorageManager service = getStorageManager();
- try {
- return service.decryptStorage(params[0]);
- } catch (Exception e) {
- Log.e(TAG, "Error while decrypting...", e);
- return -1;
- }
- }
-
- @Override
- protected void onPostExecute(Integer failedAttempts) {
- if (failedAttempts == 0) {
- // The password was entered successfully. Simply do nothing
- // and wait for the service restart to switch to surfacefligner
- if (mLockPatternView != null) {
- mLockPatternView.removeCallbacks(mClearPatternRunnable);
- mLockPatternView.postDelayed(mClearPatternRunnable, RIGHT_PATTERN_CLEAR_TIMEOUT_MS);
- }
- final TextView status = (TextView) findViewById(R.id.status);
- status.setText(R.string.starting_android);
- hide(R.id.passwordEntry);
- hide(R.id.switch_ime_button);
- hide(R.id.lockPattern);
- hide(R.id.owner_info);
- hide(R.id.emergencyCallButton);
- } else if (failedAttempts == MAX_FAILED_ATTEMPTS) {
- // Factory reset the device.
- Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
- intent.setPackage("android");
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- intent.putExtra(Intent.EXTRA_REASON, "CryptKeeper.MAX_FAILED_ATTEMPTS");
- sendBroadcast(intent);
- } else if (failedAttempts == -1) {
- // Right password, but decryption failed. Tell user bad news ...
- setContentView(R.layout.crypt_keeper_progress);
- showFactoryReset(true);
- return;
- } else {
- handleBadAttempt(failedAttempts);
- }
- }
- }
-
- private void beginAttempt() {
- final TextView status = (TextView) findViewById(R.id.status);
- status.setText(R.string.checking_decryption);
- }
-
- private void handleBadAttempt(Integer failedAttempts) {
- // Wrong entry. Handle pattern case.
- if (mLockPatternView != null) {
- mLockPatternView.setDisplayMode(DisplayMode.Wrong);
- mLockPatternView.removeCallbacks(mClearPatternRunnable);
- mLockPatternView.postDelayed(mClearPatternRunnable, WRONG_PATTERN_CLEAR_TIMEOUT_MS);
- }
- if ((failedAttempts % COOL_DOWN_ATTEMPTS) == 0) {
- mCooldown = true;
- // No need to setBackFunctionality(false) - it's already done
- // at this point.
- cooldown();
- } else {
- final TextView status = (TextView) findViewById(R.id.status);
-
- int remainingAttempts = MAX_FAILED_ATTEMPTS - failedAttempts;
- if (remainingAttempts < COOL_DOWN_ATTEMPTS) {
- CharSequence warningTemplate = getText(R.string.crypt_keeper_warn_wipe);
- CharSequence warning = TextUtils.expandTemplate(warningTemplate,
- Integer.toString(remainingAttempts));
- status.setText(warning);
- } else {
- int passwordType = StorageManager.CRYPT_TYPE_PASSWORD;
- try {
- final IStorageManager service = getStorageManager();
- passwordType = service.getPasswordType();
- } catch (Exception e) {
- Log.e(TAG, "Error calling mount service " + e);
- }
-
- if (passwordType == StorageManager.CRYPT_TYPE_PIN) {
- status.setText(R.string.cryptkeeper_wrong_pin);
- } else if (passwordType == StorageManager.CRYPT_TYPE_PATTERN) {
- status.setText(R.string.cryptkeeper_wrong_pattern);
- } else {
- status.setText(R.string.cryptkeeper_wrong_password);
- }
- }
-
- if (mLockPatternView != null) {
- mLockPatternView.setDisplayMode(DisplayMode.Wrong);
- mLockPatternView.setEnabled(true);
- }
-
- // Reenable the password entry
- if (mPasswordEntry != null) {
- mPasswordEntry.setEnabled(true);
- mPasswordEntry.scheduleShowSoftInput();
- setBackFunctionality(true);
- }
- }
- }
-
- private class ValidationTask extends AsyncTask<Void, Void, Boolean> {
- int state;
-
- @Override
- protected Boolean doInBackground(Void... params) {
- final IStorageManager service = getStorageManager();
- try {
- Log.d(TAG, "Validating encryption state.");
- state = service.getEncryptionState();
- if (state == StorageManager.ENCRYPTION_STATE_NONE) {
- Log.w(TAG, "Unexpectedly in CryptKeeper even though there is no encryption.");
- return true; // Unexpected, but fine, I guess...
- }
- return state == StorageManager.ENCRYPTION_STATE_OK;
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to get encryption state properly");
- return true;
- }
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- mValidationComplete = true;
- if (Boolean.FALSE.equals(result)) {
- Log.w(TAG, "Incomplete, or corrupted encryption detected. Prompting user to wipe.");
- mEncryptionGoneBad = true;
- mCorrupt = state == StorageManager.ENCRYPTION_STATE_ERROR_CORRUPT;
- } else {
- Log.d(TAG, "Encryption state validated. Proceeding to configure UI");
- }
- setupUi();
- }
- }
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_UPDATE_PROGRESS:
- updateProgress();
- break;
-
- case MESSAGE_NOTIFY:
- notifyUser();
- break;
- }
- }
- };
-
- private AudioManager mAudioManager;
- /** The status bar where back/home/recent buttons are shown. */
- private StatusBarManager mStatusBar;
-
- /** All the widgets to disable in the status bar */
- final private static int sWidgetsToDisable = StatusBarManager.DISABLE_EXPAND
- | StatusBarManager.DISABLE_NOTIFICATION_ICONS
- | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
- | StatusBarManager.DISABLE_HOME
- | StatusBarManager.DISABLE_SEARCH
- | StatusBarManager.DISABLE_RECENT;
-
- protected static final int MIN_LENGTH_BEFORE_REPORT = LockPatternUtils.MIN_LOCK_PATTERN_SIZE;
-
- /** @return whether or not this Activity was started for debugging the UI only. */
- private boolean isDebugView() {
- return getIntent().hasExtra(EXTRA_FORCE_VIEW);
- }
-
- /** @return whether or not this Activity was started for debugging the specific UI view only. */
- private boolean isDebugView(String viewType /* non-nullable */) {
- return viewType.equals(getIntent().getStringExtra(EXTRA_FORCE_VIEW));
- }
-
- /**
- * Notify the user that we are awaiting input. Currently this sends an audio alert.
- */
- private void notifyUser() {
- if (mNotificationCountdown > 0) {
- --mNotificationCountdown;
- } else if (mAudioManager != null) {
- try {
- // Play the standard keypress sound at full volume. This should be available on
- // every device. We cannot play a ringtone here because media services aren't
- // available yet. A DTMF-style tone is too soft to be noticed, and might not exist
- // on tablet devices. The idea is to alert the user that something is needed: this
- // does not have to be pleasing.
- mAudioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD, 100);
- } catch (Exception e) {
- Log.w(TAG, "notifyUser: Exception while playing sound: " + e);
- }
- }
- // Notify the user again in 5 seconds.
- mHandler.removeMessages(MESSAGE_NOTIFY);
- mHandler.sendEmptyMessageDelayed(MESSAGE_NOTIFY, 5 * 1000);
-
- if (mWakeLock.isHeld()) {
- if (mReleaseWakeLockCountdown > 0) {
- --mReleaseWakeLockCountdown;
- } else {
- mWakeLock.release();
- }
- }
- }
-
- /**
- * Ignore back events from this activity always - there's nowhere to go back
- * to
- */
- @Override
- public void onBackPressed() {
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // If we are not encrypted or encrypting, get out quickly.
- final String state = VoldProperties.decrypt().orElse("");
- if (!isDebugView() && ("".equals(state) || DECRYPT_STATE.equals(state))) {
- disableCryptKeeperComponent(this);
- // Typically CryptKeeper is launched as the home app. We didn't
- // want to be running, so need to finish this activity. We can count
- // on the activity manager re-launching the new home app upon finishing
- // this one, since this will leave the activity stack empty.
- // NOTE: This is really grungy. I think it would be better for the
- // activity manager to explicitly launch the crypt keeper instead of
- // home in the situation where we need to decrypt the device
- finish();
- return;
- }
-
- try {
- if (getResources().getBoolean(R.bool.crypt_keeper_allow_rotation)) {
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- }
- } catch (NotFoundException e) {
- }
-
- // Disable the status bar, but do NOT disable back because the user needs a way to go
- // from keyboard settings and back to the password screen.
- mStatusBar = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
- mStatusBar.disable(sWidgetsToDisable);
-
- if (savedInstanceState != null) {
- mCooldown = savedInstanceState.getBoolean(STATE_COOLDOWN);
- }
-
- setAirplaneModeIfNecessary();
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- // Check for (and recover) retained instance data
- final Object lastInstance = getLastNonConfigurationInstance();
- if (lastInstance instanceof NonConfigurationInstanceState) {
- NonConfigurationInstanceState retained = (NonConfigurationInstanceState) lastInstance;
- mWakeLock = retained.wakelock;
- Log.d(TAG, "Restoring wakelock from NonConfigurationInstanceState");
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle savedInstanceState) {
- savedInstanceState.putBoolean(STATE_COOLDOWN, mCooldown);
- }
-
- /**
- * Note, we defer the state check and screen setup to onStart() because this will be
- * re-run if the user clicks the power button (sleeping/waking the screen), and this is
- * especially important if we were to lose the wakelock for any reason.
- */
- @Override
- public void onStart() {
- super.onStart();
- setupUi();
- }
-
- /**
- * Initializes the UI based on the current state of encryption.
- * This is idempotent - calling repeatedly will simply re-initialize the UI.
- */
- private void setupUi() {
- if (mEncryptionGoneBad || isDebugView(FORCE_VIEW_ERROR)) {
- setContentView(R.layout.crypt_keeper_progress);
- showFactoryReset(mCorrupt);
- return;
- }
-
- final String progress = VoldProperties.encrypt_progress().orElse("");
- if (!"".equals(progress) || isDebugView(FORCE_VIEW_PROGRESS)) {
- setContentView(R.layout.crypt_keeper_progress);
- encryptionProgressInit();
- } else if (mValidationComplete || isDebugView(FORCE_VIEW_PASSWORD)) {
- new AsyncTask<Void, Void, Void>() {
- int passwordType = StorageManager.CRYPT_TYPE_PASSWORD;
- String owner_info;
- boolean pattern_visible;
- boolean password_visible;
-
- @Override
- public Void doInBackground(Void... v) {
- try {
- final IStorageManager service = getStorageManager();
- passwordType = service.getPasswordType();
- owner_info = service.getField(StorageManager.OWNER_INFO_KEY);
- pattern_visible = !("0".equals(service.getField(StorageManager.PATTERN_VISIBLE_KEY)));
- password_visible = !("0".equals(service.getField(StorageManager.PASSWORD_VISIBLE_KEY)));
- } catch (Exception e) {
- Log.e(TAG, "Error calling mount service " + e);
- }
-
- return null;
- }
-
- @Override
- public void onPostExecute(java.lang.Void v) {
- Settings.System.putInt(getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD,
- password_visible ? 1 : 0);
-
- if (passwordType == StorageManager.CRYPT_TYPE_PIN) {
- setContentView(R.layout.crypt_keeper_pin_entry);
- mStatusString = R.string.enter_pin;
- } else if (passwordType == StorageManager.CRYPT_TYPE_PATTERN) {
- setContentView(R.layout.crypt_keeper_pattern_entry);
- setBackFunctionality(false);
- mStatusString = R.string.enter_pattern;
- } else {
- setContentView(R.layout.crypt_keeper_password_entry);
- mStatusString = R.string.enter_password;
- }
- final TextView status = (TextView) findViewById(R.id.status);
- status.setText(mStatusString);
-
- final TextView ownerInfo = (TextView) findViewById(R.id.owner_info);
- ownerInfo.setText(owner_info);
- ownerInfo.setSelected(true); // Required for marquee'ing to work
-
- passwordEntryInit();
-
- findViewById(android.R.id.content).setSystemUiVisibility(View.STATUS_BAR_DISABLE_BACK);
-
- if (mLockPatternView != null) {
- mLockPatternView.setInStealthMode(!pattern_visible);
- }
- if (mCooldown) {
- // in case we are cooling down and coming back from emergency dialler
- setBackFunctionality(false);
- cooldown();
- }
-
- }
- }.execute();
- } else if (!mValidationRequested) {
- // We're supposed to be encrypted, but no validation has been done.
- new ValidationTask().execute((Void[]) null);
- mValidationRequested = true;
- }
- }
-
- @Override
- public void onStop() {
- super.onStop();
- mHandler.removeMessages(MESSAGE_UPDATE_PROGRESS);
- mHandler.removeMessages(MESSAGE_NOTIFY);
- }
-
- /**
- * Reconfiguring, so propagate the wakelock to the next instance. This runs between onStop()
- * and onDestroy() and only if we are changing configuration (e.g. rotation). Also clears
- * mWakeLock so the subsequent call to onDestroy does not release it.
- */
- @Override
- public Object onRetainNonConfigurationInstance() {
- NonConfigurationInstanceState state = new NonConfigurationInstanceState(mWakeLock);
- Log.d(TAG, "Handing wakelock off to NonConfigurationInstanceState");
- mWakeLock = null;
- return state;
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- if (mWakeLock != null) {
- Log.d(TAG, "Releasing and destroying wakelock");
- mWakeLock.release();
- mWakeLock = null;
- }
- }
-
- /**
- * Start encrypting the device.
- */
- private void encryptionProgressInit() {
- // Accquire a partial wakelock to prevent the device from sleeping. Note
- // we never release this wakelock as we will be restarted after the device
- // is encrypted.
- Log.d(TAG, "Encryption progress screen initializing.");
- if (mWakeLock == null) {
- Log.d(TAG, "Acquiring wakelock.");
- PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
- mWakeLock.acquire();
- }
-
- ((ProgressBar) findViewById(R.id.progress_bar)).setIndeterminate(true);
- // Ignore all back presses from now, both hard and soft keys.
- setBackFunctionality(false);
- // Start the first run of progress manually. This method sets up messages to occur at
- // repeated intervals.
- updateProgress();
- }
-
- /**
- * Show factory reset screen allowing the user to reset their phone when
- * there is nothing else we can do
- * @param corrupt true if userdata is corrupt, false if encryption failed
- * partway through
- */
- private void showFactoryReset(final boolean corrupt) {
- // Hide the encryption-bot to make room for the "factory reset" button
- findViewById(R.id.encroid).setVisibility(View.GONE);
-
- // Show the reset button, failure text, and a divider
- final Button button = (Button) findViewById(R.id.factory_reset);
- button.setVisibility(View.VISIBLE);
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // Factory reset the device.
- Intent intent = new Intent(Intent.ACTION_FACTORY_RESET);
- intent.setPackage("android");
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- intent.putExtra(Intent.EXTRA_REASON,
- "CryptKeeper.showFactoryReset() corrupt=" + corrupt);
- sendBroadcast(intent);
- }
- });
-
- // Alert the user of the failure.
- if (corrupt) {
- ((TextView) findViewById(R.id.title)).setText(R.string.crypt_keeper_data_corrupt_title);
- ((TextView) findViewById(R.id.status)).setText(R.string.crypt_keeper_data_corrupt_summary);
- } else {
- ((TextView) findViewById(R.id.title)).setText(R.string.crypt_keeper_failed_title);
- ((TextView) findViewById(R.id.status)).setText(R.string.crypt_keeper_failed_summary);
- }
-
- final View view = findViewById(R.id.bottom_divider);
- // TODO(viki): Why would the bottom divider be missing in certain layouts? Investigate.
- if (view != null) {
- view.setVisibility(View.VISIBLE);
- }
- }
-
- private void updateProgress() {
- final String state = VoldProperties.encrypt_progress().orElse("");
-
- if ("error_partially_encrypted".equals(state)) {
- showFactoryReset(false);
- return;
- }
-
- // Get status as percentage first
- CharSequence status = getText(R.string.crypt_keeper_setup_description);
- int percent = 0;
- try {
- // Force a 50% progress state when debugging the view.
- percent = isDebugView() ? 50 : Integer.parseInt(state);
- } catch (Exception e) {
- Log.w(TAG, "Error parsing progress: " + e.toString());
- }
- String progress = Integer.toString(percent);
-
- // Now try to get status as time remaining and replace as appropriate
- Log.v(TAG, "Encryption progress: " + progress);
- try {
- int time = VoldProperties.encrypt_time_remaining().get();
- if (time >= 0) {
- // Round up to multiple of 10 - this way display is less jerky
- time = (time + 9) / 10 * 10;
- progress = DateUtils.formatElapsedTime(time);
- status = getText(R.string.crypt_keeper_setup_time_remaining);
- }
- } catch (Exception e) {
- // Will happen if no time etc - show percentage
- }
-
- final TextView tv = (TextView) findViewById(R.id.status);
- if (tv != null) {
- tv.setText(TextUtils.expandTemplate(status, progress));
- }
-
- // Check the progress every 1 seconds
- mHandler.removeMessages(MESSAGE_UPDATE_PROGRESS);
- mHandler.sendEmptyMessageDelayed(MESSAGE_UPDATE_PROGRESS, 1000);
- }
-
- /** Insist on a power cycle to force the user to waste time between retries.
- *
- * Call setBackFunctionality(false) before calling this. */
- private void cooldown() {
- // Disable the password entry.
- if (mPasswordEntry != null) {
- mPasswordEntry.setEnabled(false);
- }
- if (mLockPatternView != null) {
- mLockPatternView.setEnabled(false);
- }
-
- final TextView status = (TextView) findViewById(R.id.status);
- status.setText(R.string.crypt_keeper_force_power_cycle);
- }
-
- /**
- * Sets the back status: enabled or disabled according to the parameter.
- * @param isEnabled true if back is enabled, false otherwise.
- */
- private final void setBackFunctionality(boolean isEnabled) {
- if (isEnabled) {
- mStatusBar.disable(sWidgetsToDisable);
- } else {
- mStatusBar.disable(sWidgetsToDisable | StatusBarManager.DISABLE_BACK);
- }
- }
-
- private void fakeUnlockAttempt(View postingView) {
- beginAttempt();
- postingView.postDelayed(mFakeUnlockAttemptRunnable, FAKE_ATTEMPT_DELAY);
- }
-
- protected LockPatternView.OnPatternListener mChooseNewLockPatternListener =
- new LockPatternView.OnPatternListener() {
-
- @Override
- public void onPatternStart() {
- mLockPatternView.removeCallbacks(mClearPatternRunnable);
- }
-
- @Override
- public void onPatternCleared() {
- }
-
- @Override
- public void onPatternDetected(List<LockPatternView.Cell> pattern) {
- mLockPatternView.setEnabled(false);
- if (pattern.size() >= MIN_LENGTH_BEFORE_REPORT) {
- new DecryptTask().execute(new String(LockPatternUtils.patternToByteArray(pattern)));
- } else {
- // Allow user to make as many of these as they want.
- fakeUnlockAttempt(mLockPatternView);
- }
- }
-
- @Override
- public void onPatternCellAdded(List<Cell> pattern) {
- }
- };
-
- private void passwordEntryInit() {
- // Password/pin case
- mPasswordEntry = (ImeAwareEditText) findViewById(R.id.passwordEntry);
- if (mPasswordEntry != null){
- mPasswordEntry.setOnEditorActionListener(this);
- mPasswordEntry.requestFocus();
- // Become quiet when the user interacts with the Edit text screen.
- mPasswordEntry.setOnKeyListener(this);
- mPasswordEntry.setOnTouchListener(this);
- mPasswordEntry.addTextChangedListener(this);
- }
-
- // Pattern case
- mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
- if (mLockPatternView != null) {
- mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
- }
-
- // Disable the Emergency call button if the device has no voice telephone capability
- if (!getTelephonyManager().isVoiceCapable()) {
- final View emergencyCall = findViewById(R.id.emergencyCallButton);
- if (emergencyCall != null) {
- Log.d(TAG, "Removing the emergency Call button");
- emergencyCall.setVisibility(View.GONE);
- }
- }
-
- final View imeSwitcher = findViewById(R.id.switch_ime_button);
- final InputMethodManager imm = (InputMethodManager) getSystemService(
- Context.INPUT_METHOD_SERVICE);
- if (imeSwitcher != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
- imeSwitcher.setVisibility(View.VISIBLE);
- imeSwitcher.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- imm.showInputMethodPickerFromSystem(false /* showAuxiliarySubtypes */,
- v.getDisplay().getDisplayId());
- }
- });
- }
-
- // We want to keep the screen on while waiting for input. In minimal boot mode, the device
- // is completely non-functional, and we want the user to notice the device and enter a
- // password.
- if (mWakeLock == null) {
- Log.d(TAG, "Acquiring wakelock.");
- final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- if (pm != null) {
- mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
- mWakeLock.acquire();
- // Keep awake for 10 minutes - if the user hasn't been alerted by then
- // best not to just drain their battery
- mReleaseWakeLockCountdown = 96; // 96 * 5 secs per click + 120 secs before we show this = 600
- }
- }
-
- // Make sure that the IME is shown when everything becomes ready.
- if (mLockPatternView == null && !mCooldown) {
- getWindow().setSoftInputMode(
- WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
- if (mPasswordEntry != null) {
- mPasswordEntry.scheduleShowSoftInput();
- }
- }
-
- updateEmergencyCallButtonState();
- // Notify the user in 120 seconds that we are waiting for him to enter the password.
- mHandler.removeMessages(MESSAGE_NOTIFY);
- mHandler.sendEmptyMessageDelayed(MESSAGE_NOTIFY, 120 * 1000);
-
- // Dismiss secure & non-secure keyguards while this screen is showing.
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
- | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
- }
-
- /**
- * Method adapted from com.android.inputmethod.latin.Utils
- *
- * @param imm The input method manager
- * @param shouldIncludeAuxiliarySubtypes
- * @return true if we have multiple IMEs to choose from
- */
- private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
- final boolean shouldIncludeAuxiliarySubtypes) {
- final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
-
- // Number of the filtered IMEs
- int filteredImisCount = 0;
-
- for (InputMethodInfo imi : enabledImis) {
- // We can return true immediately after we find two or more filtered IMEs.
- if (filteredImisCount > 1) return true;
- final List<InputMethodSubtype> subtypes =
- imm.getEnabledInputMethodSubtypeList(imi, true);
- // IMEs that have no subtypes should be counted.
- if (subtypes.isEmpty()) {
- ++filteredImisCount;
- continue;
- }
-
- int auxCount = 0;
- for (InputMethodSubtype subtype : subtypes) {
- if (subtype.isAuxiliary()) {
- ++auxCount;
- }
- }
- final int nonAuxCount = subtypes.size() - auxCount;
-
- // IMEs that have one or more non-auxiliary subtypes should be counted.
- // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
- // subtypes should be counted as well.
- if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
- ++filteredImisCount;
- continue;
- }
- }
-
- return filteredImisCount > 1
- // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
- // input method subtype (The current IME should be LatinIME.)
- || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
- }
-
- private IStorageManager getStorageManager() {
- final IBinder service = ServiceManager.getService("mount");
- if (service != null) {
- return IStorageManager.Stub.asInterface(service);
- }
- return null;
- }
-
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE) {
- // Get the password
- final String password = v.getText().toString();
-
- if (TextUtils.isEmpty(password)) {
- return true;
- }
-
- // Now that we have the password clear the password field.
- v.setText(null);
-
- // Disable the password entry and back keypress while checking the password. These
- // we either be re-enabled if the password was wrong or after the cooldown period.
- mPasswordEntry.setEnabled(false);
- setBackFunctionality(false);
-
- if (password.length() >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) {
- new DecryptTask().execute(password);
- } else {
- // Allow user to make as many of these as they want.
- fakeUnlockAttempt(mPasswordEntry);
- }
-
- return true;
- }
- return false;
- }
-
- /**
- * Set airplane mode on the device if it isn't an LTE device.
- * Full story: In minimal boot mode, we cannot save any state. In particular, we cannot save
- * any incoming SMS's. So SMSs that are received here will be silently dropped to the floor.
- * That is bad. Also, we cannot receive any telephone calls in this state. So to avoid
- * both these problems, we turn the radio off. However, on certain networks turning on and
- * off the radio takes a long time. In such cases, we are better off leaving the radio
- * running so the latency of an E911 call is short.
- * The behavior after this is:
- * 1. Emergency dialing: the emergency dialer has logic to force the device out of
- * airplane mode and restart the radio.
- * 2. Full boot: we read the persistent settings from the previous boot and restore the
- * radio to whatever it was before it restarted. This also happens when rebooting a
- * phone that has no encryption.
- */
- private final void setAirplaneModeIfNecessary() {
- if (!getTelephonyManager().isLteCdmaEvdoGsmWcdmaEnabled()) {
- Log.d(TAG, "Going into airplane mode.");
- Settings.Global.putInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 1);
- final Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", true);
- sendBroadcastAsUser(intent, UserHandle.ALL);
- }
- }
-
- /**
- * Code to update the state of, and handle clicks from, the "Emergency call" button.
- *
- * This code is mostly duplicated from the corresponding code in
- * LockPatternUtils and LockPatternKeyguardView under frameworks/base.
- */
- private void updateEmergencyCallButtonState() {
- final Button emergencyCall = (Button) findViewById(R.id.emergencyCallButton);
- // The button isn't present at all in some configurations.
- if (emergencyCall == null)
- return;
-
- if (isEmergencyCallCapable()) {
- emergencyCall.setVisibility(View.VISIBLE);
- emergencyCall.setOnClickListener(new View.OnClickListener() {
- @Override
-
- public void onClick(View v) {
- takeEmergencyCallAction();
- }
- });
- } else {
- emergencyCall.setVisibility(View.GONE);
- return;
- }
-
- int textId;
- if (getTelecomManager().isInCall()) {
- // Show "return to call"
- textId = R.string.cryptkeeper_return_to_call;
- } else {
- textId = R.string.cryptkeeper_emergency_call;
- }
- emergencyCall.setText(textId);
- }
-
- private boolean isEmergencyCallCapable() {
- return getTelephonyManager().isVoiceCapable();
- }
-
- private void takeEmergencyCallAction() {
- TelecomManager telecomManager = getTelecomManager();
- if (telecomManager.isInCall()) {
- telecomManager.showInCallScreen(false /* showDialpad */);
- } else {
- launchEmergencyDialer();
- }
- }
-
-
- private void launchEmergencyDialer() {
- final Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- setBackFunctionality(true);
- startActivity(intent);
- }
-
- private TelephonyManager getTelephonyManager() {
- return (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
- }
-
- private TelecomManager getTelecomManager() {
- return (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
- }
-
- /**
- * Listen to key events so we can disable sounds when we get a keyinput in EditText.
- */
- private void delayAudioNotification() {
- mNotificationCountdown = 20;
- }
-
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- delayAudioNotification();
- return false;
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- delayAudioNotification();
- return false;
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- return;
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- delayAudioNotification();
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- return;
- }
-
- private static void disableCryptKeeperComponent(Context context) {
- PackageManager pm = context.getPackageManager();
- ComponentName name = new ComponentName(context, CryptKeeper.class);
- Log.d(TAG, "Disabling component " + name);
- pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- }
-}
diff --git a/src/com/android/settings/CryptKeeperConfirm.java b/src/com/android/settings/CryptKeeperConfirm.java
deleted file mode 100644
index 49d027b..0000000
--- a/src/com/android/settings/CryptKeeperConfirm.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2011 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;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.StatusBarManager;
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.os.storage.IStorageManager;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.core.InstrumentedFragment;
-
-import java.util.Arrays;
-import java.util.Locale;
-
-public class CryptKeeperConfirm extends InstrumentedFragment {
-
- private static final String TAG = "CryptKeeperConfirm";
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.CRYPT_KEEPER_CONFIRM;
- }
-
- public static class Blank extends Activity {
- private Handler mHandler = new Handler();
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.crypt_keeper_blank);
-
- if (Utils.isMonkeyRunning()) {
- finish();
- }
-
- StatusBarManager sbm = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
- sbm.disable(StatusBarManager.DISABLE_EXPAND
- | StatusBarManager.DISABLE_NOTIFICATION_ICONS
- | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
- | StatusBarManager.DISABLE_SYSTEM_INFO
- | StatusBarManager.DISABLE_HOME
- | StatusBarManager.DISABLE_SEARCH
- | StatusBarManager.DISABLE_RECENT
- | StatusBarManager.DISABLE_BACK);
-
- // Post a delayed message in 700 milliseconds to enable encryption.
- // NOTE: The animation on this activity is set for 500 milliseconds
- // I am giving it a little extra time to complete.
- mHandler.postDelayed(new Runnable() {
- public void run() {
- IBinder service = ServiceManager.getService("mount");
- if (service == null) {
- Log.e("CryptKeeper", "Failed to find the mount service");
- finish();
- return;
- }
-
- IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
- try {
- Bundle args = getIntent().getExtras();
- // TODO(b/120484642): Update vold to accept a password as a byte array
- byte[] passwordBytes = args.getByteArray("password");
- String password = passwordBytes != null ? new String(passwordBytes) : null;
- Arrays.fill(passwordBytes, (byte) 0);
- storageManager.encryptStorage(args.getInt("type", -1),
- password);
- } catch (Exception e) {
- Log.e("CryptKeeper", "Error while encrypting...", e);
- }
- }
- }, 700);
- }
- }
-
- private View mContentView;
- private Button mFinalButton;
- private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
-
- public void onClick(View v) {
- if (Utils.isMonkeyRunning()) {
- return;
- }
-
- /* WARNING - nasty hack!
- Settings for the lock screen are not available to the crypto
- screen (CryptKeeper) at boot. We duplicate the ones that
- CryptKeeper needs to the crypto key/value store when they are
- modified (see LockPatternUtils).
- However, prior to encryption, the crypto key/value store is not
- persisted across reboots, thus modified settings are lost to
- CryptKeeper.
- In order to make sure CryptKeeper had the correct settings after
- first encrypting, we thus need to rewrite them, which ensures the
- crypto key/value store is up to date. On encryption, this store
- is then persisted, and the settings will be there on future
- reboots.
- */
-
- // 1. The owner info.
- LockPatternUtils utils = new LockPatternUtils(getActivity());
- utils.setVisiblePatternEnabled(
- utils.isVisiblePatternEnabled(UserHandle.USER_SYSTEM),
- UserHandle.USER_SYSTEM);
- if (utils.isOwnerInfoEnabled(UserHandle.USER_SYSTEM)) {
- utils.setOwnerInfo(utils.getOwnerInfo(UserHandle.USER_SYSTEM),
- UserHandle.USER_SYSTEM);
- }
- int value = Settings.System.getInt(getContext().getContentResolver(),
- Settings.System.TEXT_SHOW_PASSWORD,
- 1);
- utils.setVisiblePasswordEnabled(value != 0, UserHandle.USER_SYSTEM);
-
- Intent intent = new Intent(getActivity(), Blank.class);
- intent.putExtras(getArguments());
- startActivity(intent);
-
- // 2. The system locale.
- try {
- IBinder service = ServiceManager.getService("mount");
- IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
- storageManager.setField("SystemLocale", Locale.getDefault().toLanguageTag());
- } catch (Exception e) {
- Log.e(TAG, "Error storing locale for decryption UI", e);
- }
- }
- };
-
- private void establishFinalConfirmationState() {
- mFinalButton = (Button) mContentView.findViewById(R.id.execute_encrypt);
- mFinalButton.setOnClickListener(mFinalClickListener);
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getActivity().setTitle(R.string.crypt_keeper_confirm_title);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- mContentView = inflater.inflate(R.layout.crypt_keeper_confirm, null);
- establishFinalConfirmationState();
- return mContentView;
- }
-}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 61d1180..bf655ae 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -255,7 +255,6 @@
public static class BatterySaverScheduleSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccountSyncSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccountSyncSettingsInAddAccountActivity extends SettingsActivity { /* empty */ }
- public static class CryptKeeperSettingsActivity extends SettingsActivity { /* empty */ }
public static class DeviceAdminSettingsActivity extends SettingsActivity { /* empty */ }
public static class DataUsageSummaryActivity extends SettingsActivity { /* empty */ }
public static class MobileDataUsageListActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsDumpService.java b/src/com/android/settings/SettingsDumpService.java
index 7e37e32..38987f5 100644
--- a/src/com/android/settings/SettingsDumpService.java
+++ b/src/com/android/settings/SettingsDumpService.java
@@ -35,6 +35,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.settings.applications.ProcStatsData;
+import com.android.settings.datausage.lib.DataUsageLib;
import com.android.settings.fuelgauge.batterytip.AnomalyConfigJobService;
import com.android.settingslib.net.DataUsageController;
@@ -109,14 +110,8 @@
if (telephonyManager.isDataCapable()) {
JSONArray array = new JSONArray();
for (SubscriptionInfo info : manager.getAvailableSubscriptionInfoList()) {
- telephonyManager = telephonyManager
- .createForSubscriptionId(info.getSubscriptionId());
- String subscriberId = telephonyManager.getSubscriberId();
- // The null subscriberId means that no any mobile/carrier network will be matched.
- // Using old API: buildTemplateMobileAll for the null subscriberId to avoid NPE.
- NetworkTemplate template = subscriberId != null
- ? NetworkTemplate.buildTemplateCarrierMetered(subscriberId)
- : NetworkTemplate.buildTemplateMobileAll(subscriberId);
+ NetworkTemplate template = DataUsageLib.getMobileTemplateForSubId(
+ telephonyManager, info.getSubscriptionId());
final JSONObject usage = dumpDataUsage(template, controller);
usage.put("subId", info.getSubscriptionId());
array.put(usage);
@@ -125,12 +120,12 @@
}
if (packageManager.hasSystemFeature(FEATURE_WIFI)) {
obj.put("wifi", dumpDataUsage(
- NetworkTemplate.buildTemplateWifi(
- NetworkTemplate.WIFI_NETWORKID_ALL, null /* subscriberId */), controller));
+ new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build(), controller));
}
if (packageManager.hasSystemFeature(FEATURE_ETHERNET)) {
- obj.put("ethernet", dumpDataUsage(NetworkTemplate.buildTemplateEthernet(), controller));
+ obj.put("ethernet", dumpDataUsage(new NetworkTemplate.Builder(
+ NetworkTemplate.MATCH_ETHERNET).build(), controller));
}
return obj;
}
diff --git a/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java b/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java
new file mode 100644
index 0000000..a4986a0
--- /dev/null
+++ b/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindow.java
@@ -0,0 +1,154 @@
+/*
+ * 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.content.res.Resources;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Handler;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+
+/**
+ * UI container for the accessibility quick settings tooltip.
+ *
+ * <p> The popup window shows the information about the operation of the quick settings. In
+ * addition, the arrow is pointing to the top center of the device to display one-off menu within
+ * {@code mCloseDelayTimeMillis} time.</p>
+ */
+public class AccessibilityQuickSettingsTooltipWindow extends PopupWindow {
+
+ private final Context mContext;
+ private Handler mHandler;
+ private long mCloseDelayTimeMillis;
+
+ public AccessibilityQuickSettingsTooltipWindow(Context context) {
+ super(context);
+ this.mContext = context;
+ }
+
+ /**
+ * Sets up {@link #AccessibilityQuickSettingsTooltipWindow}'s layout and content.
+ *
+ * @param text text to be displayed
+ */
+ public void setup(String text) {
+ this.setup(text, /* closeDelayTimeMillis= */ 0);
+ }
+
+ /**
+ * Sets up {@link #AccessibilityQuickSettingsTooltipWindow}'s layout and content.
+ *
+ * <p> The system will attempt to close popup window to the target duration of the threads if
+ * close delay time is positive number. </p>
+ *
+ * @param text text to be displayed
+ * @param closeDelayTimeMillis how long the popup window be auto-closed
+ */
+ public void setup(String text, long closeDelayTimeMillis) {
+ this.mCloseDelayTimeMillis = closeDelayTimeMillis;
+
+ setBackgroundDrawable(new ColorDrawable(mContext.getColor(android.R.color.transparent)));
+ final LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class);
+ final View popupView =
+ inflater.inflate(R.layout.accessibility_qs_tooltips, /* root= */ null);
+ setContentView(popupView);
+ final TextView textView = getContentView().findViewById(R.id.qs_content);
+ textView.setText(text);
+
+ setWidth(getWindowWidthWith(textView));
+ setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
+ setFocusable(/* focusable= */ true);
+ }
+
+ /**
+ * Displays the content view in a popup window at the top and center position.
+ *
+ * @param targetView a target view to get the {@link View#getWindowToken()} token from.
+ */
+ public void showAtTopCenter(View targetView) {
+ showAtLocation(targetView, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
+ }
+
+ /**
+ * Disposes of the popup window.
+ *
+ * <p> Remove any pending posts of callbacks and sent messages for closing popup window. </p>
+ */
+ @Override
+ public void dismiss() {
+ super.dismiss();
+ if (mHandler != null) {
+ mHandler.removeCallbacksAndMessages(/* token= */ null);
+ }
+ }
+
+ /**
+ * Displays the content view in a popup window at the specified location.
+ *
+ * <p> The system will attempt to close popup window to the target duration of the threads if
+ * close delay time is positive number. </p>
+ *
+ * @param parent a parent view to get the {@link android.view.View#getWindowToken()} token from
+ * @param gravity the gravity which controls the placement of the popup window
+ * @param x the popup's x location offset
+ * @param y the popup's y location offset
+ */
+ @Override
+ public void showAtLocation(View parent, int gravity, int x, int y) {
+ super.showAtLocation(parent, gravity, x, y);
+ scheduleAutoCloseAction();
+ }
+
+ private void scheduleAutoCloseAction() {
+ if (mCloseDelayTimeMillis <= 0) {
+ return;
+ }
+
+ if (mHandler == null) {
+ mHandler = new Handler(mContext.getMainLooper());
+ }
+ mHandler.removeCallbacksAndMessages(/* token= */ null);
+ mHandler.postDelayed(this::dismiss, mCloseDelayTimeMillis);
+ }
+
+ private int getWindowWidthWith(TextView textView) {
+ final int availableWindowWidth = getAvailableWindowWidth();
+ final int widthSpec =
+ View.MeasureSpec.makeMeasureSpec(availableWindowWidth, View.MeasureSpec.AT_MOST);
+ final int heightSpec =
+ View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+ textView.measure(widthSpec, heightSpec);
+ return textView.getMeasuredWidth();
+ }
+
+ @VisibleForTesting
+ int getAvailableWindowWidth() {
+ final Resources res = mContext.getResources();
+ final int padding = res.getDimensionPixelSize(R.dimen.accessibility_qs_tooltips_margin);
+ final int screenWidth = res.getDisplayMetrics().widthPixels;
+ return screenWidth - padding * 2;
+ }
+}
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index dcf7897..93ec8030 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
-import android.os.storage.StorageManager;
import android.text.BidiFormatter;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -86,16 +85,6 @@
return ad;
}
- /**
- * Returns whether the device is encrypted with legacy full disk encryption. Newer devices
- * should be using File Based Encryption.
- *
- * @return true if device is encrypted
- */
- private static boolean isFullDiskEncrypted() {
- return StorageManager.isNonDefaultBlockEncrypted();
- }
-
private static View createEnableDialogContentView(Context context,
@NonNull AccessibilityServiceInfo info, View.OnClickListener listener,
UninstallActionPerformer performer) {
@@ -105,17 +94,6 @@
View content = inflater.inflate(R.layout.enable_accessibility_service_dialog_content,
null);
- TextView encryptionWarningView = (TextView) content.findViewById(
- R.id.encryption_warning);
- if (isFullDiskEncrypted()) {
- String text = context.getString(R.string.enable_service_encryption_warning,
- getServiceName(context, info));
- encryptionWarningView.setText(text);
- encryptionWarningView.setVisibility(View.VISIBLE);
- } else {
- encryptionWarningView.setVisibility(View.GONE);
- }
-
final Drawable icon;
if (info.getResolveInfo().getIconResource() == 0) {
icon = ContextCompat.getDrawable(context, R.drawable.ic_accessibility_generic);
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java
index 4030e0d..8e8c7e4 100644
--- a/src/com/android/settings/accessibility/AccessibilitySettings.java
+++ b/src/com/android/settings/accessibility/AccessibilitySettings.java
@@ -294,11 +294,6 @@
return info.loadDescription(context.getPackageManager());
}
- static boolean isRampingRingerEnabled(final Context context) {
- return Settings.System.getInt(
- context.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 0) == 1;
- }
-
@VisibleForTesting
void onContentChanged() {
// If the fragment is visible then update preferences immediately, else set the flag then
diff --git a/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java b/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java
index a2142a2..99d2bf5 100644
--- a/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceController.java
@@ -16,30 +16,66 @@
package com.android.settings.accessibility;
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-
+/** Preference controller for haptic feedback intensity */
public class HapticFeedbackIntensityPreferenceController
extends VibrationIntensityPreferenceController {
- @VisibleForTesting
- static final String PREF_KEY = "touch_vibration_preference_screen";
+ /** General configuration for haptic feedback intensity settings. */
+ public static final class HapticFeedbackVibrationPreferenceConfig
+ extends VibrationPreferenceConfig {
- public HapticFeedbackIntensityPreferenceController(Context context) {
- super(context, PREF_KEY, Settings.System.HAPTIC_FEEDBACK_INTENSITY,
- Settings.System.HAPTIC_FEEDBACK_ENABLED);
+ public HapticFeedbackVibrationPreferenceConfig(Context context) {
+ super(context, Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+ VibrationAttributes.USAGE_TOUCH);
+ }
+
+ @Override
+ public int readIntensity() {
+ final int hapticFeedbackEnabled = Settings.System.getInt(mContentResolver,
+ Settings.System.HAPTIC_FEEDBACK_ENABLED, ON);
+
+ if (hapticFeedbackEnabled == OFF) {
+ // HAPTIC_FEEDBACK_ENABLED is deprecated but should still be applied if the user has
+ // turned it off already.
+ return Vibrator.VIBRATION_INTENSITY_OFF;
+ }
+
+ return super.readIntensity();
+ }
+
+ @Override
+ public boolean updateIntensity(int intensity) {
+ final boolean success = super.updateIntensity(intensity);
+ final boolean isIntensityOff = intensity == Vibrator.VIBRATION_INTENSITY_OFF;
+
+ Settings.System.putInt(mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED,
+ isIntensityOff ? OFF : ON);
+ // HAPTIC_FEEDBACK_ENABLED is deprecated but should still reflect the intensity setting.
+
+ // HARDWARE_HAPTIC_FEEDBACK_INTENSITY is dependent on this setting, but should not be
+ // disabled by it.
+ Settings.System.putInt(mContentResolver,
+ Settings.System.HARDWARE_HAPTIC_FEEDBACK_INTENSITY,
+ isIntensityOff ? getDefaultIntensity() : intensity);
+
+ return success;
+ }
+ }
+
+ public HapticFeedbackIntensityPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey, new HapticFeedbackVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
-
- @Override
- protected int getDefaultIntensity() {
- return mVibrator.getDefaultHapticFeedbackIntensity();
- }
-
}
diff --git a/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceController.java b/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceController.java
new file mode 100644
index 0000000..fdaf140
--- /dev/null
+++ b/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceController.java
@@ -0,0 +1,34 @@
+/*
+ * 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 com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController.HapticFeedbackVibrationPreferenceConfig;
+
+/** Preference controller for haptic feedback with only a toggle for on/off states. */
+public class HapticFeedbackTogglePreferenceController extends VibrationTogglePreferenceController {
+
+ public HapticFeedbackTogglePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey, new HapticFeedbackVibrationPreferenceConfig(context));
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java
index 4ace4c6..31ae187 100644
--- a/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceController.java
@@ -17,27 +17,30 @@
package com.android.settings.accessibility;
import android.content.Context;
+import android.os.VibrationAttributes;
import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-
+/** Preference controller for notification vibration intensity */
public class NotificationVibrationIntensityPreferenceController
extends VibrationIntensityPreferenceController {
- @VisibleForTesting
- static final String PREF_KEY = "notification_vibration_preference_screen";
+ /** General configuration for notification vibration intensity settings. */
+ public static final class NotificationVibrationPreferenceConfig
+ extends VibrationPreferenceConfig {
- public NotificationVibrationIntensityPreferenceController(Context context) {
- super(context, PREF_KEY, Settings.System.NOTIFICATION_VIBRATION_INTENSITY, "");
+ public NotificationVibrationPreferenceConfig(Context context) {
+ super(context, Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ VibrationAttributes.USAGE_NOTIFICATION);
+ }
+ }
+
+ public NotificationVibrationIntensityPreferenceController(Context context,
+ String preferenceKey) {
+ super(context, preferenceKey, new NotificationVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
-
- @Override
- protected int getDefaultIntensity() {
- return mVibrator.getDefaultNotificationVibrationIntensity();
- }
}
diff --git a/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java
deleted file mode 100644
index 3ca197f..0000000
--- a/src/com/android/settings/accessibility/NotificationVibrationPreferenceFragment.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import android.app.settings.SettingsEnums;
-import android.media.AudioAttributes;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-
-/**
- * Fragment for picking accessibility shortcut service
- */
-public class NotificationVibrationPreferenceFragment extends VibrationPreferenceFragment {
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.ACCESSIBILITY_VIBRATION_NOTIFICATION;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.accessibility_notification_vibration_settings;
- }
-
- /**
- * Get the setting string of the vibration intensity setting this preference is dealing with.
- */
- @Override
- protected String getVibrationIntensitySetting() {
- return Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
- }
-
- @Override
- protected String getVibrationEnabledSetting() {
- return "";
- }
-
- @Override
- protected int getPreviewVibrationAudioAttributesUsage() {
- return AudioAttributes.USAGE_NOTIFICATION;
- }
-
- @Override
- protected int getDefaultVibrationIntensity() {
- Vibrator vibrator = getContext().getSystemService(Vibrator.class);
- return vibrator.getDefaultNotificationVibrationIntensity();
- }
-}
diff --git a/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceController.java
new file mode 100644
index 0000000..2dc02a1
--- /dev/null
+++ b/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceController.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController.NotificationVibrationPreferenceConfig;
+
+/** Preference controller for notification vibration with only a toggle for on/off states. */
+public class NotificationVibrationTogglePreferenceController
+ extends VibrationTogglePreferenceController {
+
+ public NotificationVibrationTogglePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey, new NotificationVibrationPreferenceConfig(context));
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java
index 4dee348..1ddcf2b 100644
--- a/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java
@@ -16,29 +16,63 @@
package com.android.settings.accessibility;
+import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
import android.content.Context;
+import android.media.AudioManager;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-
+/** Preference controller for ringtone vibration intensity */
public class RingVibrationIntensityPreferenceController
extends VibrationIntensityPreferenceController {
- @VisibleForTesting
- static final String PREF_KEY = "ring_vibration_preference_screen";
+ /** General configuration for ringtone vibration intensity settings. */
+ public static final class RingVibrationPreferenceConfig extends VibrationPreferenceConfig {
+ private final AudioManager mAudioManager;
- public RingVibrationIntensityPreferenceController(Context context) {
- super(context, PREF_KEY, Settings.System.RING_VIBRATION_INTENSITY,
- Settings.System.VIBRATE_WHEN_RINGING, /* supportRampingRinger= */ true);
+ public RingVibrationPreferenceConfig(Context context) {
+ super(context, Settings.System.RING_VIBRATION_INTENSITY,
+ VibrationAttributes.USAGE_RINGTONE);
+ mAudioManager = context.getSystemService(AudioManager.class);
+ }
+
+ @Override
+ public int readIntensity() {
+ final int vibrateWhenRinging = Settings.System.getInt(mContentResolver,
+ Settings.System.VIBRATE_WHEN_RINGING, ON);
+
+ if ((vibrateWhenRinging == OFF)
+ && !mAudioManager.isRampingRingerEnabled()) {
+ // VIBRATE_WHEN_RINGING is deprecated but should still be applied if the user has
+ // turned it off and has not enabled the ramping ringer (old three-state setting).
+ return Vibrator.VIBRATION_INTENSITY_OFF;
+ }
+
+ return super.readIntensity();
+ }
+
+ @Override
+ public boolean updateIntensity(int intensity) {
+ final boolean success = super.updateIntensity(intensity);
+
+ // VIBRATE_WHEN_RINGING is deprecated but should still reflect the intensity setting.
+ // Ramping ringer is independent of the ring intensity and should not be affected.
+ Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING,
+ (intensity == Vibrator.VIBRATION_INTENSITY_OFF) ? OFF : ON);
+
+ return success;
+ }
+ }
+
+ public RingVibrationIntensityPreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey, new RingVibrationPreferenceConfig(context));
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
-
- @Override
- protected int getDefaultIntensity() {
- return mVibrator.getDefaultRingVibrationIntensity();
- }
}
diff --git a/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java
deleted file mode 100644
index 5d19a9b..0000000
--- a/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import android.app.settings.SettingsEnums;
-import android.media.AudioAttributes;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-
-/**
- * Fragment for picking accessibility shortcut service
- */
-public class RingVibrationPreferenceFragment extends VibrationPreferenceFragment {
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.ACCESSIBILITY_VIBRATION_RING;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.accessibility_ring_vibration_settings;
- }
-
- /**
- * Get the setting string of the vibration intensity setting this preference is dealing with.
- */
- @Override
- protected String getVibrationIntensitySetting() {
- return Settings.System.RING_VIBRATION_INTENSITY;
- }
-
- @Override
- protected String getVibrationEnabledSetting() {
- if (AccessibilitySettings.isRampingRingerEnabled(getContext())) {
- return Settings.System.APPLY_RAMPING_RINGER;
- } else {
- return Settings.System.VIBRATE_WHEN_RINGING;
- }
- }
-
- @Override
- protected int getPreviewVibrationAudioAttributesUsage() {
- return AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
- }
-
- @Override
- protected int getDefaultVibrationIntensity() {
- Vibrator vibrator = getContext().getSystemService(Vibrator.class);
- return vibrator.getDefaultRingVibrationIntensity();
- }
-}
diff --git a/src/com/android/settings/accessibility/RingVibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/RingVibrationTogglePreferenceController.java
new file mode 100644
index 0000000..e68b6ce
--- /dev/null
+++ b/src/com/android/settings/accessibility/RingVibrationTogglePreferenceController.java
@@ -0,0 +1,34 @@
+/*
+ * 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 com.android.settings.accessibility.RingVibrationIntensityPreferenceController.RingVibrationPreferenceConfig;
+
+/** Preference controller for ringtone vibration with only a toggle for on/off states. */
+public class RingVibrationTogglePreferenceController extends VibrationTogglePreferenceController {
+
+ public RingVibrationTogglePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey, new RingVibrationPreferenceConfig(context));
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index fd987a3..04b5347 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -21,9 +21,7 @@
import static com.android.settings.accessibility.PreferredShortcuts.retrieveUserShortcutType;
import android.accessibilityservice.AccessibilityServiceInfo;
-import android.app.Activity;
import android.app.Dialog;
-import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -39,9 +37,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
@@ -52,11 +47,9 @@
import androidx.annotation.Nullable;
-import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ConfirmDeviceCredentialActivity;
import com.android.settingslib.accessibility.AccessibilityUtils;
import java.util.List;
@@ -67,9 +60,7 @@
ToggleFeaturePreferenceFragment {
private static final String TAG = "ToggleAccessibilityServicePreferenceFragment";
- private static final int ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION = 1;
private static final String KEY_HAS_LOGGED = "has_logged";
- private LockPatternUtils mLockPatternUtils;
private AtomicBoolean mIsDialogShown = new AtomicBoolean(/* initialValue= */ false);
private static final String EMPTY_STRING = "";
@@ -110,7 +101,6 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mLockPatternUtils = new LockPatternUtils(getPrefContext());
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(KEY_HAS_LOGGED)) {
mDisabledStateLogged = savedInstanceState.getBoolean(KEY_HAS_LOGGED);
@@ -263,33 +253,8 @@
.contains(mComponentName);
}
- /**
- * Return whether the device is encrypted with legacy full disk encryption. Newer devices
- * should be using File Based Encryption.
- *
- * @return true if device is encrypted
- */
- private boolean isFullDiskEncrypted() {
- return StorageManager.isNonDefaultBlockEncrypted();
- }
-
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION) {
- if (resultCode == Activity.RESULT_OK) {
- handleConfirmServiceEnabled(/* confirmed= */ true);
- // The user confirmed that they accept weaker encryption when
- // enabling the accessibility service, so change encryption.
- // Since we came here asynchronously, check encryption again.
- if (isFullDiskEncrypted()) {
- mLockPatternUtils.clearEncryptionPassword();
- Settings.Global.putInt(getContentResolver(),
- Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, 0);
- }
- } else {
- handleConfirmServiceEnabled(/* confirmed= */ false);
- }
- }
}
private void registerPackageRemoveReceiver() {
@@ -341,23 +306,6 @@
onPreferenceToggled(mPreferenceKey, confirmed);
}
- private String createConfirmCredentialReasonMessage() {
- int resId = R.string.enable_service_password_reason;
- switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
- case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: {
- resId = R.string.enable_service_pattern_reason;
- }
- break;
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: {
- resId = R.string.enable_service_pin_reason;
- }
- break;
- }
- return getString(resId, getAccessibilityServiceInfo().getResolveInfo()
- .loadLabel(getPackageManager()));
- }
-
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
if (isChecked != isAccessibilityServiceEnabled()) {
@@ -483,20 +431,11 @@
}
private void onAllowButtonFromEnableToggleClicked() {
- if (isFullDiskEncrypted()) {
- final String title = createConfirmCredentialReasonMessage();
- final Intent intent = ConfirmDeviceCredentialActivity.createIntent(title, /* details= */
- null);
- startActivityForResult(intent,
- ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION);
- } else {
- handleConfirmServiceEnabled(/* confirmed= */ true);
- if (isServiceSupportAccessibilityButton()) {
- mIsDialogShown.set(false);
- showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
- }
+ handleConfirmServiceEnabled(/* confirmed= */ true);
+ if (isServiceSupportAccessibilityButton()) {
+ mIsDialogShown.set(false);
+ showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
}
-
mDialog.dismiss();
}
diff --git a/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java
deleted file mode 100644
index f6bbbf3..0000000
--- a/src/com/android/settings/accessibility/TouchVibrationPreferenceFragment.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import android.app.settings.SettingsEnums;
-import android.media.AudioAttributes;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-
-/**
- * Fragment for picking accessibility shortcut service
- */
-public class TouchVibrationPreferenceFragment extends VibrationPreferenceFragment {
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.ACCESSIBILITY_VIBRATION_TOUCH;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.accessibility_touch_vibration_settings;
- }
-
- /**
- * Get the setting string of the vibration intensity setting this preference is dealing with.
- */
- @Override
- protected String getVibrationIntensitySetting() {
- return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
- }
-
- @Override
- protected String getVibrationEnabledSetting() {
- return Settings.System.HAPTIC_FEEDBACK_ENABLED;
- }
-
- @Override
- protected int getDefaultVibrationIntensity() {
- Vibrator vibrator = getContext().getSystemService(Vibrator.class);
- return vibrator.getDefaultHapticFeedbackIntensity();
- }
-
- @Override
- protected int getPreviewVibrationAudioAttributesUsage() {
- return AudioAttributes.USAGE_ASSISTANCE_SONIFICATION;
- }
-}
diff --git a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java
index 9d71176..e35b42c 100644
--- a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java
@@ -17,116 +17,80 @@
package com.android.settings.accessibility;
import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
import android.os.Vibrator;
-import android.provider.Settings;
-import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.SliderPreferenceController;
+import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
-public abstract class VibrationIntensityPreferenceController extends BasePreferenceController
+/**
+ * Abstract preference controller for a vibration intensity setting, that displays multiple
+ * intensity levels to the user as a slider.
+ */
+public abstract class VibrationIntensityPreferenceController extends SliderPreferenceController
implements LifecycleObserver, OnStart, OnStop {
- protected final Vibrator mVibrator;
- private final SettingObserver mSettingsContentObserver;
- private final String mSettingKey;
- private final String mEnabledKey;
- private final boolean mSupportRampingRinger;
+ protected final VibrationPreferenceConfig mPreferenceConfig;
+ private final VibrationPreferenceConfig.SettingObserver mSettingsContentObserver;
- private Preference mPreference;
-
- public VibrationIntensityPreferenceController(Context context, String prefkey,
- String settingKey, String enabledKey, boolean supportRampingRinger) {
+ protected VibrationIntensityPreferenceController(Context context, String prefkey,
+ VibrationPreferenceConfig preferenceConfig) {
super(context, prefkey);
- mVibrator = mContext.getSystemService(Vibrator.class);
- mSettingKey = settingKey;
- mEnabledKey = enabledKey;
- mSupportRampingRinger= supportRampingRinger;
- mSettingsContentObserver = new SettingObserver(settingKey) {
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateState(mPreference);
- }
- };
- }
-
- public VibrationIntensityPreferenceController(Context context, String prefkey,
- String settingKey, String enabledKey) {
- this(context, prefkey, settingKey, enabledKey, /* supportRampingRinger= */ false);
+ mPreferenceConfig = preferenceConfig;
+ mSettingsContentObserver = new VibrationPreferenceConfig.SettingObserver(
+ preferenceConfig);
}
@Override
public void onStart() {
- mContext.getContentResolver().registerContentObserver(
- mSettingsContentObserver.uri,
- false /* notifyForDescendants */,
- mSettingsContentObserver);
+ mSettingsContentObserver.register(mContext.getContentResolver());
}
@Override
public void onStop() {
- mContext.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
+ mSettingsContentObserver.unregister(mContext.getContentResolver());
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
- mPreference = screen.findPreference(getPreferenceKey());
+ final SeekBarPreference preference = screen.findPreference(getPreferenceKey());
+ mSettingsContentObserver.onDisplayPreference(this, preference);
+ // TODO: remove this and replace with a different way to play the haptic preview without
+ // relying on the setting being propagated to the service.
+ preference.setContinuousUpdates(true);
+ preference.setMin(getMin());
+ preference.setMax(getMax());
}
@Override
- public CharSequence getSummary() {
- final int intensity = Settings.System.getInt(mContext.getContentResolver(),
- mSettingKey, getDefaultIntensity());
- final boolean enabled = (Settings.System.getInt(mContext.getContentResolver(),
- mEnabledKey, 1) == 1) ||
- (mSupportRampingRinger && AccessibilitySettings.isRampingRingerEnabled(mContext));
- return getIntensityString(mContext, enabled ? intensity : Vibrator.VIBRATION_INTENSITY_OFF);
+ public int getMin() {
+ return Vibrator.VIBRATION_INTENSITY_OFF;
}
- public static CharSequence getIntensityString(Context context, int intensity) {
- final boolean supportsMultipleIntensities = context.getResources().getBoolean(
- R.bool.config_vibration_supports_multiple_intensities);
- if (supportsMultipleIntensities) {
- switch (intensity) {
- case Vibrator.VIBRATION_INTENSITY_OFF:
- return context.getString(R.string.accessibility_vibration_intensity_off);
- case Vibrator.VIBRATION_INTENSITY_LOW:
- return context.getString(R.string.accessibility_vibration_intensity_low);
- case Vibrator.VIBRATION_INTENSITY_MEDIUM:
- return context.getString(R.string.accessibility_vibration_intensity_medium);
- case Vibrator.VIBRATION_INTENSITY_HIGH:
- return context.getString(R.string.accessibility_vibration_intensity_high);
- default:
- return "";
- }
- } else {
- if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {
- return context.getString(R.string.switch_off_text);
- } else {
- return context.getString(R.string.switch_on_text);
- }
- }
+ @Override
+ public int getMax() {
+ return Vibrator.VIBRATION_INTENSITY_HIGH;
}
- protected abstract int getDefaultIntensity();
+ @Override
+ public int getSliderPosition() {
+ final int position = mPreferenceConfig.readIntensity();
+ return Math.min(position, getMax());
+ }
- private static class SettingObserver extends ContentObserver {
+ @Override
+ public boolean setSliderPosition(int position) {
+ final boolean success = mPreferenceConfig.updateIntensity(position);
- public final Uri uri;
-
- public SettingObserver(String settingKey) {
- super(new Handler(Looper.getMainLooper()));
- uri = Settings.System.getUriFor(settingKey);
+ if (success && (position != Vibrator.VIBRATION_INTENSITY_OFF)) {
+ mPreferenceConfig.playVibrationPreview();
}
+
+ return success;
}
}
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceConfig.java b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java
new file mode 100644
index 0000000..aa59554
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationPreferenceConfig.java
@@ -0,0 +1,126 @@
+/*
+ * 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.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.VibrationAttributes;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+
+import com.android.settingslib.core.AbstractPreferenceController;
+
+/**
+ * Vibration intensity settings configuration to be shared between different preference
+ * controllers that handle the same setting key.
+ */
+public abstract class VibrationPreferenceConfig {
+
+ protected final ContentResolver mContentResolver;
+ private final Vibrator mVibrator;
+ private final String mSettingKey;
+ private final int mDefaultIntensity;
+ private final VibrationAttributes mVibrationAttributes;
+
+ public VibrationPreferenceConfig(Context context, String settingKey, int vibrationUsage) {
+ mContentResolver = context.getContentResolver();
+ mVibrator = context.getSystemService(Vibrator.class);
+ mSettingKey = settingKey;
+ mDefaultIntensity = mVibrator.getDefaultVibrationIntensity(vibrationUsage);
+ mVibrationAttributes = new VibrationAttributes.Builder()
+ .setUsage(vibrationUsage)
+ .build();
+ }
+
+ /** Return the setting key for this setting preference. */
+ public String getSettingKey() {
+ return mSettingKey;
+ }
+
+ /** Returns the default intensity to be displayed when the setting value is not set. */
+ public int getDefaultIntensity() {
+ return mDefaultIntensity;
+ }
+
+ /** Reads setting value for corresponding {@link VibrationPreferenceConfig} */
+ public int readIntensity() {
+ return Settings.System.getInt(mContentResolver, mSettingKey, mDefaultIntensity);
+ }
+
+ /** Update setting value for corresponding {@link VibrationPreferenceConfig} */
+ public boolean updateIntensity(int intensity) {
+ return Settings.System.putInt(mContentResolver, mSettingKey, intensity);
+ }
+
+ /** Play a vibration effect with intensity just selected by the user. */
+ public void playVibrationPreview() {
+ mVibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK),
+ mVibrationAttributes);
+ }
+
+ /** {@link ContentObserver} for a setting described by a {@link VibrationPreferenceConfig}. */
+ public static final class SettingObserver extends ContentObserver {
+ private final Uri mUri;
+ private AbstractPreferenceController mPreferenceController;
+ private Preference mPreference;
+
+ /** Creates observer for given preference. */
+ public SettingObserver(VibrationPreferenceConfig preferenceConfig) {
+ super(new Handler(/* async= */ true));
+ mUri = Settings.System.getUriFor(preferenceConfig.getSettingKey());
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (mUri.equals(uri) && mPreferenceController != null && mPreference != null) {
+ mPreferenceController.updateState(mPreference);
+ }
+ }
+
+ /**
+ * Register this observer to given {@link ContentResolver}, to be called from lifecycle
+ * {@code onStart} method.
+ */
+ public void register(ContentResolver contentResolver) {
+ contentResolver.registerContentObserver(mUri, /* notifyForDescendants= */ false, this);
+ }
+
+ /**
+ * Unregister this observer from given {@link ContentResolver}, to be called from lifecycle
+ * {@code onStop} method.
+ */
+ public void unregister(ContentResolver contentResolver) {
+ contentResolver.unregisterContentObserver(this);
+ }
+
+ /**
+ * Binds this observer to given controller and preference, once it has been displayed to the
+ * user.
+ */
+ public void onDisplayPreference(AbstractPreferenceController controller,
+ Preference preference) {
+ mPreferenceController = controller;
+ mPreference = preference;
+ }
+ }
+}
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceController.java b/src/com/android/settings/accessibility/VibrationPreferenceController.java
deleted file mode 100644
index 8bfea34..0000000
--- a/src/com/android/settings/accessibility/VibrationPreferenceController.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 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.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-
-public class VibrationPreferenceController extends BasePreferenceController {
-
- private final Vibrator mVibrator;
-
- public VibrationPreferenceController(Context context, String preferenceKey) {
- super(context, preferenceKey);
- mVibrator = mContext.getSystemService(Vibrator.class);
- }
-
- @Override
- public int getAvailabilityStatus() {
- return AVAILABLE;
- }
-
- @Override
- public CharSequence getSummary() {
- int ringIntensity = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.RING_VIBRATION_INTENSITY,
- mVibrator.getDefaultRingVibrationIntensity());
- if (Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.VIBRATE_WHEN_RINGING, 0) == 0
- && !AccessibilitySettings.isRampingRingerEnabled(mContext)) {
- ringIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
- }
- final CharSequence ringIntensityString =
- VibrationIntensityPreferenceController.getIntensityString(mContext, ringIntensity);
-
- final int notificationIntensity = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
- mVibrator.getDefaultNotificationVibrationIntensity());
- final CharSequence notificationIntensityString =
- VibrationIntensityPreferenceController.getIntensityString(mContext,
- notificationIntensity);
-
- int touchIntensity = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.HAPTIC_FEEDBACK_INTENSITY,
- mVibrator.getDefaultHapticFeedbackIntensity());
- if (Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0) {
- touchIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
- }
- final CharSequence touchIntensityString =
- VibrationIntensityPreferenceController.getIntensityString(mContext, touchIntensity);
-
- if (ringIntensity == touchIntensity && ringIntensity == notificationIntensity) {
- return ringIntensityString;
- } else {
- return mContext.getString(R.string.accessibility_vibration_summary, ringIntensityString,
- notificationIntensityString, touchIntensityString);
- }
- }
-}
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceFragment.java b/src/com/android/settings/accessibility/VibrationPreferenceFragment.java
deleted file mode 100644
index 2ef8f66..0000000
--- a/src/com/android/settings/accessibility/VibrationPreferenceFragment.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.accessibility;
-
-import static android.os.Vibrator.VibrationIntensity;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.graphics.drawable.Drawable;
-import android.media.AudioAttributes;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settingslib.widget.CandidateInfo;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Fragment for changing vibration settings.
- */
-public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragment {
- private static final String TAG = "VibrationPreferenceFragment";
-
- @VisibleForTesting
- final static String KEY_INTENSITY_OFF = "intensity_off";
- @VisibleForTesting
- final static String KEY_INTENSITY_LOW = "intensity_low";
- @VisibleForTesting
- final static String KEY_INTENSITY_MEDIUM = "intensity_medium";
- @VisibleForTesting
- final static String KEY_INTENSITY_HIGH = "intensity_high";
- // KEY_INTENSITY_ON is only used when the device doesn't support multiple intensity levels.
- @VisibleForTesting
- final static String KEY_INTENSITY_ON = "intensity_on";
-
- private final Map<String, VibrationIntensityCandidateInfo> mCandidates;
- private final SettingsObserver mSettingsObserver;
-
- public VibrationPreferenceFragment() {
- mCandidates = new ArrayMap<>();
- mSettingsObserver = new SettingsObserver();
- }
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mSettingsObserver.register();
- if (mCandidates.isEmpty()) {
- loadCandidates(context);
- }
- }
-
- private void loadCandidates(Context context) {
- final boolean supportsMultipleIntensities = context.getResources().getBoolean(
- R.bool.config_vibration_supports_multiple_intensities);
- if (supportsMultipleIntensities) {
- mCandidates.put(KEY_INTENSITY_OFF,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
- R.string.accessibility_vibration_intensity_off,
- Vibrator.VIBRATION_INTENSITY_OFF));
- mCandidates.put(KEY_INTENSITY_LOW,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_LOW,
- R.string.accessibility_vibration_intensity_low,
- Vibrator.VIBRATION_INTENSITY_LOW));
- mCandidates.put(KEY_INTENSITY_MEDIUM,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_MEDIUM,
- R.string.accessibility_vibration_intensity_medium,
- Vibrator.VIBRATION_INTENSITY_MEDIUM));
- mCandidates.put(KEY_INTENSITY_HIGH,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_HIGH,
- R.string.accessibility_vibration_intensity_high,
- Vibrator.VIBRATION_INTENSITY_HIGH));
- } else {
- mCandidates.put(KEY_INTENSITY_OFF,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_OFF,
- R.string.switch_off_text, Vibrator.VIBRATION_INTENSITY_OFF));
- mCandidates.put(KEY_INTENSITY_ON,
- new VibrationIntensityCandidateInfo(KEY_INTENSITY_ON,
- R.string.switch_on_text, getDefaultVibrationIntensity()));
- }
- }
-
- private boolean hasVibrationEnabledSetting() {
- return !TextUtils.isEmpty(getVibrationEnabledSetting());
- }
-
- private void updateSettings(VibrationIntensityCandidateInfo candidate) {
- boolean vibrationEnabled = candidate.getIntensity() != Vibrator.VIBRATION_INTENSITY_OFF;
- if (hasVibrationEnabledSetting()) {
- // Update vibration enabled setting
- final String vibrationEnabledSetting = getVibrationEnabledSetting();
- final boolean wasEnabled = TextUtils.equals(
- vibrationEnabledSetting, Settings.System.APPLY_RAMPING_RINGER)
- ? true
- : (Settings.System.getInt(
- getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1);
- if (vibrationEnabled != wasEnabled) {
- if (vibrationEnabledSetting.equals(Settings.System.APPLY_RAMPING_RINGER)) {
- Settings.Global.putInt(getContext().getContentResolver(),
- vibrationEnabledSetting, 0);
- } else {
- Settings.System.putInt(getContext().getContentResolver(),
- vibrationEnabledSetting, vibrationEnabled ? 1 : 0);
- }
-
- int previousIntensity = Settings.System.getInt(getContext().getContentResolver(),
- getVibrationIntensitySetting(), 0);
- if (vibrationEnabled && previousIntensity == candidate.getIntensity()) {
- // We can't play preview effect here for all cases because that causes a data
- // race (VibratorService may access intensity settings before these settings
- // are updated). But we can't just play it in intensity settings update
- // observer, because the intensity settings are not changed if we turn the
- // vibration off, then on.
- //
- // In this case we sould play the preview here.
- // To be refactored in b/132952771
- playVibrationPreview();
- }
- }
- }
- // There are two conditions that need to change the intensity.
- // First: Vibration is enabled and we are changing its strength.
- // Second: There is no setting to enable this vibration, change the intensity directly.
- if (vibrationEnabled || !hasVibrationEnabledSetting()) {
- // Update vibration intensity setting
- Settings.System.putInt(getContext().getContentResolver(),
- getVibrationIntensitySetting(), candidate.getIntensity());
- }
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- mSettingsObserver.unregister();
- }
-
- /**
- * Get the setting string of the vibration intensity setting this preference is dealing with.
- */
- protected abstract String getVibrationIntensitySetting();
-
- /**
- * Get the setting string of the vibration enabledness setting this preference is dealing with.
- */
- protected abstract String getVibrationEnabledSetting();
-
- /**
- * Get the default intensity for the desired setting.
- */
- protected abstract int getDefaultVibrationIntensity();
-
- /**
- * When a new vibration intensity is selected by the user.
- */
- protected void onVibrationIntensitySelected(int intensity) { }
-
- /**
- * Play a vibration effect with intensity just selected by user
- */
- protected void playVibrationPreview() {
- Vibrator vibrator = getContext().getSystemService(Vibrator.class);
- VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
- AudioAttributes.Builder builder = new AudioAttributes.Builder();
- builder.setUsage(getPreviewVibrationAudioAttributesUsage());
- vibrator.vibrate(effect, builder.build());
- }
-
- /**
- * Get the AudioAttributes usage for vibration preview.
- */
- protected int getPreviewVibrationAudioAttributesUsage() {
- return AudioAttributes.USAGE_UNKNOWN;
- }
-
- @Override
- protected List<? extends CandidateInfo> getCandidates() {
- List<VibrationIntensityCandidateInfo> candidates = new ArrayList<>(mCandidates.values());
- candidates.sort(
- Comparator.comparing(VibrationIntensityCandidateInfo::getIntensity).reversed());
- return candidates;
- }
-
- @Override
- protected String getDefaultKey() {
- int vibrationIntensity = Settings.System.getInt(getContext().getContentResolver(),
- getVibrationIntensitySetting(), getDefaultVibrationIntensity());
- final String vibrationEnabledSetting = getVibrationEnabledSetting();
- final boolean vibrationEnabled = TextUtils.equals(
- vibrationEnabledSetting, Settings.System.APPLY_RAMPING_RINGER)
- ? true
- : (Settings.System.getInt(
- getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1);
- if (!vibrationEnabled) {
- vibrationIntensity = Vibrator.VIBRATION_INTENSITY_OFF;
- }
- for (VibrationIntensityCandidateInfo candidate : mCandidates.values()) {
- final boolean matchesIntensity = candidate.getIntensity() == vibrationIntensity;
- final boolean matchesOn = candidate.getKey().equals(KEY_INTENSITY_ON)
- && vibrationIntensity != Vibrator.VIBRATION_INTENSITY_OFF;
- if (matchesIntensity || matchesOn) {
- return candidate.getKey();
- }
- }
- return null;
- }
-
- @Override
- protected boolean setDefaultKey(String key) {
- VibrationIntensityCandidateInfo candidate = mCandidates.get(key);
- if (candidate == null) {
- Log.e(TAG, "Tried to set unknown intensity (key=" + key + ")!");
- return false;
- }
- updateSettings(candidate);
- onVibrationIntensitySelected(candidate.getIntensity());
- return true;
- }
-
- @VisibleForTesting
- class VibrationIntensityCandidateInfo extends CandidateInfo {
- private String mKey;
- private int mLabelId;
- @VibrationIntensity
- private int mIntensity;
-
- public VibrationIntensityCandidateInfo(String key, int labelId, int intensity) {
- super(true /* enabled */);
- mKey = key;
- mLabelId = labelId;
- mIntensity = intensity;
- }
-
- @Override
- public CharSequence loadLabel() {
- return getContext().getString(mLabelId);
- }
-
- @Override
- public Drawable loadIcon() {
- return null;
- }
-
- @Override
- public String getKey() {
- return mKey;
- }
-
- public int getIntensity() {
- return mIntensity;
- }
- }
-
- private class SettingsObserver extends ContentObserver {
- public SettingsObserver() {
- super(new Handler());
- }
-
- public void register() {
- getContext().getContentResolver().registerContentObserver(
- Settings.System.getUriFor(getVibrationIntensitySetting()), false, this);
- }
-
- public void unregister() {
- getContext().getContentResolver().unregisterContentObserver(this);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateCandidates();
- playVibrationPreview();
- }
- }
-}
diff --git a/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java
new file mode 100644
index 0000000..4a86538
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceController.java
@@ -0,0 +1,140 @@
+/*
+ * 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.database.ContentObserver;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Preference controller for the ramping ringer setting key, controlled via {@link AudioManager}.
+ *
+ * <p>This preference depends on the {@link Settings.System#RING_VIBRATION_INTENSITY}, and it will
+ * be disabled and display the unchecked state when the ring intensity is set to OFF. The actual
+ * ramping ringer setting will not be overwritten when the ring intensity is turned off, so the
+ * user original value will be naturally restored when the ring intensity is enabled again.
+ */
+public class VibrationRampingRingerTogglePreferenceController
+ extends TogglePreferenceController implements LifecycleObserver, OnStart, OnStop {
+
+ @VisibleForTesting
+ static final String DEVICE_CONFIG_KEY = "ramping_ringer_enabled";
+
+ private final ContentObserver mSettingObserver;
+ private final Vibrator mVibrator;
+ private final AudioManager mAudioManager;
+
+ private Preference mPreference;
+
+ public VibrationRampingRingerTogglePreferenceController(Context context, String preferenceKey) {
+ super(context, preferenceKey);
+ mVibrator = context.getSystemService(Vibrator.class);
+ mAudioManager = context.getSystemService(AudioManager.class);
+ mSettingObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ updateState(mPreference);
+ }
+ };
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ final boolean rampingRingerEnabledOnTelephonyConfig =
+ DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TELEPHONY, DEVICE_CONFIG_KEY, false);
+ return (Utils.isVoiceCapable(mContext) && !rampingRingerEnabledOnTelephonyConfig)
+ ? AVAILABLE
+ : UNSUPPORTED_ON_DEVICE;
+ }
+
+ @Override
+ public void onStart() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER),
+ /* notifyForDescendants= */ false,
+ mSettingObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY),
+ /* notifyForDescendants= */ false,
+ mSettingObserver);
+ }
+
+ @Override
+ public void onStop() {
+ mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ mPreference.setEnabled(isRingVibrationEnabled());
+ }
+
+ @Override
+ public boolean isChecked() {
+ return isRingVibrationEnabled() && mAudioManager.isRampingRingerEnabled();
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ if (isRingVibrationEnabled()) {
+ // Don't update ramping ringer setting value if ring vibration is disabled.
+ mAudioManager.setRampingRingerEnabled(isChecked);
+ }
+ return true;
+ }
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_accessibility;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ if (preference != null) {
+ preference.setEnabled(isRingVibrationEnabled());
+ }
+ }
+
+ private boolean isRingVibrationEnabled() {
+ final int ringIntensity = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.RING_VIBRATION_INTENSITY,
+ mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
+ return ringIntensity != Vibrator.VIBRATION_INTENSITY_OFF;
+ }
+}
diff --git a/src/com/android/settings/accessibility/VibrationSettings.java b/src/com/android/settings/accessibility/VibrationSettings.java
index 90ee11c..277cfee 100644
--- a/src/com/android/settings/accessibility/VibrationSettings.java
+++ b/src/com/android/settings/accessibility/VibrationSettings.java
@@ -41,7 +41,11 @@
@Override
protected int getPreferenceScreenResId() {
- return R.xml.accessibility_vibration_settings;
+ final boolean supportsMultipleIntensities = getContext().getResources().getBoolean(
+ R.bool.config_vibration_supports_multiple_intensities);
+ return supportsMultipleIntensities
+ ? R.xml.accessibility_vibration_intensity_settings
+ : R.xml.accessibility_vibration_settings;
}
@Override
diff --git a/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java b/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java
new file mode 100644
index 0000000..5278b66
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationTogglePreferenceController.java
@@ -0,0 +1,87 @@
+/*
+ * 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.os.Vibrator;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+/** Abstract preference controller for a vibration intensity setting, that has only ON/OFF states */
+public abstract class VibrationTogglePreferenceController extends TogglePreferenceController
+ implements LifecycleObserver, OnStart, OnStop {
+
+ protected final VibrationPreferenceConfig mPreferenceConfig;
+ private final VibrationPreferenceConfig.SettingObserver mSettingsContentObserver;
+
+ protected VibrationTogglePreferenceController(Context context, String preferenceKey,
+ VibrationPreferenceConfig preferenceConfig) {
+ super(context, preferenceKey);
+ mPreferenceConfig = preferenceConfig;
+ mSettingsContentObserver = new VibrationPreferenceConfig.SettingObserver(
+ preferenceConfig);
+ }
+
+ @Override
+ public void onStart() {
+ mSettingsContentObserver.register(mContext.getContentResolver());
+ }
+
+ @Override
+ public void onStop() {
+ mSettingsContentObserver.unregister(mContext.getContentResolver());
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ final Preference preference = screen.findPreference(getPreferenceKey());
+ mSettingsContentObserver.onDisplayPreference(this, preference);
+ }
+
+ @Override
+ public boolean isChecked() {
+ final int position = mPreferenceConfig.readIntensity();
+ return position != Vibrator.VIBRATION_INTENSITY_OFF;
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ final int newIntensity = isChecked
+ ? mPreferenceConfig.getDefaultIntensity()
+ : Vibrator.VIBRATION_INTENSITY_OFF;
+ final boolean success = mPreferenceConfig.updateIntensity(newIntensity);
+
+ if (success && isChecked) {
+ mPreferenceConfig.playVibrationPreview();
+ }
+
+ return success;
+ }
+
+ @Override
+ public int getSliceHighlightMenuRes() {
+ return R.string.menu_key_accessibility;
+ }
+}
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
index ac3a01d..ab999ed 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingUtils.java
@@ -16,10 +16,7 @@
package com.android.settings.activityembedding;
-import android.app.Activity;
-import android.app.ActivityTaskManager;
import android.content.Context;
-import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.FeatureFlagUtils;
import android.util.Log;
@@ -65,13 +62,4 @@
return isFlagEnabled && isSplitSupported;
}
-
- /** Whether the screen meets two-pane resolution. */
- public static boolean isTwoPaneResolution(Activity activity) {
- final Rect currentTaskBounds =
- ActivityTaskManager.getInstance().getTaskBounds(activity.getTaskId());
-
- return currentTaskBounds.width() >= getMinCurrentScreenSplitWidthPx(activity)
- && currentTaskBounds.height() >= getMinSmallestScreenSplitWidthPx(activity);
- }
}
diff --git a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java
index f321d72..6a254cb 100644
--- a/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppDataUsagePreferenceController.java
@@ -17,6 +17,7 @@
package com.android.settings.applications.appinfo;
import android.content.Context;
+import android.net.NetworkStats;
import android.net.NetworkTemplate;
import android.os.Bundle;
import android.text.format.DateUtils;
@@ -136,13 +137,13 @@
private static NetworkTemplate getTemplate(Context context) {
if (DataUsageUtils.hasReadyMobileRadio(context)) {
- return NetworkTemplate.buildTemplateMobileWildcard();
+ return new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE).setMeteredness(
+ NetworkStats.METERED_YES).build();
}
if (DataUsageUtils.hasWifiRadio(context)) {
- return NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */);
+ return new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build();
}
- return NetworkTemplate.buildTemplateEthernet();
+ return new NetworkTemplate.Builder(NetworkTemplate.MATCH_ETHERNET).build();
}
@VisibleForTesting
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 583766e..2f0e8b3 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -148,7 +148,6 @@
import com.android.settings.print.PrintJobSettingsFragment;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.privacy.PrivacyDashboardFragment;
-import com.android.settings.security.CryptKeeperSettings;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecurityAdvancedSettings;
import com.android.settings.security.SecuritySettings;
@@ -246,7 +245,6 @@
PickupGestureSettings.class.getName(),
DoubleTwistGestureSettings.class.getName(),
SystemNavigationGestureSettings.class.getName(),
- CryptKeeperSettings.class.getName(),
DataUsageSummary.class.getName(),
DreamSettings.class.getName(),
UserSettings.class.getName(),
diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java
index a4396a2..abcc45f 100644
--- a/src/com/android/settings/datausage/DataUsageSummary.java
+++ b/src/com/android/settings/datausage/DataUsageSummary.java
@@ -183,15 +183,15 @@
void addWifiSection() {
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
inflatePreferences(R.xml.data_usage_wifi);
- category.setTemplate(
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */), 0, services);
+ category.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build(),
+ 0, services);
}
private void addEthernetSection() {
TemplatePreferenceCategory category = (TemplatePreferenceCategory)
inflatePreferences(R.xml.data_usage_ethernet);
- category.setTemplate(NetworkTemplate.buildTemplateEthernet(), 0, services);
+ category.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_ETHERNET).build(),
+ 0, services);
}
private Preference inflatePreferences(int resId) {
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java
index 260a6da..b6e533b 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java
@@ -225,8 +225,7 @@
static void launchWifiDataUsage(Context context) {
final Bundle args = new Bundle(1);
args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE,
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */));
+ new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build());
args.putInt(DataUsageList.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_WIFI);
final SubSettingLauncher launcher = new SubSettingLauncher(context)
.setArguments(args)
@@ -369,8 +368,7 @@
protected long getHistoricalUsageLevel() {
final DataUsageController controller = new DataUsageController(getContext());
return controller.getHistoricalUsageLevel(
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */));
+ new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build());
}
@VisibleForTesting
diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
index ac1e1ad..1b3b47a 100644
--- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
+++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java
@@ -138,8 +138,7 @@
mDefaultTemplate = DataUsageLib.getMobileTemplate(context, subscriptionId);
} else if (DataUsageUtils.hasWifiRadio(context)) {
mDataUsageTemplate = R.string.wifi_data_template;
- mDefaultTemplate = NetworkTemplate.buildTemplateWifi(
- NetworkTemplate.WIFI_NETWORKID_ALL, null /* subscriberId */);
+ mDefaultTemplate = new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build();
} else {
mDataUsageTemplate = R.string.ethernet_data_template;
mDefaultTemplate = DataUsageUtils.getDefaultTemplate(context, subscriptionId);
diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java
index fae53ec..5227284 100644
--- a/src/com/android/settings/datausage/DataUsageUtils.java
+++ b/src/com/android/settings/datausage/DataUsageUtils.java
@@ -184,10 +184,9 @@
if (SubscriptionManager.isValidSubscriptionId(defaultSubId) && hasMobileData(context)) {
return DataUsageLib.getMobileTemplate(context, defaultSubId);
} else if (hasWifiRadio(context)) {
- return NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */);
+ return new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build();
} else {
- return NetworkTemplate.buildTemplateEthernet();
+ return new NetworkTemplate.Builder(NetworkTemplate.MATCH_ETHERNET).build();
}
}
diff --git a/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java
index 0551fc2..9d3054e 100644
--- a/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java
+++ b/src/com/android/settings/datausage/WifiDataUsageSummaryPreferenceController.java
@@ -26,6 +26,8 @@
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.net.DataUsageController;
+import java.util.Set;
+
/**
* The controller displays a data usage chart for the specified Wi-Fi network.
*/
@@ -52,7 +54,8 @@
final DataUsageSummaryPreference mPreference = (DataUsageSummaryPreference) preference;
// TODO(b/126299427): Currently gets data usage of whole Wi-Fi networks, but should get
// specified one.
- final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(mNetworkId);
+ final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI)
+ .setWifiNetworkKeys(Set.of(mNetworkId)).build();
final DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo(
template);
mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(template));
diff --git a/src/com/android/settings/datausage/lib/DataUsageLib.java b/src/com/android/settings/datausage/lib/DataUsageLib.java
index 830f1ca..9f4c78f 100644
--- a/src/com/android/settings/datausage/lib/DataUsageLib.java
+++ b/src/com/android/settings/datausage/lib/DataUsageLib.java
@@ -17,6 +17,7 @@
package com.android.settings.datausage.lib;
import android.content.Context;
+import android.net.NetworkStats;
import android.net.NetworkTemplate;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -26,6 +27,7 @@
import com.android.internal.util.ArrayUtils;
import java.util.List;
+import java.util.Set;
/**
* Lib class for data usage
@@ -71,12 +73,17 @@
return NetworkTemplate.normalize(mobileTemplate, mergedSubscriberIds);
}
- private static NetworkTemplate getMobileTemplateForSubId(
+ public static NetworkTemplate getMobileTemplateForSubId(
TelephonyManager telephonyManager, int subId) {
- // The null subscriberId means that no any mobile/carrier network will be matched.
- // Using old API: buildTemplateMobileAll for the null subscriberId to avoid NPE.
+ // Create template that matches any mobile network when the subscriberId is null.
String subscriberId = telephonyManager.getSubscriberId(subId);
- return subscriberId != null ? NetworkTemplate.buildTemplateCarrierMetered(subscriberId)
- : NetworkTemplate.buildTemplateMobileAll(subscriberId);
+ return subscriberId != null
+ ? new NetworkTemplate.Builder(NetworkTemplate.MATCH_CARRIER)
+ .setSubscriberIds(Set.of(subscriberId))
+ .setMeteredness(NetworkStats.METERED_YES)
+ .build()
+ : new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+ .setMeteredness(NetworkStats.METERED_YES)
+ .build();
}
}
diff --git a/src/com/android/settings/display/AppGridView.java b/src/com/android/settings/display/AppGridView.java
index cda1445..a0f2a63 100644
--- a/src/com/android/settings/display/AppGridView.java
+++ b/src/com/android/settings/display/AppGridView.java
@@ -20,10 +20,12 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.IconDrawableFactory;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@@ -31,6 +33,7 @@
import android.widget.ImageView;
import androidx.annotation.VisibleForTesting;
+import androidx.core.util.Preconditions;
import com.android.settings.R;
@@ -38,7 +41,18 @@
import java.util.Collections;
import java.util.List;
+/**
+ * The grid view for displaying the application entries.
+ *
+ * <p> The attribute value {@code appCount} from XML should be more than or equal to 1, otherwise
+ * throws an {@link IllegalArgumentException}.</p>
+ */
public class AppGridView extends GridView {
+ private static final String TAG = "AppGridView";
+
+ private static final int APP_COUNT_DEF_VALUE = 6;
+ private int mAppCount = APP_COUNT_DEF_VALUE;
+
public AppGridView(Context context) {
super(context);
init(context);
@@ -46,24 +60,36 @@
public AppGridView(Context context, AttributeSet attrs) {
super(context, attrs);
+ applyAttributeSet(context, attrs);
init(context);
}
public AppGridView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ applyAttributeSet(context, attrs);
init(context);
}
public AppGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleResId) {
super(context, attrs, defStyleAttr, defStyleResId);
-
+ applyAttributeSet(context, attrs);
init(context);
-
}
private void init(Context context) {
setAdapter(new AppsAdapter(context, R.layout.screen_zoom_preview_app_icon,
- android.R.id.text1, android.R.id.icon1));
+ android.R.id.text1, android.R.id.icon1, mAppCount));
+ }
+
+ private void applyAttributeSet(Context context, AttributeSet attrs) {
+ final TypedArray styledAttrs =
+ context.obtainStyledAttributes(attrs, R.styleable.AppGridView);
+ mAppCount =
+ styledAttrs.getInteger(R.styleable.AppGridView_appCount, APP_COUNT_DEF_VALUE);
+ Preconditions.checkArgument(mAppCount >= 1,
+ /* errorMessage= */ "App count may not be negative or zero");
+
+ styledAttrs.recycle();
}
/**
@@ -73,12 +99,15 @@
public static class AppsAdapter extends ArrayAdapter<ActivityEntry> {
private final PackageManager mPackageManager;
private final int mIconResId;
+ private final int mAppCount;
- public AppsAdapter(Context context, int layout, int textResId, int iconResId) {
+ public AppsAdapter(Context context, int layout, int textResId, int iconResId,
+ int appCount) {
super(context, layout, textResId);
mIconResId = iconResId;
mPackageManager = context.getPackageManager();
+ mAppCount = appCount;
loadAllApps();
}
@@ -108,20 +137,24 @@
}
private void loadAllApps() {
- final int needAppCount = 6;
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final PackageManager pm = mPackageManager;
final ArrayList<ActivityEntry> results = new ArrayList<>();
final List<ResolveInfo> infos = pm.queryIntentActivities(mainIntent, 0);
+
+ if (mAppCount > infos.size()) {
+ Log.d(TAG, "Visible app icon count does not meet the target count.");
+ }
+
final IconDrawableFactory iconFactory = IconDrawableFactory.newInstance(getContext());
for (ResolveInfo info : infos) {
final CharSequence label = info.loadLabel(pm);
if (label != null) {
results.add(new ActivityEntry(info, label.toString(), iconFactory));
}
- if (results.size() >= needAppCount) {
+ if (results.size() >= mAppCount) {
break;
}
}
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 183a2fb..c56d89b 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -42,6 +42,7 @@
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.window.embedding.SplitController;
import androidx.window.embedding.SplitRule;
import com.android.settings.R;
@@ -85,8 +86,9 @@
private View mTwoPaneSuggestionView;
private CategoryMixin mCategoryMixin;
private Set<HomepageLoadedListener> mLoadedListeners;
+ private SplitController mSplitController;
private boolean mIsEmbeddingActivityEnabled;
- private boolean mIsTwoPaneLastTime;
+ private boolean mIsTwoPane;
/** A listener receiving homepage loaded events. */
public interface HomepageLoadedListener {
@@ -149,7 +151,8 @@
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_homepage_container);
mIsEmbeddingActivityEnabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this);
- mIsTwoPaneLastTime = ActivityEmbeddingUtils.isTwoPaneResolution(this);
+ mSplitController = SplitController.getInstance();
+ mIsTwoPane = mSplitController.isActivityEmbedded(this);
final View appBar = findViewById(R.id.app_bar_container);
appBar.setMinimumHeight(getSearchBoxHeight());
@@ -213,9 +216,9 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- final boolean isTwoPane = ActivityEmbeddingUtils.isTwoPaneResolution(this);
- if (mIsTwoPaneLastTime != isTwoPane) {
- mIsTwoPaneLastTime = isTwoPane;
+ final boolean newTwoPaneState = mSplitController.isActivityEmbedded(this);
+ if (mIsTwoPane != newTwoPaneState) {
+ mIsTwoPane = newTwoPaneState;
updateHomepageAppBar();
updateHomepageBackground();
}
@@ -254,7 +257,7 @@
}
final Window window = getWindow();
- final int color = ActivityEmbeddingUtils.isTwoPaneResolution(this)
+ final int color = mIsTwoPane
? Utils.getColorAttrDefaultColor(this, com.android.internal.R.attr.colorSurface)
: Utils.getColorAttrDefaultColor(this, android.R.attr.colorBackground);
@@ -416,7 +419,7 @@
if (!mIsEmbeddingActivityEnabled) {
return;
}
- if (ActivityEmbeddingUtils.isTwoPaneResolution(this)) {
+ if (mIsTwoPane) {
findViewById(R.id.homepage_app_bar_regular_phone_view).setVisibility(View.GONE);
findViewById(R.id.homepage_app_bar_two_pane_view).setVisibility(View.VISIBLE);
} else {
diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java
index f76a3de..7ce6730 100644
--- a/src/com/android/settings/homepage/TopLevelSettings.java
+++ b/src/com/android/settings/homepage/TopLevelSettings.java
@@ -33,6 +33,7 @@
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.window.embedding.SplitController;
import com.android.settings.R;
import com.android.settings.Utils;
@@ -144,7 +145,7 @@
if (mFirstStarted) {
mFirstStarted = false;
} else if (mIsEmbeddingActivityEnabled && isOnlyOneActivityInTask()
- && !ActivityEmbeddingUtils.isTwoPaneResolution(getActivity())) {
+ && !SplitController.getInstance().isActivityEmbedded(getActivity())) {
// Set default highlight menu key for 1-pane homepage since it will show the placeholder
// page once changing back to 2-pane.
Log.i(TAG, "Set default menu key");
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index e0f8181..ea864ea 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -309,9 +309,8 @@
mAddWifiNetworkPreference = new AddWifiNetworkPreference(getPrefContext());
mDataUsagePreference = findPreference(PREF_KEY_DATA_USAGE);
mDataUsagePreference.setVisible(DataUsageUtils.hasWifiRadio(getContext()));
- mDataUsagePreference.setTemplate(
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */), 0 /*subId*/, null /*service*/);
+ mDataUsagePreference.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI)
+ .build(), 0 /*subId*/, null /*service*/);
mResetInternetPreference = findPreference(PREF_KEY_RESET_INTERNET);
if (mResetInternetPreference != null) {
mResetInternetPreference.setVisible(false);
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index cae3cae..4ef882c 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -123,6 +123,13 @@
} catch (RemoteException e) {
Log.w(TAG, "Error calling NMS", e);
}
+ // The permission system cannot make role permissions 'fixed', so check for these
+ // roles explicitly
+ List<String> roles = rm.getHeldRolesFromController(app.packageName);
+ if (roles.contains(RoleManager.ROLE_DIALER)
+ || roles.contains(RoleManager.ROLE_EMERGENCY)) {
+ row.systemApp = row.lockedImportance = true;
+ }
} else {
row.systemApp = Utils.isSystemPackage(context.getResources(), pm, app);
List<String> roles = rm.getHeldRolesFromController(app.packageName);
diff --git a/src/com/android/settings/notification/app/VibrationPreferenceController.java b/src/com/android/settings/notification/app/VibrationPreferenceController.java
index bfbe768..34d1a54 100644
--- a/src/com/android/settings/notification/app/VibrationPreferenceController.java
+++ b/src/com/android/settings/notification/app/VibrationPreferenceController.java
@@ -25,7 +25,6 @@
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.notification.NotificationBackend;
-import com.android.settings.notification.app.NotificationPreferenceController;
import com.android.settingslib.RestrictedSwitchPreference;
public class VibrationPreferenceController extends NotificationPreferenceController
@@ -36,7 +35,7 @@
public VibrationPreferenceController(Context context, NotificationBackend backend) {
super(context, backend);
- mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ mVibrator = context.getSystemService(Vibrator.class);
}
@Override
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index a1826ba..2d6f6b0 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -614,7 +614,6 @@
disableUnusablePreferences();
updatePreferenceText();
updateCurrentPreference();
- updatePreferenceSummaryIfNeeded();
} else if (!isRecreatingActivity) {
// Don't start the activity again if we are recreated for configuration change
updateUnlockMethodAndFinish(quality, false, true /* chooseLockSkipped */);
@@ -715,13 +714,6 @@
}
}
- private void setPreferenceSummary(ScreenLockType lock, @StringRes int summary) {
- Preference preference = findPreference(lock.preferenceKey);
- if (preference != null) {
- preference.setSummary(summary);
- }
- }
-
private void updateCurrentPreference() {
String currentKey = getKeyForCurrent();
Preference preference = findPreference(currentKey);
@@ -764,28 +756,6 @@
}
}
- private void updatePreferenceSummaryIfNeeded() {
- // On a default block encrypted device with accessibility, add a warning
- // that your data is not credential encrypted
- if (!StorageManager.isBlockEncrypted()) {
- return;
- }
-
- if (StorageManager.isNonDefaultBlockEncrypted()) {
- return;
- }
-
- if (AccessibilityManager.getInstance(getActivity()).getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
- return;
- }
-
- setPreferenceSummary(ScreenLockType.PATTERN, R.string.secure_lock_encryption_warning);
- setPreferenceSummary(ScreenLockType.PIN, R.string.secure_lock_encryption_warning);
- setPreferenceSummary(ScreenLockType.PASSWORD, R.string.secure_lock_encryption_warning);
- setPreferenceSummary(ScreenLockType.MANAGED, R.string.secure_lock_encryption_warning);
- }
-
protected Intent getLockManagedPasswordIntent(LockscreenCredential password) {
return mManagedPasswordProvider.createIntent(false, password);
}
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index cc0e8a1..c2aeeaf 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -22,6 +22,7 @@
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
+import com.android.settings.safetycenter.SafetyCenterStatus;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -89,5 +90,10 @@
Context context) {
return buildPreferenceControllers(context, null);
}
+
+ @Override
+ protected boolean isPageSearchEnabled(Context context) {
+ return !SafetyCenterStatus.isEnabled();
+ }
};
}
diff --git a/src/com/android/settings/security/CryptKeeperSettings.java b/src/com/android/settings/security/CryptKeeperSettings.java
deleted file mode 100644
index 2b65bf1..0000000
--- a/src/com/android/settings/security/CryptKeeperSettings.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2008 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.Activity;
-import android.app.admin.DevicePolicyManager;
-import android.app.settings.SettingsEnums;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.os.BatteryManager;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.storage.StorageManager;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.preference.Preference;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.widget.LockscreenCredential;
-import com.android.settings.CryptKeeperConfirm;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.core.InstrumentedPreferenceFragment;
-import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.settings.password.ConfirmLockPattern;
-
-public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
- private static final String TAG = "CryptKeeper";
- private static final String TYPE = "type";
- private static final String PASSWORD = "password";
-
- private static final int KEYGUARD_REQUEST = 55;
-
- // Minimum battery charge level (in percent) to launch encryption. If the battery charge is
- // lower than this, encryption should not be activated.
- private static final int MIN_BATTERY_LEVEL = 80;
-
- private View mContentView;
- private Button mInitiateButton;
- private View mPowerWarning;
- private View mBatteryWarning;
- private IntentFilter mIntentFilter;
-
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
- final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
- final int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
- final int invalidCharger = intent.getIntExtra(
- BatteryManager.EXTRA_INVALID_CHARGER, 0);
-
- final boolean levelOk = level >= MIN_BATTERY_LEVEL;
- final boolean pluggedOk =
- ((plugged & BatteryManager.BATTERY_PLUGGED_ANY) != 0) &&
- invalidCharger == 0;
-
- // Update UI elements based on power/battery status
- mInitiateButton.setEnabled(levelOk && pluggedOk);
- mPowerWarning.setVisibility(pluggedOk ? View.GONE : View.VISIBLE );
- mBatteryWarning.setVisibility(levelOk ? View.GONE : View.VISIBLE);
- }
- }
- };
-
- /**
- * If the user clicks to begin the reset sequence, we next require a
- * keyguard confirmation if the user has currently enabled one. If there
- * is no keyguard available, we prompt the user to set a password.
- */
- private Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
- // TODO replace (or follow) this dialog with an explicit launch into password UI
- new AlertDialog.Builder(getActivity())
- .setTitle(R.string.crypt_keeper_dialog_need_password_title)
- .setMessage(R.string.crypt_keeper_dialog_need_password_message)
- .setPositiveButton(android.R.string.ok, null)
- .create()
- .show();
- }
- }
- };
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
- mContentView = inflater.inflate(R.layout.crypt_keeper_settings, null);
-
- mIntentFilter = new IntentFilter();
- mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
-
- mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_encrypt);
- mInitiateButton.setOnClickListener(mInitiateListener);
- mInitiateButton.setEnabled(false);
-
- mPowerWarning = mContentView.findViewById(R.id.warning_unplugged);
- mBatteryWarning = mContentView.findViewById(R.id.warning_low_charge);
-
- return mContentView;
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.CRYPT_KEEPER;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- getActivity().registerReceiver(mIntentReceiver, mIntentFilter,
- Context.RECEIVER_EXPORTED_UNAUDITED);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- getActivity().unregisterReceiver(mIntentReceiver);
- }
-
- /**
- * If encryption is already started, and this launched via a "start encryption" intent,
- * then exit immediately - it's already up and running, so there's no point in "starting" it.
- */
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- Activity activity = getActivity();
- Intent intent = activity.getIntent();
- if (DevicePolicyManager.ACTION_START_ENCRYPTION.equals(intent.getAction())) {
- DevicePolicyManager dpm = (DevicePolicyManager)
- activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
- int status = dpm.getStorageEncryptionStatus();
- if (status != DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE) {
- // There is nothing to do here, so simply finish() (which returns to caller)
- activity.finish();
- }
- }
- }
- activity.setTitle(R.string.crypt_keeper_encrypt_title);
- }
-
- /**
- * Keyguard validation is run using the standard {@link ConfirmLockPattern}
- * component as a subactivity
- * @param request the request code to be returned once confirmation finishes
- * @return true if confirmation launched
- */
- private boolean runKeyguardConfirmation(int request) {
- final LockPatternUtils utils = new LockPatternUtils(getActivity());
- if (utils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())
- == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- showFinalConfirmation(StorageManager.CRYPT_TYPE_DEFAULT, "".getBytes());
- return true;
- }
-
- final Resources res = getActivity().getResources();
- final ChooseLockSettingsHelper.Builder builder =
- new ChooseLockSettingsHelper.Builder(getActivity(), this);
- return builder.setRequestCode(request)
- .setTitle(res.getText(R.string.crypt_keeper_encrypt_title))
- .setReturnCredentials(true)
- .show();
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode != KEYGUARD_REQUEST) {
- return;
- }
-
- // If the user entered a valid keyguard trace, present the final
- // confirmation prompt; otherwise, go back to the initial state.
- if (resultCode == Activity.RESULT_OK && data != null) {
- int type = data.getIntExtra(ChooseLockSettingsHelper.EXTRA_KEY_TYPE, -1);
- LockscreenCredential password = data.getParcelableExtra(
- ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
- if (password != null && !password.isNone()) {
- showFinalConfirmation(type, password.getCredential());
- }
- }
- }
-
- private void showFinalConfirmation(int type, byte[] password) {
- Preference preference = new Preference(getPreferenceManager().getContext());
- preference.setFragment(CryptKeeperConfirm.class.getName());
- preference.setTitle(R.string.crypt_keeper_confirm_title);
- addEncryptionInfoToPreference(preference, type, password);
- ((SettingsActivity) getActivity()).onPreferenceStartFragment(null, preference);
- }
-
- private void addEncryptionInfoToPreference(Preference preference, int type, byte[] password) {
- Activity activity = getActivity();
- DevicePolicyManager dpm = (DevicePolicyManager)
- activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm.getDoNotAskCredentialsOnBoot()) {
- preference.getExtras().putInt(TYPE, StorageManager.CRYPT_TYPE_DEFAULT);
- preference.getExtras().putByteArray(PASSWORD, "".getBytes());
- } else {
- preference.getExtras().putInt(TYPE, type);
- preference.getExtras().putByteArray(PASSWORD, password);
- }
- }
-}
diff --git a/src/com/android/settings/security/EncryptionStatusPreferenceController.java b/src/com/android/settings/security/EncryptionStatusPreferenceController.java
index 322be10..d835798 100644
--- a/src/com/android/settings/security/EncryptionStatusPreferenceController.java
+++ b/src/com/android/settings/security/EncryptionStatusPreferenceController.java
@@ -55,15 +55,9 @@
public void updateState(Preference preference) {
final boolean encryptionEnabled = LockPatternUtils.isDeviceEncryptionEnabled();
if (encryptionEnabled) {
- if (TextUtils.equals(getPreferenceKey(), PREF_KEY_ENCRYPTION_DETAIL_PAGE)) {
- preference.setFragment(null);
- }
- preference.setSummary(R.string.crypt_keeper_encrypted_summary);
+ preference.setSummary(R.string.encrypted_summary);
} else {
- if (TextUtils.equals(getPreferenceKey(), PREF_KEY_ENCRYPTION_DETAIL_PAGE)) {
- preference.setFragment(CryptKeeperSettings.class.getName());
- }
- preference.setSummary(R.string.decryption_settings_summary);
+ preference.setSummary(R.string.not_encrypted_summary);
}
}
diff --git a/src/com/android/settings/security/RequestManageCredentials.java b/src/com/android/settings/security/RequestManageCredentials.java
index 1a8da67..6a1d40a 100644
--- a/src/com/android/settings/security/RequestManageCredentials.java
+++ b/src/com/android/settings/security/RequestManageCredentials.java
@@ -16,6 +16,8 @@
package com.android.settings.security;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
import android.annotation.Nullable;
import android.app.Activity;
import android.app.admin.DevicePolicyEventLogger;
@@ -120,6 +122,7 @@
.setStrings(mCredentialManagerPackage)
.write();
setContentView(R.layout.request_manage_credentials);
+ getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
mIsLandscapeMode = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
@@ -211,7 +214,9 @@
private void loadButtons() {
mButtonPanel = findViewById(R.id.button_panel);
Button dontAllowButton = findViewById(R.id.dont_allow_button);
+ dontAllowButton.setFilterTouchesWhenObscured(true);
Button allowButton = findViewById(R.id.allow_button);
+ allowButton.setFilterTouchesWhenObscured(true);
dontAllowButton.setOnClickListener(b -> {
DevicePolicyEventLogger
diff --git a/src/com/android/settings/security/SecurityAdvancedSettings.java b/src/com/android/settings/security/SecurityAdvancedSettings.java
index 7d8c9ff..4a73eb7 100644
--- a/src/com/android/settings/security/SecurityAdvancedSettings.java
+++ b/src/com/android/settings/security/SecurityAdvancedSettings.java
@@ -25,6 +25,8 @@
import com.android.settings.biometrics.face.FaceProfileStatusPreferenceController;
import com.android.settings.biometrics.fingerprint.FingerprintProfileStatusPreferenceController;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.safetycenter.SafetyCenterStatus;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.security.trustagent.TrustAgentListPreferenceController;
import com.android.settings.widget.PreferenceCategoryController;
@@ -47,6 +49,10 @@
private static final String TAG = "SecurityAdvancedSettings";
private static final String WORK_PROFILE_SECURITY_CATEGORY = "security_category_profile";
+ /** Used in case of old Security settings when SafetyCenter is disabled */
+ private static final String CATEGORY_SECURITY_LEGACY_ADVANCED_SETTINGS =
+ "com.android.settings.category.ia.legacy_advanced_security";
+
@Override
public int getMetricsCategory() {
return SettingsEnums.SECURITY_ADVANCED;
@@ -54,7 +60,19 @@
@Override
public String getCategoryKey() {
- return CategoryKey.CATEGORY_SECURITY_ADVANCED_SETTINGS;
+ if (SafetyCenterStatus.isEnabled()) {
+ return CategoryKey.CATEGORY_SECURITY_ADVANCED_SETTINGS;
+ } else {
+ final SecuritySettingsFeatureProvider securitySettingsFeatureProvider =
+ FeatureFactory.getFactory(getContext())
+ .getSecuritySettingsFeatureProvider();
+
+ if (securitySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment()) {
+ return securitySettingsFeatureProvider.getAlternativeAdvancedSettingsCategoryKey();
+ } else {
+ return CATEGORY_SECURITY_LEGACY_ADVANCED_SETTINGS;
+ }
+ }
}
@Override
diff --git a/src/com/android/settings/security/SecuritySettingsFeatureProvider.java b/src/com/android/settings/security/SecuritySettingsFeatureProvider.java
index 78e4bc7..128ec01 100644
--- a/src/com/android/settings/security/SecuritySettingsFeatureProvider.java
+++ b/src/com/android/settings/security/SecuritySettingsFeatureProvider.java
@@ -24,4 +24,10 @@
/** Returns the alternative SecuritySettings fragment name if available. */
String getAlternativeSecuritySettingsFragmentClassname();
+
+ /**
+ * Returns the category of SecurityAdvancedSettings fragment for the alternative
+ * SecuritySettings if available.
+ */
+ String getAlternativeAdvancedSettingsCategoryKey();
}
diff --git a/src/com/android/settings/security/SecuritySettingsFeatureProviderImpl.java b/src/com/android/settings/security/SecuritySettingsFeatureProviderImpl.java
index 8aba523..e4f540c 100644
--- a/src/com/android/settings/security/SecuritySettingsFeatureProviderImpl.java
+++ b/src/com/android/settings/security/SecuritySettingsFeatureProviderImpl.java
@@ -28,4 +28,9 @@
public String getAlternativeSecuritySettingsFragmentClassname() {
return null;
}
+
+ @Override
+ public String getAlternativeAdvancedSettingsCategoryKey() {
+ return null;
+ }
}
diff --git a/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java b/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
index 9e82e78..4d65ae7 100644
--- a/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
+++ b/src/com/android/settings/security/VisiblePatternProfilePreferenceController.java
@@ -126,6 +126,8 @@
@Override
public void onResume() {
- mPreference.setVisible(isAvailable());
+ if (mPreference != null) {
+ mPreference.setVisible(isAvailable());
+ }
}
}
diff --git a/src/com/android/settings/sound/VibrateForCallsPreferenceController.java b/src/com/android/settings/sound/VibrateForCallsPreferenceController.java
deleted file mode 100644
index 58c6ba5..0000000
--- a/src/com/android/settings/sound/VibrateForCallsPreferenceController.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2020 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.sound;
-
-import android.content.Context;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.core.BasePreferenceController;
-
-/**
- * Controller for vibrate for calls settings.
- */
-public class VibrateForCallsPreferenceController extends BasePreferenceController {
-
- private static final int ON = 1;
- private static final int OFF = 0;
- @VisibleForTesting
- static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
-
- public VibrateForCallsPreferenceController(Context context, String preferenceKey) {
- super(context, preferenceKey);
- }
-
- @Override
- @AvailabilityStatus
- public int getAvailabilityStatus() {
- return Utils.isVoiceCapable(mContext) && !DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_TELEPHONY, RAMPING_RINGER_ENABLED, false)
- ? AVAILABLE
- : UNSUPPORTED_ON_DEVICE;
- }
-
- @Override
- public CharSequence getSummary() {
- if (Settings.System.getInt(
- mContext.getContentResolver(),
- Settings.System.APPLY_RAMPING_RINGER, OFF) == ON) {
- return mContext.getText(R.string.vibrate_when_ringing_option_ramping_ringer);
- } else if (Settings.System.getInt(
- mContext.getContentResolver(),
- Settings.System.VIBRATE_WHEN_RINGING, OFF) == ON) {
- return mContext.getText(R.string.vibrate_when_ringing_option_always_vibrate);
- } else {
- return mContext.getText(R.string.vibrate_when_ringing_option_never_vibrate);
- }
- }
-}
diff --git a/src/com/android/settings/sound/VibrateForCallsPreferenceFragment.java b/src/com/android/settings/sound/VibrateForCallsPreferenceFragment.java
deleted file mode 100644
index a769de1..0000000
--- a/src/com/android/settings/sound/VibrateForCallsPreferenceFragment.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2019 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.sound;
-
-import android.app.settings.SettingsEnums;
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settings.R;
-import com.android.settings.widget.RadioButtonPickerFragment;
-import com.android.settingslib.widget.CandidateInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Fragment for changing vibrate for calls options.
- */
-public class VibrateForCallsPreferenceFragment extends RadioButtonPickerFragment {
- private static final String TAG = "VibrateForCallsPreferenceFragment";
-
- @VisibleForTesting
- static final String KEY_NEVER_VIBRATE = "never_vibrate";
- @VisibleForTesting
- static final String KEY_ALWAYS_VIBRATE = "always_vibrate";
- @VisibleForTesting
- static final String KEY_RAMPING_RINGER = "ramping_ringer";
-
- private static final int ON = 1;
- private static final int OFF = 0;
-
- private final Map<String, VibrateForCallsCandidateInfo> mCandidates;
-
- public VibrateForCallsPreferenceFragment() {
- mCandidates = new ArrayMap<>();
- }
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- loadCandidates(context);
- }
-
- private void loadCandidates(Context context) {
- mCandidates.put(KEY_NEVER_VIBRATE,
- new VibrateForCallsCandidateInfo(
- KEY_NEVER_VIBRATE, R.string.vibrate_when_ringing_option_never_vibrate));
- mCandidates.put(KEY_ALWAYS_VIBRATE,
- new VibrateForCallsCandidateInfo(
- KEY_ALWAYS_VIBRATE, R.string.vibrate_when_ringing_option_always_vibrate));
- mCandidates.put(KEY_RAMPING_RINGER,
- new VibrateForCallsCandidateInfo(
- KEY_RAMPING_RINGER, R.string.vibrate_when_ringing_option_ramping_ringer));
- }
-
- private void updateSettings(VibrateForCallsCandidateInfo candidate) {
- final String key = candidate.getKey();
- if (TextUtils.equals(key, KEY_ALWAYS_VIBRATE)) {
- Settings.System.putInt(
- getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, ON);
- Settings.System.putInt(
- getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
- } else if (TextUtils.equals(key, KEY_RAMPING_RINGER)) {
- Settings.System.putInt(
- getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, OFF);
- Settings.System.putInt(
- getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, ON);
- } else {
- Settings.System.putInt(
- getContext().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, OFF);
- Settings.System.putInt(
- getContext().getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
- }
- }
-
- @Override
- protected List<? extends CandidateInfo> getCandidates() {
- final List<VibrateForCallsCandidateInfo> candidates = new ArrayList<>();
- candidates.add(mCandidates.get(KEY_NEVER_VIBRATE));
- candidates.add(mCandidates.get(KEY_ALWAYS_VIBRATE));
- candidates.add(mCandidates.get(KEY_RAMPING_RINGER));
- return candidates;
- }
-
- @Override
- protected String getDefaultKey() {
- if (Settings.System.getInt(
- getContext().getContentResolver(),
- Settings.System.APPLY_RAMPING_RINGER, OFF) == ON) {
- return KEY_RAMPING_RINGER;
- } else if (Settings.System.getInt(
- getContext().getContentResolver(),
- Settings.System.VIBRATE_WHEN_RINGING, OFF) == ON) {
- return KEY_ALWAYS_VIBRATE;
- } else {
- return KEY_NEVER_VIBRATE;
- }
- }
-
- @Override
- protected boolean setDefaultKey(String key) {
- final VibrateForCallsCandidateInfo candidate = mCandidates.get(key);
- if (candidate == null) {
- Log.e(TAG, "Unknown vibrate for calls candidate (key = " + key + ")!");
- return false;
- }
- updateSettings(candidate);
- return true;
- }
-
- @Override
- protected int getPreferenceScreenResId() {
- return R.xml.vibrate_for_calls_settings;
- }
-
- @Override
- public int getMetricsCategory() {
- return SettingsEnums.VIBRATE_FOR_CALLS;
- }
-
- @VisibleForTesting
- class VibrateForCallsCandidateInfo extends CandidateInfo {
- private final String mKey;
- private final int mLabelId;
-
- VibrateForCallsCandidateInfo(String key, int labelId) {
- super(true /* enabled */);
- mKey = key;
- mLabelId = labelId;
- }
-
- @Override
- public CharSequence loadLabel() {
- return getContext().getString(mLabelId);
- }
-
- @Override
- public Drawable loadIcon() {
- return null;
- }
-
- @Override
- public String getKey() {
- return mKey;
- }
- }
-}
diff --git a/src/com/android/settings/users/UserCapabilities.java b/src/com/android/settings/users/UserCapabilities.java
index 7af6c64..620738f 100644
--- a/src/com/android/settings/users/UserCapabilities.java
+++ b/src/com/android/settings/users/UserCapabilities.java
@@ -23,6 +23,7 @@
import android.os.UserManager;
import android.provider.Settings;
+import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -30,7 +31,7 @@
public class UserCapabilities {
boolean mEnabled = true;
boolean mCanAddUser = true;
- boolean mCanAddRestrictedProfile = true;
+ boolean mCanAddRestrictedProfile;
boolean mIsAdmin;
boolean mIsGuest;
boolean mUserSwitcherEnabled;
@@ -57,12 +58,13 @@
caps.mIsAdmin = myUserInfo.isAdmin();
DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
Context.DEVICE_POLICY_SERVICE);
- // No restricted profiles for tablets with a device owner, or phones.
- if (dpm.isDeviceManaged()
- || Utils.isVoiceCapable(context)
- || !userManager.isUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED)) {
- caps.mCanAddRestrictedProfile = false;
- }
+
+ boolean offerRestricted =
+ context.getResources().getBoolean(R.bool.config_offer_restricted_profiles);
+ caps.mCanAddRestrictedProfile =
+ offerRestricted && !dpm.isDeviceManaged() && userManager.isUserTypeEnabled(
+ UserManager.USER_TYPE_FULL_RESTRICTED);
+
caps.updateAddUserCapabilities(context);
return caps;
}
diff --git a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
index ff8f805..ddd57f3 100644
--- a/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
+++ b/src/com/android/settings/widget/HighlightableTopLevelPreferenceAdapter.java
@@ -31,10 +31,10 @@
import androidx.preference.PreferenceGroupAdapter;
import androidx.preference.PreferenceViewHolder;
import androidx.recyclerview.widget.RecyclerView;
+import androidx.window.embedding.SplitController;
import com.android.settings.R;
import com.android.settings.Utils;
-import com.android.settings.activityembedding.ActivityEmbeddingUtils;
import com.android.settings.homepage.SettingsHomepageActivity;
/**
@@ -255,6 +255,6 @@
}
private boolean isHighlightNeeded() {
- return ActivityEmbeddingUtils.isTwoPaneResolution(mHomepageActivity);
+ return SplitController.getInstance().isActivityEmbedded(mHomepageActivity);
}
}
diff --git a/src/com/android/settings/wifi/AddWifiNetworkPreference.java b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
index ff4d38e..1820539 100644
--- a/src/com/android/settings/wifi/AddWifiNetworkPreference.java
+++ b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
@@ -26,8 +26,10 @@
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.wifi.dpp.WifiDppUtils;
+import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
/**
* The Preference for users to add Wi-Fi networks in WifiSettings
@@ -37,6 +39,8 @@
private static final String TAG = "AddWifiNetworkPreference";
private final Drawable mScanIconDrawable;
+ @VisibleForTesting
+ boolean mIsAddWifiConfigAllow;
public AddWifiNetworkPreference(Context context) {
super(context);
@@ -47,6 +51,8 @@
setTitle(R.string.wifi_add_network);
mScanIconDrawable = getDrawable(R.drawable.ic_scan_24dp);
+ mIsAddWifiConfigAllow = WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(context);
+ updatePreferenceForRestriction();
}
@Override
@@ -73,4 +79,12 @@
}
return buttonIcon;
}
+
+ @VisibleForTesting
+ void updatePreferenceForRestriction() {
+ if (!mIsAddWifiConfigAllow) {
+ setEnabled(false);
+ setSummary(R.string.not_allowed_by_ent);
+ }
+ }
}
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index 127c882..9e96be9 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -169,6 +169,7 @@
private String mUnspecifiedCertString;
private String mMultipleCertSetString;
private String mUseSystemCertsString;
+ private String mTrustOnFirstUse;
private String mDoNotProvideEapUserCertString;
@VisibleForTesting String mInstallCertsString;
@@ -219,6 +220,7 @@
Integer[] mSecurityInPosition;
private final WifiManager mWifiManager;
+ private boolean mIsTrustOnFirstUseSupported;
private final List<SubscriptionInfo> mActiveSubscriptionInfos = new ArrayList<>();
@@ -251,6 +253,7 @@
mWifiEntrySecurity = (wifiEntry == null) ? WifiEntry.SECURITY_NONE :
wifiEntry.getSecurity();
mMode = mode;
+ mIsTrustOnFirstUseSupported = mWifiManager.isTrustOnFirstUseSupported();
final Resources res = mContext.getResources();
@@ -268,6 +271,7 @@
mUnspecifiedCertString = mContext.getString(R.string.wifi_unspecified);
mMultipleCertSetString = mContext.getString(R.string.wifi_multiple_cert_added);
mUseSystemCertsString = mContext.getString(R.string.wifi_use_system_certs);
+ mTrustOnFirstUse = mContext.getString(R.string.wifi_trust_on_first_use);
mDoNotProvideEapUserCertString =
mContext.getString(R.string.wifi_do_not_provide_eap_user_cert);
mInstallCertsString = mContext.getString(R.string.wifi_install_credentials);
@@ -707,6 +711,8 @@
config.enterpriseConfig.setDomainSuffixMatch(mEapDomainView.getText().toString());
if (caCert.equals(mUnspecifiedCertString)) {
// ca_cert already set to null, so do nothing.
+ } else if (mIsTrustOnFirstUseSupported && caCert.equals(mTrustOnFirstUse)) {
+ config.enterpriseConfig.enableTrustOnFirstUse(true);
} else if (caCert.equals(mUseSystemCertsString)) {
config.enterpriseConfig.setCaPath(SYSTEM_CA_STORE_PATH);
} else if (caCert.equals(mMultipleCertSetString)) {
@@ -1120,7 +1126,12 @@
} else {
String[] caCerts = enterpriseConfig.getCaCertificateAliases();
if (caCerts == null) {
- setSelection(mEapCaCertSpinner, mUnspecifiedCertString);
+ if (mIsTrustOnFirstUseSupported
+ && enterpriseConfig.isTrustOnFirstUseEnabled()) {
+ setSelection(mEapCaCertSpinner, mTrustOnFirstUse);
+ } else {
+ setSelection(mEapCaCertSpinner, mUnspecifiedCertString);
+ }
} else if (caCerts.length == 1) {
setSelection(mEapCaCertSpinner, caCerts[0]);
} else {
@@ -1263,7 +1274,9 @@
if (mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) {
String eapCertSelection = (String) mEapCaCertSpinner.getSelectedItem();
- if (eapCertSelection.equals(mUnspecifiedCertString)) {
+ if (eapCertSelection.equals(mUnspecifiedCertString)
+ || (mIsTrustOnFirstUseSupported
+ && eapCertSelection.equals(mTrustOnFirstUse))) {
// Domain suffix matching is not relevant if the user hasn't chosen a CA
// certificate yet, or chooses not to validate the EAP server.
setDomainInvisible();
@@ -1511,6 +1524,9 @@
}
if (showUsePreinstalledCertOption) {
certs.add(mUseSystemCertsString);
+ if (mIsTrustOnFirstUseSupported) {
+ certs.add(mTrustOnFirstUse);
+ }
certs.add(mInstallCertsString);
}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index b779a72..bbddd98 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -270,9 +270,8 @@
mStatusMessagePreference = findPreference(PREF_KEY_STATUS_MESSAGE);
mDataUsagePreference = findPreference(PREF_KEY_DATA_USAGE);
mDataUsagePreference.setVisible(DataUsageUtils.hasWifiRadio(getContext()));
- mDataUsagePreference.setTemplate(
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */), 0 /*subId*/, null /*service*/);
+ mDataUsagePreference.setTemplate(new NetworkTemplate.Builder(
+ NetworkTemplate.MATCH_WIFI).build(), 0 /*subId*/, null /*service*/);
}
@Override
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
index 6bf9104..f1e6568 100644
--- a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
@@ -36,6 +36,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin;
+import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
/**
* When apps send a new intent with a WifiConfiguration list extra to Settings APP. Settings APP
@@ -55,6 +56,8 @@
final Bundle mBundle = new Bundle();
@VisibleForTesting
IActivityManager mActivityManager = ActivityManager.getService();
+ @VisibleForTesting
+ boolean mIsAddWifiConfigAllow;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -71,6 +74,8 @@
window.setGravity(Gravity.BOTTOM);
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);
+
+ mIsAddWifiConfigAllow = WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(this);
}
@Override
@@ -85,6 +90,10 @@
@VisibleForTesting
protected boolean showAddNetworksFragment() {
+ if (!mIsAddWifiConfigAllow) {
+ Log.d(TAG, "Not allowed by Enterprise Restriction");
+ return false;
+ }
String packageName = getCallingAppPackageName();
if (TextUtils.isEmpty(packageName)) {
Log.d(TAG, "Package name is null");
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.java
new file mode 100644
index 0000000..f1e1121b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsTooltipWindowTest.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.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.PopupWindow;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowLooper;
+
+/** Tests for {@link AccessibilityQuickSettingsTooltipWindow}. */
+@RunWith(RobolectricTestRunner.class)
+public class AccessibilityQuickSettingsTooltipWindowTest {
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock
+ private PopupWindow.OnDismissListener mMockOnDismissListener;
+
+ private static final String TEST_PACKAGE_NAME = "com.test.package";
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+ private AccessibilityQuickSettingsTooltipWindow mToolTipView;
+ private View mView;
+
+ @Before
+ public void setUp() {
+ mToolTipView = new AccessibilityQuickSettingsTooltipWindow(mContext);
+ mView = new View(RuntimeEnvironment.application);
+ }
+
+ @Test
+ public void initToolTipView_atMostAvailableTextWidth() {
+ final String quickSettingsTooltipsContent = mContext.getString(
+ R.string.accessibility_service_quick_settings_tooltips_content, TEST_PACKAGE_NAME);
+ mToolTipView.setup(quickSettingsTooltipsContent);
+
+ final int getMaxWidth = mToolTipView.getAvailableWindowWidth();
+ assertThat(mToolTipView.getWidth()).isAtMost(getMaxWidth);
+ }
+
+ @Test
+ public void showToolTipView_success() {
+ mToolTipView.setup(TEST_PACKAGE_NAME);
+ assertThat(getLatestPopupWindow()).isNull();
+
+ mToolTipView.showAtTopCenter(mView);
+
+ assertThat(getLatestPopupWindow()).isSameInstanceAs(mToolTipView);
+ }
+
+ @Test
+ public void dismiss_toolTipViewShown_shouldInvokeCallbackAndNotShowing() {
+ mToolTipView.setup(TEST_PACKAGE_NAME);
+ mToolTipView.setOnDismissListener(mMockOnDismissListener);
+ mToolTipView.showAtTopCenter(mView);
+
+ mToolTipView.dismiss();
+
+ verify(mMockOnDismissListener).onDismiss();
+ assertThat(getLatestPopupWindow().isShowing()).isFalse();
+ }
+
+ @Test
+ public void waitAutoCloseDelayTime_toolTipViewShown_shouldInvokeCallbackAndNotShowing() {
+ mToolTipView.setup(TEST_PACKAGE_NAME, /* closeDelayTimeMillis= */ 1);
+ mToolTipView.setOnDismissListener(mMockOnDismissListener);
+ mToolTipView.showAtTopCenter(mView);
+
+ ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+ verify(mMockOnDismissListener).onDismiss();
+ assertThat(getLatestPopupWindow().isShowing()).isFalse();
+ }
+
+ private static PopupWindow getLatestPopupWindow() {
+ final ShadowApplication shadowApplication = Shadow.extract(RuntimeEnvironment.application);
+ return shadowApplication.getLatestPopupWindow();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
index c9f1b66..d1c59f7 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java
@@ -52,7 +52,6 @@
import com.android.internal.content.PackageMonitor;
import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedPreference;
@@ -144,22 +143,6 @@
}
@Test
- @Config(shadows = {ShadowDeviceConfig.class})
- public void isRampingRingerEnabled_settingsFlagOn_Enabled() {
- Settings.System.putInt(
- mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, ON);
- assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isTrue();
- }
-
- @Test
- @Config(shadows = {ShadowDeviceConfig.class})
- public void isRampingRingerEnabled_settingsFlagOff_Disabled() {
- Settings.System.putInt(
- mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, OFF);
- assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isFalse();
- }
-
- @Test
public void getServiceSummary_serviceCrash_showsStopped() {
mServiceInfo.crashed = true;
diff --git a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java
index a454831..4e8b3f6 100644
--- a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackIntensityPreferenceControllerTest.java
@@ -18,42 +18,136 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class HapticFeedbackIntensityPreferenceControllerTest {
+ private static final String PREFERENCE_KEY = "preference_key";
+ private static final int OFF = 0;
+ private static final int ON = 1;
+
+ @Mock
+ private PreferenceScreen mScreen;
+
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
+ private Vibrator mVibrator;
private HapticFeedbackIntensityPreferenceController mController;
+ private SeekBarPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
- mContext = RuntimeEnvironment.application;
- mController = new HapticFeedbackIntensityPreferenceController(mContext);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mVibrator = mContext.getSystemService(Vibrator.class);
+ mController = new HapticFeedbackIntensityPreferenceController(mContext, PREFERENCE_KEY);
+ mLifecycle.addObserver(mController);
+ mPreference = new SeekBarPreference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ showPreference();
}
@Test
public void verifyConstants() {
- assertThat(mController.getPreferenceKey())
- .isEqualTo(HapticFeedbackIntensityPreferenceController.PREF_KEY);
+ assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
+ assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+ }
+
+ @Test
+ public void missingSetting_shouldReturnDefault() {
+ Settings.System.putString(mContext.getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY, /* value= */ null);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress())
+ .isEqualTo(mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
+ }
+
+ @Test
+ public void updateState_shouldDisplayIntensityInSliderPosition() {
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ }
+
+ @Test
+ public void setProgress_updatesIntensityAndDependentSettings() throws Exception {
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
+ }
+
+ private void updateSetting(String key, int value) {
+ Settings.System.putInt(mContext.getContentResolver(), key, value);
+ }
+
+ private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+ return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mScreen);
}
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..25455f4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/HapticFeedbackTogglePreferenceControllerTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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 static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class HapticFeedbackTogglePreferenceControllerTest {
+
+ private static final String PREFERENCE_KEY = "preference_key";
+ private static final int OFF = 0;
+ private static final int ON = 1;
+
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private LifecycleOwner mLifecycleOwner;
+ private Lifecycle mLifecycle;
+ private Context mContext;
+ private Vibrator mVibrator;
+ private HapticFeedbackTogglePreferenceController mController;
+ private SwitchPreference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLifecycleOwner = () -> mLifecycle;
+ mLifecycle = new Lifecycle(mLifecycleOwner);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mVibrator = mContext.getSystemService(Vibrator.class);
+ mController = new HapticFeedbackTogglePreferenceController(mContext, PREFERENCE_KEY);
+ mLifecycle.addObserver(mController);
+ mPreference = new SwitchPreference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ showPreference();
+ }
+
+ @Test
+ public void verifyConstants() {
+ assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void missingSetting_shouldReturnDefault() {
+ Settings.System.putString(mContext.getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY, /* value= */ null);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void updateState_shouldDisplayOnOffState() {
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
+ updateSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isFalse();
+
+ mPreference.setChecked(true);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+ .isEqualTo(mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_TOUCH));
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(ON);
+
+ mPreference.setChecked(false);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.HAPTIC_FEEDBACK_ENABLED)).isEqualTo(OFF);
+ }
+
+ private void updateSetting(String key, int value) {
+ Settings.System.putInt(mContext.getContentResolver(), key, value);
+ }
+
+ private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+ return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mScreen);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
index 41accfb..9dbd6d1 100644
--- a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationIntensityPreferenceControllerTest.java
@@ -16,24 +16,22 @@
package com.android.settings.accessibility;
-import static android.provider.Settings.System.NOTIFICATION_VIBRATION_INTENSITY;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.content.res.Resources;
+import android.os.VibrationAttributes;
import android.os.Vibrator;
import android.provider.Settings;
import androidx.lifecycle.LifecycleOwner;
-import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
-import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.SeekBarPreference;
import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before;
@@ -42,115 +40,105 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class NotificationVibrationIntensityPreferenceControllerTest {
+ private static final String PREFERENCE_KEY = "preference_key";
+
@Mock
private PreferenceScreen mScreen;
private LifecycleOwner mLifecycleOwner;
private Lifecycle mLifecycle;
private Context mContext;
- private Resources mResources;
+ private Vibrator mVibrator;
private NotificationVibrationIntensityPreferenceController mController;
- private Preference mPreference;
+ private SeekBarPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
- mContext = spy(RuntimeEnvironment.application);
- mResources = spy(mContext.getResources());
- when(mContext.getResources()).thenReturn(mResources);
- when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
- .thenReturn(true);
- mController = new NotificationVibrationIntensityPreferenceController(mContext) {
- @Override
- protected int getDefaultIntensity() {
- return 10;
- }
- };
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mVibrator = mContext.getSystemService(Vibrator.class);
+ mController = new NotificationVibrationIntensityPreferenceController(mContext,
+ PREFERENCE_KEY);
mLifecycle.addObserver(mController);
- mPreference = new Preference(mContext);
- mPreference.setSummary("Test");
- when(mScreen.findPreference(mController.getPreferenceKey()))
- .thenReturn(mPreference);
+ mPreference = new SeekBarPreference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ showPreference();
}
@Test
public void verifyConstants() {
- assertThat(mController.getPreferenceKey())
- .isEqualTo(NotificationVibrationIntensityPreferenceController.PREF_KEY);
+ assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
+ assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
@Test
- public void updateState_withMultipleIntensitySuport_shouldRefreshSummary() {
- setSupportsMultipleIntensities(true);
- showPreference();
-
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+ public void missingSetting_shouldReturnDefault() {
+ Settings.System.putString(mContext.getContentResolver(),
+ Settings.System.NOTIFICATION_VIBRATION_INTENSITY, /* value= */ null);
mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_low));
-
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
- mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_high));
-
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
- mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_medium));
-
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
- mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.accessibility_vibration_intensity_off));
+ assertThat(mPreference.getProgress()).isEqualTo(
+ mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
}
@Test
- public void updateState_withoutMultipleIntensitySupport_shouldRefreshSummary() {
- setSupportsMultipleIntensities(false);
- showPreference();
-
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+ public void updateState_shouldDisplayIntensityInSliderPosition() {
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_HIGH);
mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.switch_on_text));
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM);
mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.switch_on_text));
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_LOW);
mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.switch_on_text));
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
- Settings.System.putInt(mContext.getContentResolver(),
- NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_OFF);
mController.updateState(mPreference);
- assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getString(R.string.switch_off_text));
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
}
- private void setSupportsMultipleIntensities(boolean hasSupport) {
- when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
- .thenReturn(hasSupport);
+
+ @Test
+ public void setProgress_updatesIntensitySetting() throws Exception {
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
+ assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
+ assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+ }
+
+ private void updateSetting(String key, int value) {
+ Settings.System.putInt(mContext.getContentResolver(), key, value);
+ }
+
+ private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+ return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
private void showPreference() {
diff --git a/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..d40d779
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/NotificationVibrationTogglePreferenceControllerTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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 static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class NotificationVibrationTogglePreferenceControllerTest {
+
+ private static final String PREFERENCE_KEY = "preference_key";
+
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private LifecycleOwner mLifecycleOwner;
+ private Lifecycle mLifecycle;
+ private Context mContext;
+ private Vibrator mVibrator;
+ private NotificationVibrationTogglePreferenceController mController;
+ private SwitchPreference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLifecycleOwner = () -> mLifecycle;
+ mLifecycle = new Lifecycle(mLifecycleOwner);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mVibrator = mContext.getSystemService(Vibrator.class);
+ mController = new NotificationVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
+ mLifecycle.addObserver(mController);
+ mPreference = new SwitchPreference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ showPreference();
+ }
+
+ @Test
+ public void verifyConstants() {
+ assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void missingSetting_shouldReturnDefault() {
+ Settings.System.putString(mContext.getContentResolver(),
+ Settings.System.NOTIFICATION_VIBRATION_INTENSITY, /* value= */ null);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void updateState_shouldDisplayOnOffState() {
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_HIGH);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_LOW);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
+ updateSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isFalse();
+
+ mPreference.setChecked(true);
+ assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY)).isEqualTo(
+ mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_NOTIFICATION));
+
+ mPreference.setChecked(false);
+ assertThat(readSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ }
+
+ private void updateSetting(String key, int value) {
+ Settings.System.putInt(mContext.getContentResolver(), key, value);
+ }
+
+ private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+ return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mScreen);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
index 0eaf008..4e1730e 100644
--- a/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceControllerTest.java
@@ -16,18 +16,24 @@
package com.android.settings.accessibility;
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
import android.content.Context;
+import android.os.VibrationAttributes;
import android.os.Vibrator;
+import android.provider.Settings;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.widget.SeekBarPreference;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,29 +44,112 @@
/** Tests for {@link RingVibrationIntensityPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
public class RingVibrationIntensityPreferenceControllerTest {
- @Mock
- private Vibrator mVibrator;
+ private static final String PREFERENCE_KEY = "preference_key";
+ private static final int OFF = 0;
+ private static final int ON = 1;
+
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private LifecycleOwner mLifecycleOwner;
+ private Lifecycle mLifecycle;
+ private Context mContext;
+ private Vibrator mVibrator;
private RingVibrationIntensityPreferenceController mController;
+ private SeekBarPreference mPreference;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
MockitoAnnotations.initMocks(this);
-
- final Context mContext = spy(ApplicationProvider.getApplicationContext());
- doReturn(mVibrator).when(mContext).getSystemService(Vibrator.class);
- mController = new RingVibrationIntensityPreferenceController(mContext);
+ mLifecycleOwner = () -> mLifecycle;
+ mLifecycle = new Lifecycle(mLifecycleOwner);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mVibrator = mContext.getSystemService(Vibrator.class);
+ mController = new RingVibrationIntensityPreferenceController(mContext, PREFERENCE_KEY);
+ mLifecycle.addObserver(mController);
+ mPreference = new SeekBarPreference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ showPreference();
}
@Test
- public void getAvailabilityStatus_available() {
- assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ public void verifyConstants() {
+ assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE);
+ assertThat(mController.getMin()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(mController.getMax()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
}
@Test
- public void getDefaultIntensity_success() {
- doReturn(/* toBeReturned= */ 5).when(mVibrator).getDefaultRingVibrationIntensity();
+ public void missingSetting_shouldReturnDefault() {
+ Settings.System.putString(mContext.getContentResolver(),
+ Settings.System.RING_VIBRATION_INTENSITY, /* value= */ null);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(
+ mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
+ }
- assertThat(mController.getDefaultIntensity()).isEqualTo(/* expected= */ 5);
+ @Test
+ public void updateState_shouldDisplayIntensityInSliderPosition() {
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.getProgress()).isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ }
+
+
+ @Test
+ public void setProgress_updatesIntensityAndDependentSettings() throws Exception {
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_LOW);
+ assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_LOW);
+ assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_HIGH);
+ assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_HIGH);
+ assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+ mPreference.setProgress(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
+ }
+
+ private void updateSetting(String key, int value) {
+ Settings.System.putInt(mContext.getContentResolver(), key, value);
+ }
+
+ private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+ return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mScreen);
}
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java
deleted file mode 100644
index e2b1051..0000000
--- a/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2019 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 static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
-
-import org.junit.Before;
-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)
-public class RingVibrationPreferenceFragmentTest {
-
- private Context mContext;
- private RingVibrationPreferenceFragment mFragment;
-
- @Before
- public void setUp() {
- mContext = RuntimeEnvironment.application;
- mFragment = spy(new RingVibrationPreferenceFragment());
- doReturn(mContext).when(mFragment).getContext();
- }
-
- @Test
- @Config(shadows = {ShadowDeviceConfig.class})
- public void getVibrationEnabledSetting_rampingRingerEnabled_returnApplyRampingRinger() {
- // Turn on both flags to enable ramping ringer.
- Settings.System.putInt(
- mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 1 /* ON */);
- assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo(
- Settings.System.APPLY_RAMPING_RINGER);
- }
-
- @Test
- public void getVibrationEnabledSetting_rampingRingerDisabled_returnVibrationWhenRinging() {
- // Turn off Settings.System.APPLY_RAMPING_RINGER to disable ramping ringer.
- Settings.System.putInt(
- mContext.getContentResolver(), Settings.System.APPLY_RAMPING_RINGER, 0 /* OFF */);
- assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo(
- Settings.System.VIBRATE_WHEN_RINGING);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..2d1c69c
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationTogglePreferenceControllerTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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 static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.VibrationAttributes;
+import android.os.Vibrator;
+import android.provider.Settings;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class RingVibrationTogglePreferenceControllerTest {
+
+ private static final String PREFERENCE_KEY = "preference_key";
+ private static final int OFF = 0;
+ private static final int ON = 1;
+
+ @Mock
+ private PreferenceScreen mScreen;
+
+ private LifecycleOwner mLifecycleOwner;
+ private Lifecycle mLifecycle;
+ private Context mContext;
+ private Vibrator mVibrator;
+ private RingVibrationTogglePreferenceController mController;
+ private SwitchPreference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLifecycleOwner = () -> mLifecycle;
+ mLifecycle = new Lifecycle(mLifecycleOwner);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mVibrator = mContext.getSystemService(Vibrator.class);
+ mController = new RingVibrationTogglePreferenceController(mContext, PREFERENCE_KEY);
+ mLifecycle.addObserver(mController);
+ mPreference = new SwitchPreference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ showPreference();
+ }
+
+ @Test
+ public void verifyConstants() {
+ assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void missingSetting_shouldReturnDefault() {
+ Settings.System.putString(mContext.getContentResolver(),
+ Settings.System.RING_VIBRATION_INTENSITY, /* value= */ null);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void updateState_shouldDisplayOnOffState() {
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_MEDIUM);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_LOW);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setChecked_updatesIntensityAndDependentSettings() throws Exception {
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isFalse();
+
+ mPreference.setChecked(true);
+ assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY)).isEqualTo(
+ mVibrator.getDefaultVibrationIntensity(VibrationAttributes.USAGE_RINGTONE));
+ assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(ON);
+
+ mPreference.setChecked(false);
+ assertThat(readSetting(Settings.System.RING_VIBRATION_INTENSITY))
+ .isEqualTo(Vibrator.VIBRATION_INTENSITY_OFF);
+ assertThat(readSetting(Settings.System.VIBRATE_WHEN_RINGING)).isEqualTo(OFF);
+ }
+
+ private void updateSetting(String key, int value) {
+ Settings.System.putInt(mContext.getContentResolver(), key, value);
+ }
+
+ private int readSetting(String settingKey) throws Settings.SettingNotFoundException {
+ return Settings.System.getInt(mContext.getContentResolver(), settingKey);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mScreen);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
deleted file mode 100644
index e4d0f45..0000000
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 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.os.Vibrator;
-import android.provider.Settings;
-
-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.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class VibrationPreferenceControllerTest {
-
- private static final String VIBRATION_ON = "On";
- private static final String VIBRATION_OFF = "Off";
-
- private Context mContext;
- private VibrationPreferenceController mController;
-
- @Before
- public void setUp() {
- mContext = RuntimeEnvironment.application;
- mController = new VibrationPreferenceController(mContext, "vibration_pref");
- }
-
- @Test
- public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
- assertThat(mController.getAvailabilityStatus())
- .isEqualTo(BasePreferenceController.AVAILABLE);
- }
-
- @Test
- public void getSummary_disabledVibration_shouldReturnOffSummary() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
- final String expectedResult = mContext.getString(R.string.switch_off_text);
-
- assertThat(mController.getSummary()).isEqualTo(expectedResult);
- }
-
- @Test
- public void getSummary_enabledSomeVibration_shouldReturnVibrationOnSummary() {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.VIBRATE_WHEN_RINGING, 1);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.NOTIFICATION_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.HAPTIC_FEEDBACK_INTENSITY, Vibrator.VIBRATION_INTENSITY_MEDIUM);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.HAPTIC_FEEDBACK_ENABLED, 1);
- final String expectedResult = mContext.getString(R.string.accessibility_vibration_summary,
- VIBRATION_ON /* ring */,
- VIBRATION_OFF /* notification */,
- VIBRATION_ON /* touch */);
-
- assertThat(mController.getSummary()).isEqualTo(expectedResult);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
deleted file mode 100644
index 9f83f72..0000000
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceFragmentTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.accessibility;
-
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_HIGH;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_LOW;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_MEDIUM;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_OFF;
-import static com.android.settings.accessibility.VibrationPreferenceFragment.KEY_INTENSITY_ON;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.UserManager;
-import android.os.Vibrator;
-import android.provider.Settings;
-
-import com.android.settings.R;
-import com.android.settings.accessibility.VibrationPreferenceFragment
- .VibrationIntensityCandidateInfo;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settingslib.widget.CandidateInfo;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@RunWith(RobolectricTestRunner.class)
-public class VibrationPreferenceFragmentTest {
-
- private static final Map<Integer, String> INTENSITY_TO_KEY = new HashMap<>(4);
- static {
- INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_OFF, KEY_INTENSITY_OFF);
- INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_LOW, KEY_INTENSITY_LOW);
- INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_MEDIUM, KEY_INTENSITY_MEDIUM);
- INTENSITY_TO_KEY.put(Vibrator.VIBRATION_INTENSITY_HIGH, KEY_INTENSITY_HIGH);
- }
-
- @Mock
- private UserManager mUserManager;
-
- private Context mContext;
- private Resources mResources;
- private TestVibrationPreferenceFragment mFragment;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- FakeFeatureFactory.setupForTest();
-
- mContext = spy(RuntimeEnvironment.application);
- mResources = spy(mContext.getResources());
- when(mContext.getResources()).thenReturn(mResources);
-
- mFragment = spy(new TestVibrationPreferenceFragment());
- when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
- }
-
- @Test
- public void changeIntensitySetting_shouldResultInCorrespondingKey() {
- setSupportsMultipleIntensities(true);
- mFragment.onAttach(mContext);
- for (Map.Entry<Integer, String> entry : INTENSITY_TO_KEY.entrySet()) {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.HAPTIC_FEEDBACK_INTENSITY, entry.getKey());
- assertThat(mFragment.getDefaultKey()).isEqualTo(entry.getValue());
- }
- }
-
- @Test
- public void changeIntensitySetting_WithoutMultipleIntensitySupport_shouldResultInOn() {
- setSupportsMultipleIntensities(false);
- mFragment.onAttach(mContext);
- for (int intensity : INTENSITY_TO_KEY.keySet()) {
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.HAPTIC_FEEDBACK_INTENSITY, intensity);
- final String expectedKey = intensity == Vibrator.VIBRATION_INTENSITY_OFF
- ? KEY_INTENSITY_OFF
- : KEY_INTENSITY_ON;
- assertThat(mFragment.getDefaultKey()).isEqualTo(expectedKey);
- }
- }
-
- @Test
- public void initialDefaultKey_shouldBeMedium() {
- setSupportsMultipleIntensities(true);
- mFragment.onAttach(mContext);
- assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_MEDIUM);
- }
-
- @Test
- public void initialDefaultKey_WithoutMultipleIntensitySupport_shouldBeOn() {
- setSupportsMultipleIntensities(false);
- mFragment.onAttach(mContext);
- assertThat(mFragment.getDefaultKey()).isEqualTo(KEY_INTENSITY_ON);
- }
-
- @Test
- public void candidates_shouldBeSortedByIntensity() {
- setSupportsMultipleIntensities(true);
- mFragment.onAttach(mContext);
- final List<? extends CandidateInfo> candidates = mFragment.getCandidates();
- assertThat(candidates.size()).isEqualTo(INTENSITY_TO_KEY.size());
- VibrationIntensityCandidateInfo prevCandidate =
- (VibrationIntensityCandidateInfo) candidates.get(0);
- for (int i = 1; i < candidates.size(); i++) {
- VibrationIntensityCandidateInfo candidate =
- (VibrationIntensityCandidateInfo) candidates.get(i);
- assertThat(candidate.getIntensity()).isLessThan(prevCandidate.getIntensity());
- }
- }
-
- private void setSupportsMultipleIntensities(boolean hasSupport) {
- when(mResources.getBoolean(R.bool.config_vibration_supports_multiple_intensities))
- .thenReturn(hasSupport);
- }
-
- private class TestVibrationPreferenceFragment extends VibrationPreferenceFragment {
- @Override
- protected int getPreferenceScreenResId() {
- return 0;
- }
-
- @Override
- public int getMetricsCategory() {
- return 0;
- }
-
- /**
- * Get the setting string of the vibration intensity setting this preference is dealing with.
- */
- @Override
- protected String getVibrationIntensitySetting() {
- return Settings.System.HAPTIC_FEEDBACK_INTENSITY;
- }
-
- @Override
- protected String getVibrationEnabledSetting() {
- return "";
- }
-
- @Override
- protected int getDefaultVibrationIntensity() {
- return Vibrator.VIBRATION_INTENSITY_MEDIUM;
- }
-
- @Override
- public Context getContext() {
- return mContext;
- }
- }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java
new file mode 100644
index 0000000..08831c8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationRampingRingerTogglePreferenceControllerTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Vibrator;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class VibrationRampingRingerTogglePreferenceControllerTest {
+
+ private static final String PREFERENCE_KEY = "preference_key";
+
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private AudioManager mAudioManager;
+
+ private LifecycleOwner mLifecycleOwner;
+ private Lifecycle mLifecycle;
+ private Context mContext;
+ private VibrationRampingRingerTogglePreferenceController mController;
+ private SwitchPreference mPreference;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLifecycleOwner = () -> mLifecycle;
+ mLifecycle = new Lifecycle(mLifecycleOwner);
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+ when(mContext.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
+ mController = new VibrationRampingRingerTogglePreferenceController(mContext,
+ PREFERENCE_KEY);
+ mLifecycle.addObserver(mController);
+ mPreference = new SwitchPreference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ showPreference();
+ }
+
+ @Test
+ public void verifyConstants() {
+ assertThat(mController.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
+ }
+
+ @Test
+ public void getAvailabilityStatus_notVoiceCapable_returnUnsupportedOnDevice() {
+ when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "false", false);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_rampingRingerEnabled_returnUnsupportedOnDevice() {
+ when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "true", false);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_voiceCapableAndRampingRingerDisabled_returnAvailable() {
+ when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ VibrationRampingRingerTogglePreferenceController.DEVICE_CONFIG_KEY, "false", false);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ public void updateState_withRingDisabled_shouldReturnFalseForCheckedAndEnabled() {
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+ when(mAudioManager.isRampingRingerEnabled()).thenReturn(true);
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void updateState_withRingEnabled_shouldReturnTheSettingStateAndAlwaysEnabled() {
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+ when(mAudioManager.isRampingRingerEnabled()).thenReturn(true, false);
+
+ mController.updateState(mPreference);
+ assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreference.isChecked()).isTrue();
+
+ mController.updateState(mPreference);
+ assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void setChecked_withRingDisabled_ignoresUpdates() {
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_OFF);
+
+ mPreference.setChecked(true);
+ mPreference.setChecked(false);
+ verify(mAudioManager, never()).setRampingRingerEnabled(anyBoolean());
+ }
+
+ @Test
+ public void setChecked_withRingEnabled_updatesSetting() {
+ updateSetting(Settings.System.RING_VIBRATION_INTENSITY, Vibrator.VIBRATION_INTENSITY_HIGH);
+
+ mPreference.setChecked(true);
+ verify(mAudioManager).setRampingRingerEnabled(true);
+
+ mPreference.setChecked(false);
+ verify(mAudioManager).setRampingRingerEnabled(false);
+ }
+
+ private void updateSetting(String key, int value) {
+ Settings.System.putInt(mContext.getContentResolver(), key, value);
+ }
+
+ private void showPreference() {
+ mController.displayPreference(mScreen);
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
index f75b7f0..c0cdb01 100644
--- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
@@ -310,8 +310,7 @@
ReflectionHelpers.setField(mFragment, "mContext", context);
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
ReflectionHelpers.setField(mFragment, "mTemplate",
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */));
+ new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build());
final long end = System.currentTimeMillis();
final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
@@ -336,8 +335,7 @@
ReflectionHelpers.setField(mFragment, "mContext", context);
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
ReflectionHelpers.setField(mFragment, "mTemplate",
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */));
+ new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build());
final long end = System.currentTimeMillis();
final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
@@ -368,8 +366,7 @@
ReflectionHelpers.setField(mFragment, "mCycles", testCycles);
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
ReflectionHelpers.setField(mFragment, "mTemplate",
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */));
+ new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build());
final NetworkCycleDataForUidLoader loader = (NetworkCycleDataForUidLoader)
mFragment.mUidDataCallbacks.onCreateLoader(0 /* id */, Bundle.EMPTY /* args */);
diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsagePreferenceTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsagePreferenceTest.java
index ff8ef93..02f683a 100644
--- a/tests/robotests/src/com/android/settings/datausage/DataUsagePreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/DataUsagePreferenceTest.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.Intent;
+import android.net.NetworkStats;
import android.net.NetworkTemplate;
import com.android.settingslib.net.DataUsageController;
@@ -58,8 +59,9 @@
public void setTemplate_noDataUsage_shouldDisablePreference() {
doReturn(0L).when(mController).getHistoricalUsageLevel(any(NetworkTemplate.class));
- mPreference.setTemplate(
- NetworkTemplate.buildTemplateMobileWildcard(), 5 /* subId */, null /* services */);
+ mPreference.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+ .setMeteredness(NetworkStats.METERED_YES).build(),
+ 5 /* subId */, null /* services */);
verify(mPreference).setEnabled(false);
verify(mPreference).setIntent(null);
@@ -69,8 +71,9 @@
public void setTemplate_hasDataUsage_shouldNotDisablePreference() {
doReturn(200L).when(mController).getHistoricalUsageLevel(any(NetworkTemplate.class));
- mPreference.setTemplate(
- NetworkTemplate.buildTemplateMobileWildcard(), 5 /* subId */, null /* services */);
+ mPreference.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+ .setMeteredness(NetworkStats.METERED_YES).build(),
+ 5 /* subId */, null /* services */);
verify(mPreference, never()).setEnabled(false);
verify(mPreference).setIntent(any(Intent.class));
diff --git a/tests/robotests/src/com/android/settings/display/AppGridViewTest.java b/tests/robotests/src/com/android/settings/display/AppGridViewTest.java
index e7daac8..22e1cc3 100644
--- a/tests/robotests/src/com/android/settings/display/AppGridViewTest.java
+++ b/tests/robotests/src/com/android/settings/display/AppGridViewTest.java
@@ -18,26 +18,39 @@
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;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
import android.util.IconDrawableFactory;
+import com.android.settings.R;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link AppGridView}.
+ */
@RunWith(RobolectricTestRunner.class)
public class AppGridViewTest {
@@ -87,4 +100,72 @@
assertThat(entry1.compareTo(entry2)).isEqualTo(0);
assertThat(entry1.compareTo(entry3)).isNotEqualTo(0);
}
+
+ @Test
+ public void noAppCountAttribute_matchListSize() {
+ final int appCountFromSystem = 8;
+ setUpResolveInfos(appCountFromSystem);
+
+ final AppGridView appGridView = new AppGridView(mContext, /* attrs= */ null);
+
+ assertThat(appGridView.getAdapter().getCount()).isEqualTo(/* expected= */ 6);
+ }
+
+ @Test
+ public void setAppCountAttribute_matchListSize() {
+ final int appCountFromSystem = 8;
+ final int appCountFromAttr = 7;
+ setUpResolveInfos(appCountFromSystem);
+
+ final AppGridView appGridView =
+ new AppGridView(mContext, createAttributeSet(appCountFromAttr));
+
+ assertThat(appGridView.getAdapter().getCount()).isEqualTo(appCountFromAttr);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void setAppCountAttribute_belowLowerBound_matchListSize() {
+ final int appCountFromSystem = 9;
+ final int appCountFromAttr = -1; // The num is just for the test.
+ setUpResolveInfos(appCountFromSystem);
+
+ new AppGridView(mContext, createAttributeSet(appCountFromAttr));
+ }
+
+ @Test
+ public void setAppCountAttribute_aboveUpperBound_matchListSize() {
+ final int appCountFromSystem = 10;
+ final int appCountFromAttr = 15;
+ setUpResolveInfos(appCountFromSystem);
+
+ final AppGridView appGridView =
+ new AppGridView(mContext, createAttributeSet(appCountFromAttr));
+
+ assertThat(appGridView.getAdapter().getCount()).isEqualTo(appCountFromSystem);
+ }
+
+ private AttributeSet createAttributeSet(int appCount) {
+ return Robolectric.buildAttributeSet()
+ .addAttribute(R.attr.appCount, String.valueOf(appCount))
+ .build();
+ }
+
+ private void setUpResolveInfos(int appCount) {
+ when(mContext.getPackageManager().queryIntentActivities(
+ any(Intent.class), anyInt()))
+ .thenReturn(createFakeResolveInfos(appCount));
+ }
+
+ private List<ResolveInfo> createFakeResolveInfos(int count) {
+ final List<ResolveInfo> list = new ArrayList<>();
+
+ for (int i = 0; i < count; i++) {
+ final ResolveInfo info = new ResolveInfo();
+ info.nonLocalizedLabel = String.valueOf(i);
+
+ list.add(info);
+ }
+
+ return list;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java b/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java
index 71fab42..64cde5a 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationBackendTest.java
@@ -114,6 +114,30 @@
}
@Test
+ public void testMarkAppRow_fixedPermission_withRole() throws Exception {
+ Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(),
+ Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM);
+
+ PackageInfo pi = new PackageInfo();
+ pi.packageName = "test";
+ pi.applicationInfo = new ApplicationInfo();
+ pi.applicationInfo.packageName = "test";
+ pi.applicationInfo.uid = 123;
+
+ List<String> roles = new ArrayList<>();
+ roles.add(RoleManager.ROLE_DIALER);
+ RoleManager rm = mock(RoleManager.class);
+ when(rm.getHeldRolesFromController(anyString())).thenReturn(roles);
+ when(mInm.isPermissionFixed(pi.packageName, 0)).thenReturn(false);
+
+ AppRow appRow = new NotificationBackend().loadAppRow(RuntimeEnvironment.application,
+ mock(PackageManager.class), rm, pi);
+
+ assertTrue(appRow.systemApp);
+ assertTrue(appRow.lockedImportance);
+ }
+
+ @Test
public void testMarkAppRow_fixedPermission() throws Exception {
Secure.putIntForUser(RuntimeEnvironment.application.getContentResolver(),
Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 1, USER_SYSTEM);
diff --git a/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java
index 9f0e115..970564a 100644
--- a/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/EncryptionStatusPreferenceControllerTest.java
@@ -94,23 +94,23 @@
assertThat(mPreference.getFragment()).isNull();
assertThat(mPreference.getSummary())
- .isEqualTo(mContext.getText(R.string.crypt_keeper_encrypted_summary));
+ .isEqualTo(mContext.getText(R.string.encrypted_summary));
}
@Test
- public void updateSummary_unencrypted_shouldHasEncryptionFragment() {
+ public void updateSummary_unencrypted_shouldSayUnencrypted() {
ShadowLockPatternUtils.setDeviceEncryptionEnabled(false);
mController.updateState(mPreference);
- final CharSequence summary = mContext.getText(R.string.decryption_settings_summary);
+ final CharSequence summary = mContext.getText(R.string.not_encrypted_summary);
assertThat(mPreference.getSummary()).isEqualTo(summary);
assertThat(mController.getPreferenceKey()).isNotEqualTo(PREF_KEY_ENCRYPTION_SECURITY_PAGE);
- assertThat(mPreference.getFragment()).isEqualTo(CryptKeeperSettings.class.getName());
+ assertThat(mPreference.getFragment()).isNull();
}
@Test
- public void updateSummary_unencrypted_securityPage_shouldNotHaveEncryptionFragment() {
+ public void updateSummary_unencrypted_securityPage_shouldSayUnencrypted() {
mController =
new EncryptionStatusPreferenceController(mContext,
PREF_KEY_ENCRYPTION_SECURITY_PAGE);
@@ -118,9 +118,8 @@
mController.updateState(mPreference);
- final CharSequence summary = mContext.getText(R.string.decryption_settings_summary);
+ final CharSequence summary = mContext.getText(R.string.not_encrypted_summary);
assertThat(mPreference.getSummary()).isEqualTo(summary);
-
- assertThat(mPreference.getFragment()).isNotEqualTo(CryptKeeperSettings.class.getName());
+ assertThat(mPreference.getFragment()).isNull();
}
}
diff --git a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceControllerTest.java
deleted file mode 100644
index 1f4ba96..0000000
--- a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceControllerTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2020 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.sound;
-
-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 static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.telephony.TelephonyManager;
-
-import com.android.settings.R;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowDeviceConfig.class})
-public class VibrateForCallsPreferenceControllerTest {
-
- private static final int OFF = 0;
- private static final int ON = 1;
- private Context mContext;
- private ContentResolver mContentResolver;
- @Mock
- private TelephonyManager mTelephonyManager;
- private VibrateForCallsPreferenceController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
- mContentResolver = mContext.getContentResolver();
- when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
- mController = new VibrateForCallsPreferenceController(
- mContext, VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED);
- }
-
- @Test
- public void getAvailabilityStatus_notVoiceCapable_returnUnsupportedOnDevice() {
- when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
- VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "false", false);
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
- }
-
- @Test
- public void getAvailabilityStatus_rampingRingerEnabled_returnUnsupportedOnDevice() {
- when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
- VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "true", false);
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
- }
-
- @Test
- public void getAvailabilityStatus_voiceCapableAndRampingRingerDisabled_returnAvailable() {
- when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
- VibrateForCallsPreferenceController.RAMPING_RINGER_ENABLED, "false", false);
-
- assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
- }
-
- @Test
- public void getSummary_applyRampingRinger_rampingRingerSummary() {
- Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
- Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, ON);
-
- assertThat(mController.getSummary()).isEqualTo(
- mContext.getText(R.string.vibrate_when_ringing_option_ramping_ringer));
- }
-
- @Test
- public void getSummary_enableVibrateWhenRinging_alwaysVibrateSummary() {
- Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, ON);
- Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
- assertThat(mController.getSummary()).isEqualTo(
- mContext.getText(R.string.vibrate_when_ringing_option_always_vibrate));
- }
-
- @Test
- public void getSummary_notApplyRampingRingerDisableVibrateWhenRinging_neverVibrateSummary() {
- Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
- Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
- assertThat(mController.getSummary()).isEqualTo(
- mContext.getText(R.string.vibrate_when_ringing_option_never_vibrate));
- }
-}
diff --git a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceFragmentTest.java
deleted file mode 100644
index 889e5a6..0000000
--- a/tests/robotests/src/com/android/settings/sound/VibrateForCallsPreferenceFragmentTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2020 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.sound;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class VibrateForCallsPreferenceFragmentTest {
-
- private static final int OFF = 0;
- private static final int ON = 1;
- private Context mContext;
- private ContentResolver mContentResolver;
- private VibrateForCallsPreferenceFragment mFragment;
-
- @Before
- public void setUp() {
- mContext = spy(RuntimeEnvironment.application);
- mContentResolver = mContext.getContentResolver();
- mFragment = spy(new VibrateForCallsPreferenceFragment());
- doReturn(mContext).when(mFragment).getContext();
- mFragment.onAttach(mContext);
- }
-
- @Test
- public void getDefaultKey_applyRampingRinger_keyRampingRinger() {
- Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
- Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, ON);
-
- assertThat(mFragment.getDefaultKey()).isEqualTo(
- VibrateForCallsPreferenceFragment.KEY_RAMPING_RINGER);
- }
-
- @Test
- public void getDefaultKey_enableVibrateWhenRinging_keyAlwaysVibrate() {
- Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, ON);
- Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
- assertThat(mFragment.getDefaultKey()).isEqualTo(
- VibrateForCallsPreferenceFragment.KEY_ALWAYS_VIBRATE);
- }
-
- @Test
- public void getDefaultKey_notApplyRampingRingerDisableVibrateWhenRinging_keyNeverVibrate() {
- Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF);
- Settings.System.putInt(mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF);
-
- assertThat(mFragment.getDefaultKey()).isEqualTo(
- VibrateForCallsPreferenceFragment.KEY_NEVER_VIBRATE);
- }
-
- @Test
- public void setDefaultKey_keyRampingRinger_applyRampingRingerDisableVibrateWhenRinging() {
- mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_RAMPING_RINGER);
-
- assertThat(Settings.System.getInt(
- mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(ON);
- assertThat(Settings.System.getInt(
- mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(OFF);
- }
-
- @Test
- public void setDefaultKey_keyAlwaysVibrate_notApplyRampingRingerEnableVibrateWhenRinging() {
- mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_ALWAYS_VIBRATE);
-
- assertThat(Settings.System.getInt(
- mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(OFF);
- assertThat(Settings.System.getInt(
- mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(ON);
- }
-
- @Test
- public void setDefaultKey_keyNeverVibrate_notApplyRampingRingerDisableVibrateWhenRinging() {
- mFragment.setDefaultKey(VibrateForCallsPreferenceFragment.KEY_NEVER_VIBRATE);
-
- assertThat(Settings.System.getInt(
- mContentResolver, Settings.System.APPLY_RAMPING_RINGER, OFF)).isEqualTo(OFF);
- assertThat(Settings.System.getInt(
- mContentResolver, Settings.System.VIBRATE_WHEN_RINGING, OFF)).isEqualTo(OFF);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
index 1d4f201..dc42515 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java
@@ -49,6 +49,7 @@
private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
private final Set<Integer> mManagedProfiles = new HashSet<>();
+ private final Set<String> mEnabledTypes = new HashSet<>();
private boolean mIsQuietModeEnabled = false;
private int[] profileIdsForUser = new int[0];
private boolean mUserSwitchEnabled;
@@ -105,6 +106,11 @@
mGuestRestrictions.add(restriction);
}
+ @Implementation
+ protected boolean hasUserRestriction(String restrictionKey) {
+ return hasUserRestriction(restrictionKey, UserHandle.of(UserHandle.myUserId()));
+ }
+
public static ShadowUserManager getShadow() {
return (ShadowUserManager) Shadow.extract(
RuntimeEnvironment.application.getSystemService(UserManager.class));
@@ -199,4 +205,17 @@
public void setSwitchabilityStatus(@UserManager.UserSwitchabilityResult int newStatus) {
mSwitchabilityStatus = newStatus;
}
+
+ @Implementation
+ protected boolean isUserTypeEnabled(String userType) {
+ return mEnabledTypes.contains(userType);
+ }
+
+ public void setUserTypeEnabled(String type, boolean enabled) {
+ if (enabled) {
+ mEnabledTypes.add(type);
+ } else {
+ mEnabledTypes.remove(type);
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
index 382ac5d..628c14e 100644
--- a/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserCapabilitiesTest.java
@@ -18,12 +18,17 @@
import static com.google.common.truth.Truth.assertThat;
+import android.content.ComponentName;
import android.content.Context;
import android.os.UserHandle;
import android.os.UserManager;
+import com.android.settings.R;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowUserManager;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,16 +37,24 @@
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowUserManager.class})
+@Config(shadows = {ShadowUserManager.class, ShadowDevicePolicyManager.class,
+ SettingsShadowResources.class})
public class UserCapabilitiesTest {
private Context mContext;
private ShadowUserManager mUserManager;
+ private ShadowDevicePolicyManager mDpm;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mUserManager = ShadowUserManager.getShadow();
+ mDpm = ShadowDevicePolicyManager.getShadow();
+ }
+
+ @After
+ public void tearDown() {
+ SettingsShadowResources.reset();
}
@Test
@@ -85,4 +98,40 @@
assertThat(userCapabilities.mUserSwitcherEnabled).isTrue();
}
+
+ @Test
+ public void restrictedProfile_enabled() {
+ mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, true);
+ mDpm.setDeviceOwner(null);
+ SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, true);
+ final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+ assertThat(userCapabilities.mCanAddRestrictedProfile).isTrue();
+ }
+
+ @Test
+ public void restrictedProfile_configNotSet() {
+ mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, true);
+ mDpm.setDeviceOwner(null);
+ SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, false);
+ final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+ assertThat(userCapabilities.mCanAddRestrictedProfile).isFalse();
+ }
+
+ @Test
+ public void restrictedProfile_deviceIsManaged() {
+ mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, true);
+ mDpm.setDeviceOwner(new ComponentName("test", "test"));
+ SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, true);
+ final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+ assertThat(userCapabilities.mCanAddRestrictedProfile).isFalse();
+ }
+
+ @Test
+ public void restrictedProfile_typeNotEnabled() {
+ mUserManager.setUserTypeEnabled(UserManager.USER_TYPE_FULL_RESTRICTED, false);
+ mDpm.setDeviceOwner(null);
+ SettingsShadowResources.overrideResource(R.bool.config_offer_restricted_profiles, true);
+ final UserCapabilities userCapabilities = UserCapabilities.create(mContext);
+ assertThat(userCapabilities.mCanAddRestrictedProfile).isFalse();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/AddWifiNetworkPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/AddWifiNetworkPreferenceTest.java
new file mode 100644
index 0000000..04ecdab
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/AddWifiNetworkPreferenceTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.wifi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AddWifiNetworkPreferenceTest {
+
+ private Context mContext;
+ private AddWifiNetworkPreference mPreference;
+
+ @Mock
+ private UserManager mUserManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager);
+ mPreference = new AddWifiNetworkPreference(mContext);
+
+ }
+
+ @Test
+ public void updatePreferenceForRestriction_isAddWifiConfigAllowed_prefIsEnabled() {
+ mPreference.mIsAddWifiConfigAllow = true;
+
+ mPreference.updatePreferenceForRestriction();
+
+ assertThat(mPreference.isEnabled()).isTrue();
+ assertThat(mPreference.getSummary()).isNull();
+ }
+
+ @Test
+ public void updatePreferenceForRestriction_isAddWifiConfigNotAllowed_prefIsDisabled() {
+ mPreference.mIsAddWifiConfigAllow = false;
+
+ mPreference.updatePreferenceForRestriction();
+
+ assertThat(mPreference.isEnabled()).isFalse();
+ assertThat(mPreference.getSummary())
+ .isEqualTo(mContext.getString(R.string.not_allowed_by_ent));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
index ff0d7b2..5d568fe 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
@@ -19,8 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -36,7 +35,6 @@
import android.net.wifi.WifiEnterpriseConfig.Eap;
import android.net.wifi.WifiEnterpriseConfig.Phase2;
import android.net.wifi.WifiManager;
-import android.os.UserHandle;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -86,6 +84,8 @@
private WifiEntry mWifiEntry;
@Mock
private AndroidKeystoreAliasLoader mAndroidKeystoreAliasLoader;
+ @Mock
+ private WifiManager mWifiManager;
private View mView;
private Spinner mHiddenSettingsSpinner;
private Spinner mEapCaCertSpinner;
@@ -127,6 +127,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
+ when(mContext.getSystemService(eq(WifiManager.class))).thenReturn(mWifiManager);
when(mConfigUiBase.getContext()).thenReturn(mContext);
when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_PSK);
mView = LayoutInflater.from(mContext).inflate(R.layout.wifi_dialog, null);
@@ -420,7 +421,7 @@
private TestWifiConfigController2(
WifiConfigUiBase2 parent, View view, WifiEntry wifiEntry, int mode) {
- super(parent, view, wifiEntry, mode);
+ super(parent, view, wifiEntry, mode, mWifiManager);
}
private TestWifiConfigController2(
diff --git a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
index 39408e2..6cd20fc 100644
--- a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
@@ -47,6 +47,7 @@
mActivity = Robolectric.buildActivity(AddAppNetworksActivity.class).create().get();
mActivity.mActivityManager = mIActivityManager;
+ mActivity.mIsAddWifiConfigAllow = true;
}
@Test
@@ -77,6 +78,13 @@
assertThat(mActivity.showAddNetworksFragment()).isTrue();
}
+ @Test
+ public void showAddNetworksFragment_isAddWifiConfigNotAllow_returnFalse() {
+ mActivity.mIsAddWifiConfigAllow = false;
+
+ assertThat(mActivity.showAddNetworksFragment()).isFalse();
+ }
+
private void fakeCallingPackage(@Nullable String packageName) {
try {
when(mIActivityManager.getLaunchedFromPackage(any())).thenReturn(packageName);
diff --git a/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java b/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
index d770aba..b80e9d2 100644
--- a/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
+++ b/tests/unit/src/com/android/settings/datausage/DataUsageInfoControllerTest.java
@@ -101,8 +101,7 @@
}
private NetworkPolicy getDefaultNetworkPolicy() {
- NetworkTemplate template = NetworkTemplate.buildTemplateWifi(
- NetworkTemplate.WIFI_NETWORKID_ALL, null /* subscriberId */);
+ NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build();
int cycleDay = -1;
String cycleTimezone = "UTC";
long warningBytes = -1;
diff --git a/tests/unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java b/tests/unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java
index 7d814b5..b27591e 100644
--- a/tests/unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java
+++ b/tests/unit/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java
@@ -531,13 +531,11 @@
final Bundle expect = new Bundle(1);
expect.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE,
- NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL,
- null /* subscriberId */));
+ new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build());
final Bundle actual = startedIntent
.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
assertThat((NetworkTemplate) actual.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE))
- .isEqualTo(NetworkTemplate.buildTemplateWifi(
- NetworkTemplate.WIFI_NETWORKID_ALL, null /* subscriberId */));
+ .isEqualTo(new NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build());
assertThat(startedIntent.getIntExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID, 0))
.isEqualTo(ResourcesUtils.getResourcesId(mContext, "string", "wifi_data_usage"));
diff --git a/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java b/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java
index 6e30bbb..e18b258 100644
--- a/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java
+++ b/tests/unit/src/com/android/settings/security/SecurityAdvancedSettingsTest.java
@@ -18,13 +18,18 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.os.Looper;
+import android.provider.DeviceConfig;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.settings.safetycenter.SafetyCenterStatus;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.ResourcesUtils;
import com.android.settingslib.drawer.CategoryKey;
@@ -35,6 +40,9 @@
@RunWith(AndroidJUnit4.class)
public class SecurityAdvancedSettingsTest {
private static final String SCREEN_XML_RESOURCE_NAME = "security_advanced_settings";
+ private static final String ALTERNATIVE_CATEGORY_KEY = "alternative_category_key";
+ private static final String LEGACY_CATEGORY_KEY =
+ "com.android.settings.category.ia.legacy_advanced_security";
private Context mContext;
private SecurityAdvancedSettings mSecurityAdvancedSettings;
@@ -58,12 +66,51 @@
}
@Test
- public void getCategoryKey_whenCalled_returnsSecurity() {
+ public void getCategoryKey_whenSafetyCenterIsEnabled_returnsSecurity() {
+ setSafetyCenterEnabled(true);
+
assertThat(mSecurityAdvancedSettings.getCategoryKey())
.isEqualTo(CategoryKey.CATEGORY_SECURITY_ADVANCED_SETTINGS);
}
+ @Test
+ public void getCategoryKey_whenAlternativeFragmentPresented_returnsAlternative() {
+ setSafetyCenterEnabled(false);
+ setupAlternativeFragment(true, ALTERNATIVE_CATEGORY_KEY);
+
+ assertThat(mSecurityAdvancedSettings.getCategoryKey())
+ .isEqualTo(ALTERNATIVE_CATEGORY_KEY);
+ }
+
+ @Test
+ public void getCategoryKey_whenNoAlternativeFragmentPresented_returnsLegacy() {
+ setSafetyCenterEnabled(false);
+ setupAlternativeFragment(false, null);
+
+ assertThat(mSecurityAdvancedSettings.getCategoryKey())
+ .isEqualTo(LEGACY_CATEGORY_KEY);
+ }
+
private int getXmlResId(String resName) {
return ResourcesUtils.getResourcesId(mContext, "xml", resName);
}
+
+ private void setSafetyCenterEnabled(boolean isEnabled) {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_PRIVACY,
+ SafetyCenterStatus.SAFETY_CENTER_IS_ENABLED,
+ /* value = */ Boolean.toString(isEnabled),
+ /* makeDefault = */ false);
+ }
+
+ private void setupAlternativeFragment(boolean hasAlternativeFragment,
+ String alternativeCategoryKey) {
+ final FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest();
+ when(fakeFeatureFactory.securitySettingsFeatureProvider
+ .hasAlternativeSecuritySettingsFragment())
+ .thenReturn(hasAlternativeFragment);
+ when(fakeFeatureFactory.securitySettingsFeatureProvider
+ .getAlternativeAdvancedSettingsCategoryKey())
+ .thenReturn(alternativeCategoryKey);
+ }
}