Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 164d42e..d927073 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -154,8 +154,7 @@
<!-- Activity for launching deep link page in 2-pane. -->
<activity android:name=".homepage.DeepLinkHomepageActivity"
android:label="@string/settings_label_launcher"
- android:theme="@style/Theme.Settings.Home.DeepLink"
- android:taskAffinity=""
+ android:theme="@style/Theme.Settings.Home"
android:launchMode="singleTask"
android:exported="true"
android:enabled="false"
@@ -169,9 +168,9 @@
android:value="true" />
</activity>
- <activity android:name=".homepage.SliceDeepLinkHomepageActivity"
+ <activity android:name=".homepage.DeepLinkHomepageActivityInternal"
android:label="@string/settings_label_launcher"
- android:theme="@style/Theme.Settings.Home.DeepLink"
+ android:theme="@style/Theme.Settings.Home.NoAnimation"
android:taskAffinity=""
android:launchMode="singleTask"
android:exported="false"
@@ -3144,6 +3143,24 @@
</activity>
<activity
+ android:name="Settings$TurnScreenOnSettingsActivity"
+ android:exported="true"
+ android:label="@string/turn_screen_on_title">
+ <intent-filter android:priority="1">
+ <action android:name="android.settings.TURN_SCREEN_ON_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.applications.specialaccess.turnscreenon.TurnScreenOnSettings" />
+ <meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"
+ android:value="@string/menu_key_apps"/>
+ </activity>
+
+ <activity
android:name="Settings$InteractAcrossProfilesSettingsActivity"
android:exported="true"
android:label="@string/interact_across_profiles_title">
diff --git a/res/drawable/data_bytes_editor_spinner_background.xml b/res/drawable/data_bytes_editor_spinner_background.xml
new file mode 100644
index 0000000..19cfc45
--- /dev/null
+++ b/res/drawable/data_bytes_editor_spinner_background.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<ripple
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="@color/settingslib_ripple_color">
+
+ <item android:id="@android:id/background">
+ <layer-list android:paddingMode="stack"
+ android:paddingStart="0dp"
+ android:paddingEnd="48dp"
+ android:paddingLeft="0dp"
+ android:paddingRight="0dp">
+ <item>
+ <shape>
+ <corners android:radius="28dp"/>
+ <solid android:color="@android:color/system_accent1_100"/>
+ <size android:height="@dimen/settingslib_spinner_height"/>
+ </shape>
+ </item>
+
+ <item
+ android:gravity="center|end"
+ android:width="18dp"
+ android:height="18dp"
+ android:end="12dp"
+ android:drawable="@drawable/settingslib_arrow_drop_down"/>
+ </layer-list>
+ </item>
+</ripple>
diff --git a/res/layout/accessibility_edit_magnification_shortcut.xml b/res/layout/accessibility_edit_magnification_shortcut.xml
deleted file mode 100644
index 2702e70..0000000
--- a/res/layout/accessibility_edit_magnification_shortcut.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- 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
- -->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/container_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scrollbarStyle="outsideOverlay">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:padding="24dp">
-
- <ImageView
- android:id="@+id/image"
- android:layout_width="@dimen/accessibility_imageview_size"
- android:layout_height="@dimen/accessibility_imageview_size"
- android:layout_gravity="center_horizontal"
- android:layout_marginBottom="@dimen/accessibility_textview_layout_margin_bottom"
- android:scaleType="fitCenter"/>
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/accessibility_magnification_switch_shortcut_message"
- android:textAppearance="?android:attr/textAppearanceListItemSecondary"
- android:textColor="?android:attr/textColorSecondary"
- android:layout_marginBottom="@dimen/accessibility_textview_layout_margin_bottom"/>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <Button
- android:id="@+id/custom_positive_button"
- style="@style/AccessibilityDialogButton"
- android:gravity="center|end"
- android:text="@string/accessibility_magnification_switch_shortcut_positive_button"/>
-
- <Button
- android:id="@+id/custom_negative_button"
- style="@style/AccessibilityDialogButton"
- android:gravity="center|end"
- android:text="@string/accessibility_magnification_switch_shortcut_negative_button"/>
-
- </LinearLayout>
- </LinearLayout>
-</ScrollView>
\ No newline at end of file
diff --git a/res/layout/accessibility_text_reading_preview_mail_content.xml b/res/layout/accessibility_text_reading_preview_mail_content.xml
index a8d4e52..941535f 100644
--- a/res/layout/accessibility_text_reading_preview_mail_content.xml
+++ b/res/layout/accessibility_text_reading_preview_mail_content.xml
@@ -26,7 +26,8 @@
android:layout_height="wrap_content"
android:text="@string/accessibility_text_reading_preview_mail_subject"
android:textSize="14sp"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:attr/textColorPrimary"/>
<TextView
android:id="@+id/from"
@@ -44,5 +45,5 @@
android:layout_height="wrap_content"
android:textSize="13sp"
android:text="@string/accessibility_text_reading_preview_mail_content"
- android:textAppearance="?android:attr/textAppearanceMedium" />
+ android:textColor="?android:attr/textColorPrimary"/>
</LinearLayout>
diff --git a/res/layout/data_usage_bytes_editor.xml b/res/layout/data_usage_bytes_editor.xml
index a72352d..23778d9 100644
--- a/res/layout/data_usage_bytes_editor.xml
+++ b/res/layout/data_usage_bytes_editor.xml
@@ -39,6 +39,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
- android:entries="@array/bytes_picker_sizes" />
+ android:entries="@array/bytes_picker_sizes"
+ style="@style/DataByteEditorSpinner"/>
</LinearLayout>
diff --git a/res/layout/magnification_triple_tap_warning_dialog.xml b/res/layout/magnification_triple_tap_warning_dialog.xml
new file mode 100644
index 0000000..059ab62
--- /dev/null
+++ b/res/layout/magnification_triple_tap_warning_dialog.xml
@@ -0,0 +1,37 @@
+<?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
+ -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scrollbarStyle="outsideOverlay">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="?android:attr/dialogPreferredPadding"
+ android:paddingStart="?android:attr/dialogPreferredPadding"
+ android:paddingEnd="?android:attr/dialogPreferredPadding">
+
+ <TextView
+ android:id="@+id/message"
+ android:text="@string/accessibility_magnification_triple_tap_warning_message"
+ style="@style/AccessibilityDialogDescription" />
+
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0ae67e5..905f036 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1586,15 +1586,6 @@
<!-- Content of the dialog shown when the user only has one attempt left to provide the work lock password before the work profile is removed. [CHAR LIMIT=NONE] -->
<string name="lock_last_password_attempt_before_wipe_profile">If you enter an incorrect password on the next attempt, your work profile and its data will be deleted</string>
- <!-- Content of the dialog shown when the user has failed to provide the device lock too many times and the device is wiped. [CHAR LIMIT=NONE] -->
- <string name="lock_failed_attempts_now_wiping_device">Too many incorrect attempts. This device\'s data will be deleted.</string>
- <!-- Content of the dialog shown when the user has failed to provide the user lock too many times and the user is removed. [CHAR LIMIT=NONE] -->
- <string name="lock_failed_attempts_now_wiping_user">Too many incorrect attempts. This user will be deleted.</string>
- <!-- Content of the dialog shown when the user has failed to provide the work lock too many times and the work profile is removed. [CHAR LIMIT=NONE] -->
- <string name="lock_failed_attempts_now_wiping_profile">Too many incorrect attempts. This work profile and its data will be deleted.</string>
- <!-- Button label to dismiss the dialog telling the user the work profile has been wiped. [CHAR LIMIT=40] -->
- <string name="lock_failed_attempts_now_wiping_dialog_dismiss">Dismiss</string>
-
<!-- Hint shown in dialog screen when password is too short -->
<plurals name="lockpassword_password_too_short">
<item quantity="one">Must contain at least <xliff:g id="count" example="1">%d</xliff:g> character</item>
@@ -7640,8 +7631,6 @@
<string name="user_list_title">Users & profiles</string>
<!-- User settings add user or restricted profile menu [CHAR LIMIT=35] -->
<string name="user_add_user_or_profile_menu">Add user or profile</string>
- <!-- User settings add user menu [CHAR LIMIT=35] -->
- <string name="user_add_user_menu">Add user</string>
<!-- User settings summary for a restricted profile [CHAR LIMIT=50] -->
<string name="user_summary_restricted_profile">Restricted profile</string>
@@ -7657,8 +7646,7 @@
<string name="user_you">You (<xliff:g id="name" example="Name">%s</xliff:g>)</string>
<!-- Summary for add user action, when it's disabled [CHAR LIMIT=100] -->
- <string name="user_add_max_count">You can add up to <xliff:g id="user_count">%1$d</xliff:g> users</string>
-
+ <string name="user_add_max_count">You can\u2019t add any more users. Remove a user to add a new one.</string>
<!-- Message to secondary users that only owner can manage users [CHAR LIMIT=none] -->
<string name="user_cannot_manage_message" product="tablet">Only the tablet\u2019s owner can manage users.</string>
@@ -7702,12 +7690,6 @@
<!-- Delete button text [CHAR LIMIT=25] -->
<string name="user_delete_button">Delete</string>
<!-- TODO: Remove it once the same entry in SettingsLib is translated. -->
- <!-- Title for Guest user [CHAR LIMIT=35] -->
- <string name="user_guest">Guest</string>
- <!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
- <string name="user_exit_guest_title">Remove guest</string>
- <!-- Title of dialog to user to confirm exiting guest. [CHAR LIMIT=50] -->
- <string name="user_exit_guest_confirm_title">Remove guest?</string>
<!-- Message to user to confirm exiting guest. [CHAR LIMIT=none] -->
<string name="user_exit_guest_confirm_message">All apps and data in this session will be deleted.</string>
<!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
@@ -10467,8 +10449,14 @@
<item quantity="other"><xliff:g id="count" example="10">%d</xliff:g> unused apps</item>
</plurals>
- <!-- Label of a switch preference that controls whether the system will remove the permissions and free up space when the app has not been used for months [CHAR LIMIT=40]-->
- <string name="unused_apps_switch">Remove permissions and free up space</string>
+ <!-- Label for category for unused app settings for an app. [CHAR LIMIT=40]-->
+ <string name="unused_apps_category">Unused app settings</string>
+
+ <!-- Label of a switch preference that controls whether the system will pause app activity when the app has not been used for months [CHAR LIMIT=40]-->
+ <string name="unused_apps_switch">Pause app activity</string>
+
+ <!-- Summary of the switch preference that controls whether the system will pause app activity when the app has not been used for months [CHAR LIMIT=NONE]-->
+ <string name="unused_apps_switch_summary">Remove permissions, delete temporary files, and stop notifications if unused</string>
<!-- Label for showing all apps in list [CHAR LIMIT=30] -->
<string name="filter_all_apps">All apps</string>
@@ -13514,6 +13502,11 @@
<!-- Summary for allowing screen overlays on Settings app. [CHAR LIMIT=NONE]-->
<string name="overlay_settings_summary">Allow apps that can display over other apps to overlay Settings screens</string>
+ <!-- Developer settings: Title for allowing mock modem service for testing. [CHAR LIMIT=50]-->
+ <string name="allow_mock_modem">Allow Mock Modem</string>
+ <!-- Developer settings: Summary for allowing mock modem service. [CHAR LIMIT=NONE]-->
+ <string name="allow_mock_modem_summary">Allow this device to run Mock Modem service for instrumentation testing. Do not enable this during normal usage of the phone</string>
+
<!-- Title for media control settings [CHAR LIMIT=50]-->
<string name="media_controls_title">Media</string>
<!-- Title of toggle to enable or disable the media resumption feature in quick settings [CHAR LIMIT=50]-->
@@ -13701,7 +13694,7 @@
<!-- Title for default print service main switch. [CHAR LIMIT=50] -->
<string name="default_print_service_main_switch_title">Use print service</string>
<!-- Title for multiple users main switch. [CHAR LIMIT=50] -->
- <string name="multiple_users_main_switch_title">Enable multiple users</string>
+ <string name="multiple_users_main_switch_title">Allow multiple users</string>
<!-- Title for wireless debugging main switch. [CHAR LIMIT=50] -->
<string name="wireless_debugging_main_switch_title">Use wireless debugging</string>
<!-- Title for graphics driver main switch. [CHAR LIMIT=50] -->
@@ -14066,13 +14059,13 @@
<!-- The title of the toggle which enables/disables overlays on top of the screen saver [CHAR LIMIT=none] -->
<string name="dream_complications_toggle_title">Show additional information</string>
<!-- The summary of what overlays this toggle controls [CHAR LIMIT=none] -->
- <string name="dream_complications_toggle_summary">Display time, date and weather on the screen saver</string>
+ <string name="dream_complications_toggle_summary">Display time, date, weather, air quality, and Cast details on the screen saver</string>
<!-- The title of the category to show for the screensaver miscellaneous settings [CHAR LIMIT=none] -->
<string name="dream_more_settings_category">More settings</string>
<!-- The title of the screen saver setup page [CHAR LIMIT=none] -->
- <string name="dream_setup_title">Customize your screen saver</string>
+ <string name="dream_setup_title">Choose your screen saver</string>
<!-- The description of the screen saver setup page [CHAR LIMIT=none] -->
- <string name="dream_setup_description">Choose what you’ll see on your screen when your device is not in use.</string>
+ <string name="dream_setup_description">Choose what you’ll see on your screen when your tablet is docked. Your device may use more energy when a screen saver is used.</string>
<!-- Button to customize the screensaver [CHAR LIMIT=20] -->
<string name="customize_button_title">Customize</string>
@@ -14094,7 +14087,7 @@
<string name="placeholder_activity" translatable="false">*This is a temporary placeholder fallback activity.</string>
<!-- The title of the spatial audio [CHAR LIMIT=none] -->
- <string name="bluetooth_details_spatial_audio_title">Spatial audio</string>
+ <string name="bluetooth_details_spatial_audio_title">Spatial Audio</string>
<!-- The summary of the spatial audio [CHAR LIMIT=none] -->
<string name="bluetooth_details_spatial_audio_summary">Audio from compatible media becomes more immersive</string>
<!-- The title of the head tracking [CHAR LIMIT=none] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4d63689..8e91a9e 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -948,4 +948,9 @@
<item name="rippleColor">?android:attr/colorControlHighlight</item>
<item name="contentPadding">@dimen/dream_item_content_padding</item>
</style>
+
+ <style name="DataByteEditorSpinner" parent="@style/Spinner.SettingsLib">
+ <item name="android:background">@drawable/data_bytes_editor_spinner_background</item>
+ <item name="android:dropDownVerticalOffset">36dp</item>
+ </style>
</resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 3328b6c..ff56e7e 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -218,7 +218,7 @@
<item name="android:statusBarColor">?attr/colorPrimaryDark</item>
</style>
- <style name="Theme.Settings.Home.DeepLink">
+ <style name="Theme.Settings.Home.NoAnimation">
<item name="android:windowAnimationStyle">@null</item>
</style>
diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml
index bb5fbae..95fefb6 100644
--- a/res/xml/app_info_settings.xml
+++ b/res/xml/app_info_settings.xml
@@ -148,6 +148,7 @@
<SwitchPreference
android:key="hibernation_switch"
android:title="@string/unused_apps_switch"
+ android:summary="@string/unused_apps_switch_summary"
settings:controller=
"com.android.settings.applications.appinfo.HibernationSwitchPreferenceController" />
</PreferenceCategory>
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 9867419..89e5167 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -250,6 +250,11 @@
android:title="@string/force_high_refresh_rate_toggle"
android:summary="@string/force_high_refresh_rate_desc" />
+ <SwitchPreference
+ android:key="allow_mock_modem"
+ android:title="@string/allow_mock_modem"
+ android:summary="@string/allow_mock_modem_summary" />
+
</PreferenceCategory>
<PreferenceCategory
diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml
index 892c3eb..5b37f6a 100644
--- a/res/xml/special_access.xml
+++ b/res/xml/special_access.xml
@@ -157,6 +157,11 @@
</Preference>
<Preference
+ android:key="turn_screen_on"
+ android:title="@string/turn_screen_on_title"
+ android:fragment="com.android.settings.applications.specialaccess.turnscreenon.TurnScreenOnSettings" />
+
+ <Preference
android:key="special_access_more"
android:title="@string/special_access_more"
settings:controller="com.android.settings.applications.specialaccess.MoreSpecialAccessPreferenceController" />
diff --git a/res/xml/turn_screen_on_permissions_details.xml b/res/xml/turn_screen_on_permissions_details.xml
new file mode 100644
index 0000000..1b013ea
--- /dev/null
+++ b/res/xml/turn_screen_on_permissions_details.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="turn_screen_on_permission_detail_settings"
+ android:title="@string/turn_screen_on_title">
+
+ <com.android.settings.widget.FilterTouchesSwitchPreference
+ android:key="app_ops_settings_switch"
+ android:title="@string/allow_turn_screen_on"/>
+
+ <com.android.settingslib.widget.FooterPreference
+ android:title="@string/allow_turn_screen_on_description"
+ android:selectable="false"/>
+
+</PreferenceScreen>
diff --git a/res/xml/turn_screen_on_settings.xml b/res/xml/turn_screen_on_settings.xml
new file mode 100644
index 0000000..6aefa72
--- /dev/null
+++ b/res/xml/turn_screen_on_settings.xml
@@ -0,0 +1,23 @@
+<?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:settings="http://schemas.android.com/apk/res-auto"
+ android:key="turn_screen_on_screen"
+ android:title="@string/turn_screen_on_title"
+ settings:searchable="false" />
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 5c3e53e..9282d92 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -274,6 +274,7 @@
public static class VrListenersSettingsActivity extends SettingsActivity { /* empty */ }
public static class PremiumSmsAccessActivity extends SettingsActivity { /* empty */ }
public static class PictureInPictureSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class TurnScreenOnSettingsActivity extends SettingsActivity { /* empty */ }
public static class AppPictureInPictureSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenAccessSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenAccessDetailSettingsActivity extends SettingsActivity {}
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index d258cc2..4e2088e 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -65,8 +65,8 @@
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.core.gateway.SettingsGateway;
import com.android.settings.dashboard.DashboardFeatureProvider;
+import com.android.settings.homepage.DeepLinkHomepageActivityInternal;
import com.android.settings.homepage.SettingsHomepageActivity;
-import com.android.settings.homepage.SliceDeepLinkHomepageActivity;
import com.android.settings.homepage.TopLevelSettings;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.wfd.WifiDisplaySettings;
@@ -254,7 +254,7 @@
final Intent intent = getIntent();
if (shouldShowTwoPaneDeepLink(intent) && tryStartTwoPaneDeepLink(intent)) {
- finishAndRemoveTask();
+ finish();
super.onCreate(savedState);
return;
}
@@ -421,7 +421,7 @@
mHighlightMenuKey = highlightMenuKey;
}
trampolineIntent = getTrampolineIntent(intent, mHighlightMenuKey);
- trampolineIntent.setClass(this, SliceDeepLinkHomepageActivity.class);
+ trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal.class);
} else {
trampolineIntent = getTrampolineIntent(intent, mHighlightMenuKey);
}
@@ -440,8 +440,11 @@
return false;
}
- // If the activity is not the task root, it should not start trampoline for deep links.
- if (!isTaskRoot()) {
+ // If the activity is task root, starting trampoline is needed in order to show two-pane UI.
+ // If FLAG_ACTIVITY_NEW_TASK is set, the activity will become the start of a new task on
+ // this history stack, so starting trampoline is needed in order to notify the homepage that
+ // the highlight key is changed.
+ if (!isTaskRoot() && (intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
return false;
}
diff --git a/src/com/android/settings/accessibility/AccessibilityDialogUtils.java b/src/com/android/settings/accessibility/AccessibilityDialogUtils.java
index f06138f..3d0c1db 100644
--- a/src/com/android/settings/accessibility/AccessibilityDialogUtils.java
+++ b/src/com/android/settings/accessibility/AccessibilityDialogUtils.java
@@ -36,7 +36,6 @@
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
-import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -131,7 +130,6 @@
DialogType.EDIT_SHORTCUT_GENERIC_SUW,
DialogType.EDIT_SHORTCUT_MAGNIFICATION,
DialogType.EDIT_SHORTCUT_MAGNIFICATION_SUW,
- DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT,
})
public @interface DialogType {
@@ -139,7 +137,6 @@
int EDIT_SHORTCUT_GENERIC_SUW = 1;
int EDIT_SHORTCUT_MAGNIFICATION = 2;
int EDIT_SHORTCUT_MAGNIFICATION_SUW = 3;
- int EDIT_MAGNIFICATION_SWITCH_SHORTCUT = 4;
}
/**
@@ -160,27 +157,6 @@
}
/**
- * Method to show the magnification edit shortcut dialog in Magnification.
- *
- * @param context A valid context
- * @param positiveBtnListener The positive button listener
- * @return A magnification edit shortcut dialog in Magnification
- */
- public static Dialog createMagnificationSwitchShortcutDialog(Context context,
- CustomButtonsClickListener positiveBtnListener) {
- final View contentView = createSwitchShortcutDialogContentView(context);
- final AlertDialog alertDialog = new AlertDialog.Builder(context)
- .setView(contentView)
- .setTitle(context.getString(
- R.string.accessibility_magnification_switch_shortcut_title))
- .create();
- setCustomButtonsClickListener(alertDialog, contentView,
- positiveBtnListener, /* negativeBtnListener= */ null);
- setScrollIndicators(contentView);
- return alertDialog;
- }
-
- /**
* Updates the software shortcut in edit shortcut dialog.
*
* @param context A valid context
@@ -233,56 +209,6 @@
View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM);
}
-
- interface CustomButtonsClickListener {
- void onClick(@CustomButton int which);
- }
-
- /**
- * Annotation for customized dialog button type.
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({
- CustomButton.POSITIVE,
- CustomButton.NEGATIVE,
- })
-
- public @interface CustomButton {
- int POSITIVE = 1;
- int NEGATIVE = 2;
- }
-
- private static void setCustomButtonsClickListener(Dialog dialog, View contentView,
- CustomButtonsClickListener positiveBtnListener,
- CustomButtonsClickListener negativeBtnListener) {
- final Button positiveButton = contentView.findViewById(
- R.id.custom_positive_button);
- final Button negativeButton = contentView.findViewById(
- R.id.custom_negative_button);
-
- if (positiveButton != null) {
- positiveButton.setOnClickListener(v -> {
- if (positiveBtnListener != null) {
- positiveBtnListener.onClick(CustomButton.POSITIVE);
- }
- dialog.dismiss();
- });
- }
-
- if (negativeButton != null) {
- negativeButton.setOnClickListener(v -> {
- if (negativeBtnListener != null) {
- negativeBtnListener.onClick(CustomButton.NEGATIVE);
- }
- dialog.dismiss();
- });
- }
- }
-
- private static View createSwitchShortcutDialogContentView(Context context) {
- return createEditDialogContentView(context, DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT);
- }
-
/**
* Get a content View for the edit shortcut dialog.
*
@@ -325,12 +251,6 @@
initMagnifyShortcut(context, contentView);
initAdvancedWidget(contentView);
break;
- case DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT:
- contentView = inflater.inflate(
- R.layout.accessibility_edit_magnification_shortcut, null);
- final ImageView image = contentView.findViewById(R.id.image);
- image.setImageResource(retrieveSoftwareShortcutImageResId(context));
- break;
default:
throw new IllegalArgumentException();
}
@@ -548,18 +468,24 @@
* @param context A valid context
* @param dialogTitle The title of the dialog
* @param customView The customized view
- * @param listener This listener will be invoked when the positive button in the dialog is
- * clicked
+ * @param positiveButtonText The text of the positive button
+ * @param positiveListener This listener will be invoked when the positive button in the dialog
+ * is clicked
+ * @param negativeButtonText The text of the negative button
+ * @param negativeListener This listener will be invoked when the negative button in the dialog
+ * is clicked
* @return the {@link Dialog} with the given view
*/
public static Dialog createCustomDialog(Context context, CharSequence dialogTitle,
- View customView, DialogInterface.OnClickListener listener) {
+ View customView, CharSequence positiveButtonText,
+ DialogInterface.OnClickListener positiveListener, CharSequence negativeButtonText,
+ DialogInterface.OnClickListener negativeListener) {
final AlertDialog alertDialog = new AlertDialog.Builder(context)
.setView(customView)
.setTitle(dialogTitle)
.setCancelable(true)
- .setPositiveButton(R.string.save, listener)
- .setNegativeButton(R.string.cancel, null)
+ .setPositiveButton(positiveButtonText, positiveListener)
+ .setNegativeButton(negativeButtonText, negativeListener)
.create();
if (customView instanceof ScrollView || customView instanceof AbsListView) {
setScrollIndicators(customView);
diff --git a/src/com/android/settings/accessibility/MagnificationModePreferenceController.java b/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
index 7110656..91eb2e9 100644
--- a/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
+++ b/src/com/android/settings/accessibility/MagnificationModePreferenceController.java
@@ -16,8 +16,6 @@
package com.android.settings.accessibility;
-import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
-import static com.android.settings.accessibility.AccessibilityDialogUtils.CustomButton;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
@@ -27,12 +25,13 @@
import android.content.DialogInterface;
import android.os.Bundle;
import android.provider.Settings;
-import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
+import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
@@ -45,6 +44,7 @@
import com.android.settings.R;
import com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.utils.AnnotationSpan;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnCreate;
import com.android.settingslib.core.lifecycle.events.OnResume;
@@ -52,7 +52,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.StringJoiner;
/** Controller that shows the magnification area mode summary and the preference click behavior. */
public class MagnificationModePreferenceController extends BasePreferenceController implements
@@ -63,17 +62,18 @@
@VisibleForTesting
static final int DIALOG_MAGNIFICATION_MODE = DIALOG_ID_BASE + 1;
@VisibleForTesting
- static final int DIALOG_MAGNIFICATION_SWITCH_SHORTCUT = DIALOG_ID_BASE + 2;
+ static final int DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING = DIALOG_ID_BASE + 2;
@VisibleForTesting
static final String EXTRA_MODE = "mode";
private static final String TAG = "MagnificationModePreferenceController";
- private static final char COMPONENT_NAME_SEPARATOR = ':';
private DialogHelper mDialogHelper;
// The magnification mode in the dialog.
- private int mMode = MagnificationMode.NONE;
+ @MagnificationMode
+ private int mModeCache = MagnificationMode.NONE;
private Preference mModePreference;
+ private ShortcutPreference mLinkPreference;
@VisibleForTesting
ListView mMagnificationModesListView;
@@ -113,7 +113,7 @@
@Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
- mMode = savedInstanceState.getInt(EXTRA_MODE, MagnificationMode.NONE);
+ mModeCache = savedInstanceState.getInt(EXTRA_MODE, MagnificationMode.NONE);
}
}
@@ -121,8 +121,10 @@
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mModePreference = screen.findPreference(getPreferenceKey());
+ mLinkPreference = screen.findPreference(
+ ToggleFeaturePreferenceFragment.KEY_SHORTCUT_PREFERENCE);
mModePreference.setOnPreferenceClickListener(preference -> {
- mMode = MagnificationCapabilities.getCapabilities(mContext);
+ mModeCache = MagnificationCapabilities.getCapabilities(mContext);
mDialogHelper.showDialog(DIALOG_MAGNIFICATION_MODE);
return true;
});
@@ -130,7 +132,7 @@
@Override
public void onSaveInstanceState(Bundle outState) {
- outState.putInt(EXTRA_MODE, mMode);
+ outState.putInt(EXTRA_MODE, mModeCache);
}
/**
@@ -147,8 +149,8 @@
case DIALOG_MAGNIFICATION_MODE:
return createMagnificationModeDialog();
- case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
- return createMagnificationShortCutConfirmDialog();
+ case DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING:
+ return createMagnificationTripleTapWarningDialog();
}
return null;
}
@@ -158,8 +160,8 @@
switch (dialogId) {
case DIALOG_MAGNIFICATION_MODE:
return SettingsEnums.DIALOG_MAGNIFICATION_CAPABILITY;
- case DIALOG_MAGNIFICATION_SWITCH_SHORTCUT:
- return SettingsEnums.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT;
+ case DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING:
+ return SettingsEnums.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING;
default:
return 0;
}
@@ -178,29 +180,40 @@
mMagnificationModesListView.setItemChecked(computeSelectionIndex(), true);
final CharSequence title = mContext.getString(
R.string.accessibility_magnification_mode_dialog_title);
+ final CharSequence positiveBtnText = mContext.getString(R.string.save);
+ final CharSequence negativeBtnText = mContext.getString(R.string.cancel);
return AccessibilityDialogUtils.createCustomDialog(mContext, title,
- mMagnificationModesListView, this::onMagnificationModeDialogPositiveButtonClicked);
+ mMagnificationModesListView,
+ positiveBtnText, this::onMagnificationModeDialogPositiveButtonClicked,
+ negativeBtnText, /* negativeListener= */ null);
}
- private void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface,
+ @VisibleForTesting
+ void onMagnificationModeDialogPositiveButtonClicked(DialogInterface dialogInterface,
int which) {
final int selectedIndex = mMagnificationModesListView.getCheckedItemPosition();
- if (selectedIndex != AdapterView.INVALID_POSITION) {
- final MagnificationModeInfo modeInfo =
- (MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
- selectedIndex);
- setMode(modeInfo.mMagnificationMode);
- } else {
+ if (selectedIndex == AdapterView.INVALID_POSITION) {
Log.w(TAG, "invalid index");
+ return;
+ }
+
+ mModeCache = ((MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
+ selectedIndex)).mMagnificationMode;
+
+ // Do not save mode until user clicks positive button in triple tap warning dialog.
+ if (isTripleTapEnabled(mContext) && mModeCache != MagnificationMode.FULLSCREEN) {
+ mDialogHelper.showDialog(DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+ } else { // Save mode (capabilities) value, don't need to show dialog to confirm.
+ updateCapabilitiesAndSummary(mModeCache);
}
}
- private void setMode(int mode) {
- mMode = mode;
- MagnificationCapabilities.setCapabilities(mContext, mMode);
+ private void updateCapabilitiesAndSummary(@MagnificationMode int mode) {
+ mModeCache = mode;
+ MagnificationCapabilities.setCapabilities(mContext, mModeCache);
mModePreference.setSummary(
- MagnificationCapabilities.getSummary(mContext, mMode));
+ MagnificationCapabilities.getSummary(mContext, mModeCache));
}
private void onMagnificationModeSelected(AdapterView<?> parent, View view, int position,
@@ -208,19 +221,16 @@
final MagnificationModeInfo modeInfo =
(MagnificationModeInfo) mMagnificationModesListView.getItemAtPosition(
position);
- if (modeInfo.mMagnificationMode == mMode) {
+ if (modeInfo.mMagnificationMode == mModeCache) {
return;
}
- mMode = modeInfo.mMagnificationMode;
- if (isTripleTapEnabled(mContext) && mMode != MagnificationMode.FULLSCREEN) {
- mDialogHelper.showDialog(DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
- }
+ mModeCache = modeInfo.mMagnificationMode;
}
private int computeSelectionIndex() {
final int modesSize = mModeInfos.size();
for (int i = 0; i < modesSize; i++) {
- if (mModeInfos.get(i).mMagnificationMode == mMode) {
+ if (mModeInfos.get(i).mMagnificationMode == mModeCache) {
return i + mMagnificationModesListView.getHeaderViewsCount();
}
}
@@ -234,41 +244,56 @@
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF) == ON;
}
- private Dialog createMagnificationShortCutConfirmDialog() {
- return AccessibilityDialogUtils.createMagnificationSwitchShortcutDialog(mContext,
- this::onSwitchShortcutDialogButtonClicked);
+ private Dialog createMagnificationTripleTapWarningDialog() {
+ final View contentView = LayoutInflater.from(mContext).inflate(
+ R.layout.magnification_triple_tap_warning_dialog, /* root= */ null);
+ final CharSequence title = mContext.getString(
+ R.string.accessibility_magnification_triple_tap_warning_title);
+ final CharSequence positiveBtnText = mContext.getString(
+ R.string.accessibility_magnification_triple_tap_warning_positive_button);
+ final CharSequence negativeBtnText = mContext.getString(
+ R.string.accessibility_magnification_triple_tap_warning_negative_button);
+
+ final Dialog dialog = AccessibilityDialogUtils.createCustomDialog(mContext, title,
+ contentView,
+ positiveBtnText, this::onMagnificationTripleTapWarningDialogPositiveButtonClicked,
+ negativeBtnText, this::onMagnificationTripleTapWarningDialogNegativeButtonClicked);
+
+ updateLinkInTripleTapWarningDialog(dialog, contentView);
+
+ return dialog;
+ }
+
+ private void updateLinkInTripleTapWarningDialog(Dialog dialog, View contentView) {
+ final TextView messageView = contentView.findViewById(R.id.message);
+ // TODO(b/225682559): Need to remove performClick() after refactoring accessibility dialog.
+ final View.OnClickListener linkListener = view -> {
+ mLinkPreference.performClick();
+ dialog.dismiss();
+ };
+ final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
+ AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, linkListener);
+ final CharSequence textWithLink = AnnotationSpan.linkify(mContext.getText(
+ R.string.accessibility_magnification_triple_tap_warning_message), linkInfo);
+
+ if (messageView != null) {
+ messageView.setText(textWithLink);
+ messageView.setMovementMethod(LinkMovementMethod.getInstance());
+ }
+ dialog.setContentView(contentView);
}
@VisibleForTesting
- void onSwitchShortcutDialogButtonClicked(@CustomButton int which) {
- optOutMagnificationFromTripleTap();
- //TODO(b/147990389): Merge this function into AccessibilityUtils after the format of
- // magnification target is changed to ComponentName.
- optInMagnificationToAccessibilityButton();
+ void onMagnificationTripleTapWarningDialogNegativeButtonClicked(
+ DialogInterface dialogInterface, int which) {
+ mModeCache = MagnificationCapabilities.getCapabilities(mContext);
+ mDialogHelper.showDialog(DIALOG_MAGNIFICATION_MODE);
}
- private void optOutMagnificationFromTripleTap() {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, OFF);
- }
-
- private void optInMagnificationToAccessibilityButton() {
- final String targetKey = Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
- final String targetString = Settings.Secure.getString(mContext.getContentResolver(),
- targetKey);
- if (targetString != null && targetString.contains(MAGNIFICATION_CONTROLLER_NAME)) {
- return;
- }
-
- final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR));
-
- if (!TextUtils.isEmpty(targetString)) {
- joiner.add(targetString);
- }
- joiner.add(MAGNIFICATION_CONTROLLER_NAME);
-
- Settings.Secure.putString(mContext.getContentResolver(), targetKey,
- joiner.toString());
+ @VisibleForTesting
+ void onMagnificationTripleTapWarningDialogPositiveButtonClicked(
+ DialogInterface dialogInterface, int which) {
+ updateCapabilitiesAndSummary(mModeCache);
}
// TODO(b/186731461): Remove it when this controller is used in DashBoardFragment only.
@@ -277,7 +302,6 @@
updateState(mModePreference);
}
-
/**
* An interface to help the delegate to show the dialog. It will be injected to the delegate.
*/
diff --git a/src/com/android/settings/accessibility/ShortcutPreference.java b/src/com/android/settings/accessibility/ShortcutPreference.java
index cff9117..ec911a9 100644
--- a/src/com/android/settings/accessibility/ShortcutPreference.java
+++ b/src/com/android/settings/accessibility/ShortcutPreference.java
@@ -64,6 +64,11 @@
setLayoutResource(R.layout.accessibility_shortcut_secondary_action);
setWidgetLayoutResource(R.layout.preference_widget_primary_switch);
setIconSpaceReserved(false);
+ // Treat onSettingsClicked as this preference's click.
+ setOnPreferenceClickListener(preference -> {
+ callOnSettingsClicked();
+ return true;
+ });
}
@Override
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index fd19376..e123a53 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -102,7 +102,7 @@
protected static final String KEY_USE_SERVICE_PREFERENCE = "use_service";
public static final String KEY_GENERAL_CATEGORY = "general_categories";
protected static final String KEY_HTML_DESCRIPTION_PREFERENCE = "html_description";
- private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
+ public static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
protected static final String KEY_SAVED_USER_SHORTCUT_TYPE = "shortcut_type";
protected static final String KEY_SAVED_QS_TOOLTIP_RESHOW = "qs_tooltip_reshow";
protected static final String KEY_SAVED_QS_TOOLTIP_TYPE = "qs_tooltip_type";
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceController.java b/src/com/android/settings/accessibility/VibrationPreferenceController.java
index 238527c..d1faedd 100644
--- a/src/com/android/settings/accessibility/VibrationPreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationPreferenceController.java
@@ -16,9 +16,13 @@
package com.android.settings.accessibility;
+import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
+
import android.content.Context;
import android.os.Vibrator;
+import android.provider.Settings;
+import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
/** Controller for "Vibration & haptics" settings page. */
@@ -35,4 +39,11 @@
public int getAvailabilityStatus() {
return mHasVibrator ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
+
+ @Override
+ public CharSequence getSummary() {
+ final boolean isVibrateOn = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.VIBRATE_ON, ON) == ON;
+ return mContext.getText(isVibrateOn ? R.string.switch_on_text : R.string.switch_off_text);
+ }
}
diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
index 3ca8168..ad0d4ea 100644
--- a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
+++ b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java
@@ -41,8 +41,8 @@
import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroductionInternal;
import com.android.settings.core.FeatureFlags;
import com.android.settings.homepage.DeepLinkHomepageActivity;
+import com.android.settings.homepage.DeepLinkHomepageActivityInternal;
import com.android.settings.homepage.SettingsHomepageActivity;
-import com.android.settings.homepage.SliceDeepLinkHomepageActivity;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.users.AvatarPickerActivity;
@@ -106,9 +106,7 @@
}
/**
- * Register a new SplitPairRule for Settings home. Because homepage is able to be opened by
- * {@link Settings} or {@link SettingsHomepageActivity} or
- * {@link SliceDeepLinkHomepageActivity}, we register split rule for above cases.
+ * Registers a {@link SplitPairRule} for all classes that Settings homepage can be invoked from.
*/
public static void registerTwoPanePairRuleForSettingsHome(Context context,
ComponentName secondaryComponent,
@@ -151,7 +149,7 @@
registerTwoPanePairRule(
context,
- new ComponentName(context, SliceDeepLinkHomepageActivity.class),
+ new ComponentName(context, DeepLinkHomepageActivityInternal.class),
secondaryComponent,
secondaryIntentAction,
finishPrimaryWithSecondary ? SplitRule.FINISH_ALWAYS : SplitRule.FINISH_NEVER,
@@ -202,8 +200,6 @@
private void registerHomepagePlaceholderRule() {
final Set<ActivityFilter> activityFilters = new HashSet<>();
addActivityFilter(activityFilters, SettingsHomepageActivity.class);
- addActivityFilter(activityFilters, DeepLinkHomepageActivity.class);
- addActivityFilter(activityFilters, SliceDeepLinkHomepageActivity.class);
addActivityFilter(activityFilters, Settings.class);
final Intent intent = new Intent(mContext, Settings.NetworkDashboardActivity.class);
diff --git a/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnDetails.java b/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnDetails.java
new file mode 100644
index 0000000..4540ab9
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnDetails.java
@@ -0,0 +1,118 @@
+/*
+ * 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.applications.specialaccess.turnscreenon;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.OP_TURN_SCREEN_ON;
+
+import android.app.AppOpsManager;
+import android.app.settings.SettingsEnums;
+import android.os.Bundle;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceChangeListener;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.R;
+import com.android.settings.applications.AppInfoWithHeader;
+
+/**
+ * Detail page for turn screen on special app access.
+ */
+public class TurnScreenOnDetails extends AppInfoWithHeader
+ implements OnPreferenceChangeListener {
+
+ private static final String KEY_APP_OPS_SETTINGS_SWITCH = "app_ops_settings_switch";
+
+ private SwitchPreference mSwitchPref;
+ private AppOpsManager mAppOpsManager;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mAppOpsManager = this.getSystemService(AppOpsManager.class);
+
+ // find preferences
+ addPreferencesFromResource(R.xml.turn_screen_on_permissions_details);
+ mSwitchPref = (SwitchPreference) findPreference(KEY_APP_OPS_SETTINGS_SWITCH);
+
+ // set title/summary for all of them
+ mSwitchPref.setTitle(R.string.allow_turn_screen_on);
+
+ // install event listeners
+ mSwitchPref.setOnPreferenceChangeListener(this);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mSwitchPref) {
+ setTurnScreenOnAppOp(mPackageInfo.applicationInfo.uid, mPackageName,
+ (Boolean) newValue);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean refreshUi() {
+ boolean isAllowed = isTurnScreenOnAllowed(mAppOpsManager,
+ mPackageInfo.applicationInfo.uid, mPackageName);
+ mSwitchPref.setChecked(isAllowed);
+ return true;
+ }
+
+ @Override
+ protected AlertDialog createDialog(int id, int errorCode) {
+ return null;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SETTINGS_MANAGE_TURN_SCREEN_ON;
+ }
+
+ /**
+ * Sets whether the app associated with the given {@code packageName} is allowed to turn the
+ * screen on.
+ */
+ void setTurnScreenOnAppOp(int uid, String packageName, boolean value) {
+ final int newMode = value ? MODE_ALLOWED : MODE_ERRORED;
+ mAppOpsManager.setMode(OP_TURN_SCREEN_ON, uid, packageName, newMode);
+ }
+
+ /**
+ * @return whether the app associated with the given {@code packageName} is allowed to turn the
+ * screen on.
+ */
+ static boolean isTurnScreenOnAllowed(AppOpsManager appOpsManager, int uid, String packageName) {
+ return appOpsManager.checkOpNoThrow(OP_TURN_SCREEN_ON, uid, packageName) == MODE_ALLOWED;
+ }
+
+ /**
+ * @return the summary for the current state of whether the app associated with the given
+ * packageName is allowed to turn the screen on.
+ */
+ public static int getPreferenceSummary(AppOpsManager appOpsManager, int uid,
+ String packageName) {
+ final boolean enabled = TurnScreenOnDetails.isTurnScreenOnAllowed(appOpsManager, uid,
+ packageName);
+ return enabled ? R.string.app_permission_summary_allowed
+ : R.string.app_permission_summary_not_allowed;
+ }
+}
diff --git a/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettings.java b/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettings.java
new file mode 100644
index 0000000..302d6b5
--- /dev/null
+++ b/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettings.java
@@ -0,0 +1,214 @@
+/*
+ * 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.applications.specialaccess.turnscreenon;
+
+import android.Manifest;
+import android.annotation.Nullable;
+import android.app.AppOpsManager;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.IconDrawableFactory;
+import android.util.Pair;
+import android.view.View;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.Preference.OnPreferenceClickListener;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.applications.AppInfoBase;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.EmptyTextSettings;
+import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.widget.AppPreference;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Settings page for providing special app access to turn the screen of the device on.
+ */
+@SearchIndexable
+public class TurnScreenOnSettings extends EmptyTextSettings {
+
+ @VisibleForTesting
+ static final List<String> IGNORE_PACKAGE_LIST = new ArrayList<>();
+
+ static {
+ IGNORE_PACKAGE_LIST.add("com.android.systemui");
+ }
+
+ /**
+ * Comparator by name, then user id.
+ * {@see PackageItemInfo#DisplayNameComparator}
+ */
+ static class AppComparator implements Comparator<Pair<ApplicationInfo, Integer>> {
+
+ private final Collator mCollator = Collator.getInstance();
+ private final PackageManager mPm;
+
+ AppComparator(PackageManager pm) {
+ mPm = pm;
+ }
+
+ public final int compare(Pair<ApplicationInfo, Integer> a,
+ Pair<ApplicationInfo, Integer> b) {
+ CharSequence sa = a.first.loadLabel(mPm);
+ if (sa == null) sa = a.first.name;
+ CharSequence sb = b.first.loadLabel(mPm);
+ if (sb == null) sb = b.first.name;
+ int nameCmp = mCollator.compare(sa.toString(), sb.toString());
+ if (nameCmp != 0) {
+ return nameCmp;
+ } else {
+ return a.second - b.second;
+ }
+ }
+ }
+
+ private AppOpsManager mAppOpsManager;
+ private Context mContext;
+ private PackageManager mPackageManager;
+ private UserManager mUserManager;
+ private IconDrawableFactory mIconDrawableFactory;
+
+ public TurnScreenOnSettings() {
+ // Do nothing
+ }
+
+ public TurnScreenOnSettings(PackageManager pm, UserManager um) {
+ mPackageManager = pm;
+ mUserManager = um;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mContext = getActivity();
+ mPackageManager = mContext.getPackageManager();
+ mUserManager = mContext.getSystemService(UserManager.class);
+ mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+ mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ // Clear the prefs
+ final PreferenceScreen screen = getPreferenceScreen();
+ screen.removeAll();
+
+ // Fetch the set of applications for each profile which have the permission required to turn
+ // the screen on with a wake lock.
+ final ArrayList<Pair<ApplicationInfo, Integer>> apps = collectTurnScreenOnApps(
+ UserHandle.myUserId());
+ apps.sort(new AppComparator(mPackageManager));
+
+ // Rebuild the list of prefs
+ final Context prefContext = getPrefContext();
+ for (final Pair<ApplicationInfo, Integer> appData : apps) {
+ final ApplicationInfo appInfo = appData.first;
+ final int userId = appData.second;
+ final UserHandle user = UserHandle.of(userId);
+ final String packageName = appInfo.packageName;
+ final CharSequence label = appInfo.loadLabel(mPackageManager);
+
+ final Preference pref = new AppPreference(prefContext);
+ pref.setIcon(mIconDrawableFactory.getBadgedIcon(appInfo, userId));
+ pref.setTitle(mPackageManager.getUserBadgedLabel(label, user));
+ pref.setSummary(TurnScreenOnDetails.getPreferenceSummary(mAppOpsManager,
+ appInfo.uid, packageName));
+ pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ AppInfoBase.startAppInfoFragment(TurnScreenOnDetails.class,
+ getString(R.string.turn_screen_on_title),
+ packageName, appInfo.uid,
+ TurnScreenOnSettings.this, -1, getMetricsCategory());
+ return true;
+ }
+ });
+ screen.addPreference(pref);
+ }
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ setEmptyText(R.string.no_applications);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.turn_screen_on_settings;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SETTINGS_MANAGE_TURN_SCREEN_ON;
+ }
+
+ /**
+ * @return the list of applications for the given user and all their profiles that can turn on
+ * the screen with wake locks.
+ */
+ @VisibleForTesting
+ ArrayList<Pair<ApplicationInfo, Integer>> collectTurnScreenOnApps(int userId) {
+ final ArrayList<Pair<ApplicationInfo, Integer>> apps = new ArrayList<>();
+ final ArrayList<Integer> userIds = new ArrayList<>();
+ for (UserInfo user : mUserManager.getProfiles(userId)) {
+ userIds.add(user.id);
+ }
+
+ for (int id : userIds) {
+ final List<PackageInfo> installedPackages = mPackageManager.getInstalledPackagesAsUser(
+ /* flags= */ 0, id);
+ for (PackageInfo packageInfo : installedPackages) {
+ if (hasTurnScreenOnPermission(mPackageManager, packageInfo.packageName)) {
+ apps.add(new Pair<>(packageInfo.applicationInfo, id));
+ }
+ }
+ }
+ return apps;
+ }
+
+ /**
+ * @return true if the package has the permission to turn the screen on.
+ */
+ @VisibleForTesting
+ static boolean hasTurnScreenOnPermission(PackageManager packageManager, String packageName) {
+ if (IGNORE_PACKAGE_LIST.contains(packageName)) {
+ return false;
+ }
+ return packageManager.checkPermission(Manifest.permission.WAKE_LOCK, packageName)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider(R.xml.turn_screen_on_settings);
+}
diff --git a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
index 06cee85..7b74f77 100644
--- a/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/LeAudioBluetoothDetailsHeaderController.java
@@ -275,11 +275,15 @@
return;
}
boolean isLeft = (deviceId & LEFT_DEVICE_ID) != 0;
- boolean isRight = (deviceId & LEFT_DEVICE_ID) != 0;
+ boolean isRight = (deviceId & RIGHT_DEVICE_ID) != 0;
boolean isLeftRight = isLeft && isRight;
// The LE device updates the BatteryLayout
if (isLeftRight) {
- Log.d(TAG, "The device id is left+right. Do nothing.");
+ Log.d(TAG, "Show the legacy battery style if the device id is left+right.");
+ final TextView summary = mLayoutPreference.findViewById(R.id.entity_header_summary);
+ if (summary != null) {
+ summary.setText(mCachedDevice.getConnectionSummary());
+ }
} else if (isLeft) {
updateBatteryLayout(getBatteryTitleResource(LEFT_DEVICE_ID),
getBatterySummaryResource(LEFT_DEVICE_ID), cachedDevice.getBatteryLevel());
diff --git a/src/com/android/settings/core/BasePreferenceController.java b/src/com/android/settings/core/BasePreferenceController.java
index c90fe48..6cc09e2 100644
--- a/src/com/android/settings/core/BasePreferenceController.java
+++ b/src/com/android/settings/core/BasePreferenceController.java
@@ -121,10 +121,13 @@
protected final String mPreferenceKey;
protected UiBlockListener mUiBlockListener;
+ protected boolean mUiBlockerFinished;
private boolean mIsForWork;
@Nullable
private UserHandle mWorkProfileUser;
private int mMetricsCategory;
+ private boolean mIsFirstLaunch;
+ private boolean mPrefVisibility;
/**
* Instantiate a controller as specified controller type and user-defined key.
@@ -195,6 +198,8 @@
public BasePreferenceController(Context context, String preferenceKey) {
super(context);
mPreferenceKey = preferenceKey;
+ mIsFirstLaunch = true;
+ mPrefVisibility = true;
if (TextUtils.isEmpty(mPreferenceKey)) {
throw new IllegalArgumentException("Preference key must be set");
}
@@ -327,6 +332,13 @@
}
/**
+ * Set back the value of whether this is the first launch.
+ */
+ public void revokeFirstLaunch() {
+ mIsFirstLaunch = false;
+ }
+
+ /**
* Launches the specified fragment for the work profile user if the associated
* {@link Preference} is clicked. Otherwise just forward it to the super class.
*
@@ -378,6 +390,14 @@
mUiBlockListener = uiBlockListener;
}
+ public void setUiBlockerFinished(boolean isFinished) {
+ mUiBlockerFinished = isFinished;
+ }
+
+ public boolean getSavedPrefVisibility() {
+ return mPrefVisibility;
+ }
+
/**
* Listener to invoke when background job is finished
*/
@@ -428,4 +448,28 @@
protected UserHandle getWorkProfileUser() {
return mWorkProfileUser;
}
+
+ /**
+ * Used for {@link BasePreferenceController} that implements {@link UiBlocker} to control the
+ * preference visibility.
+ */
+ protected void updatePreferenceVisibilityDelegate(Preference preference, boolean isVisible) {
+ if (mUiBlockerFinished || !mIsFirstLaunch) {
+ preference.setVisible(isVisible);
+ return;
+ }
+
+ savePrefVisibility(isVisible);
+
+ // Preferences that should be invisible have a high priority to be updated since the
+ // whole UI should be blocked/invisible. While those that should be visible will be
+ // updated once the blocker work is finished. That's done in DashboardFragment.
+ if (!isVisible) {
+ preference.setVisible(false);
+ }
+ }
+
+ private void savePrefVisibility(boolean isVisible) {
+ mPrefVisibility = isVisible;
+ }
}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index ce3cab9..b11ce01 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -60,6 +60,8 @@
import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetails;
import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureSettings;
import com.android.settings.applications.specialaccess.premiumsms.PremiumSmsAccess;
+import com.android.settings.applications.specialaccess.turnscreenon.TurnScreenOnDetails;
+import com.android.settings.applications.specialaccess.turnscreenon.TurnScreenOnSettings;
import com.android.settings.applications.specialaccess.vrlistener.VrListenerSettings;
import com.android.settings.applications.specialaccess.zenaccess.ZenAccessDetails;
import com.android.settings.backup.PrivacySettings;
@@ -335,7 +337,9 @@
AutoBrightnessSettings.class.getName(),
OneHandedSettings.class.getName(),
MobileNetworkSettings.class.getName(),
- AppLocaleDetails.class.getName()
+ AppLocaleDetails.class.getName(),
+ TurnScreenOnSettings.class.getName(),
+ TurnScreenOnDetails.class.getName()
};
public static final String[] SETTINGS_FOR_RESTRICTED = {
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index 6ac0fa4..bff8226 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -250,6 +250,11 @@
}
mListeningToCategoryChange = false;
}
+ mControllers.forEach(controller -> {
+ if (controller instanceof BasePreferenceController.UiBlocker) {
+ ((BasePreferenceController) controller).revokeFirstLaunch();
+ }
+ });
}
@Override
@@ -424,7 +429,14 @@
for (AbstractPreferenceController controller : controllerList) {
final String key = controller.getPreferenceKey();
final Preference preference = findPreference(key);
- if (preference != null) {
+ if (preference == null) {
+ continue;
+ }
+ if (controller instanceof BasePreferenceController.UiBlocker) {
+ final boolean prefVisible =
+ ((BasePreferenceController) controller).getSavedPrefVisibility();
+ preference.setVisible(visible && controller.isAvailable() && prefVisible);
+ } else {
preference.setVisible(visible && controller.isAvailable());
}
}
@@ -496,6 +508,7 @@
@Override
public void onBlockerWorkFinished(BasePreferenceController controller) {
mBlockerController.countDown(controller.getPreferenceKey());
+ controller.setUiBlockerFinished(mBlockerController.isBlockerFinished());
}
protected Preference createPreference(Tile tile) {
diff --git a/src/com/android/settings/dashboard/UiBlockerController.java b/src/com/android/settings/dashboard/UiBlockerController.java
index 710175b..b3729f1 100644
--- a/src/com/android/settings/dashboard/UiBlockerController.java
+++ b/src/com/android/settings/dashboard/UiBlockerController.java
@@ -37,7 +37,7 @@
*/
public class UiBlockerController {
private static final String TAG = "UiBlockerController";
- private static final int TIMEOUT_MILLIS = 500;
+ private static final int TIMEOUT_MILLIS = 300;
private CountDownLatch mCountDownLatch;
private boolean mBlockerFinished;
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 085a372..722e94e 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -518,6 +518,7 @@
controllers.add(new BugReportInPowerPreferenceController(context));
controllers.add(new AutomaticSystemServerHeapDumpPreferenceController(context));
controllers.add(new MockLocationAppPreferenceController(context, fragment));
+ controllers.add(new MockModemPreferenceController(context));
controllers.add(new DebugViewAttributesPreferenceController(context));
controllers.add(new SelectDebugAppPreferenceController(context, fragment));
controllers.add(new WaitForDebuggerPreferenceController(context));
diff --git a/src/com/android/settings/development/MockModemPreferenceController.java b/src/com/android/settings/development/MockModemPreferenceController.java
new file mode 100644
index 0000000..655f157
--- /dev/null
+++ b/src/com/android/settings/development/MockModemPreferenceController.java
@@ -0,0 +1,86 @@
+/*
+ * 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.development;
+
+import android.content.Context;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.SwitchPreference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.development.DeveloperOptionsPreferenceController;
+
+/**
+ * PreferenceController for MockModem
+ */
+public class MockModemPreferenceController extends
+ DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
+ PreferenceControllerMixin {
+
+ private static final String TAG = "MockModemPreferenceController";
+ private static final String ALLOW_MOCK_MODEM_KEY =
+ "allow_mock_modem";
+ @VisibleForTesting
+ static final String ALLOW_MOCK_MODEM_PROPERTY =
+ "persist.radio.allow_mock_modem";
+
+ public MockModemPreferenceController(Context context) {
+ super(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return ALLOW_MOCK_MODEM_KEY;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean isEnabled = (Boolean) newValue;
+ try {
+ SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY,
+ isEnabled ? "true" : "false");
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Fail to set radio system property: " + e.getMessage());
+ }
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ try {
+ final boolean isEnabled = SystemProperties.getBoolean(
+ ALLOW_MOCK_MODEM_PROPERTY, false /* default */);
+ ((SwitchPreference) mPreference).setChecked(isEnabled);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Fail to get radio system property: " + e.getMessage());
+ }
+ }
+
+ @Override
+ protected void onDeveloperOptionsSwitchDisabled() {
+ super.onDeveloperOptionsSwitchDisabled();
+ try {
+ SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY, "false");
+ ((SwitchPreference) mPreference).setChecked(false);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Fail to set radio system property: " + e.getMessage());
+ }
+ }
+}
diff --git a/src/com/android/settings/development/tare/TareHomePage.java b/src/com/android/settings/development/tare/TareHomePage.java
index cea0954..d0567f7 100644
--- a/src/com/android/settings/development/tare/TareHomePage.java
+++ b/src/com/android/settings/development/tare/TareHomePage.java
@@ -22,7 +22,11 @@
import android.app.Activity;
import android.content.Intent;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
@@ -40,6 +44,9 @@
private Button mRevButton;
private TextView mAlarmManagerView;
private TextView mJobSchedulerView;
+ private ConfigObserver mConfigObserver;
+
+ private static final int SETTING_VALUE_DEFAULT = -1;
private static final int SETTING_VALUE_OFF = 0;
private static final int SETTING_VALUE_ON = 1;
@@ -53,14 +60,17 @@
mAlarmManagerView = findViewById(R.id.alarmmanager);
mJobSchedulerView = findViewById(R.id.jobscheduler);
- final boolean isTareEnabled = Settings.Global.getInt(getContentResolver(),
- Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1;
- setEnabled(isTareEnabled);
+ mConfigObserver = new ConfigObserver(new Handler(Looper.getMainLooper()));
mOnSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- setEnabled(isChecked);
+ if (mConfigObserver.mEnableTareSetting == SETTING_VALUE_DEFAULT
+ && isChecked == (Settings.Global.DEFAULT_ENABLE_TARE == SETTING_VALUE_ON)) {
+ // Don't bother writing something that's not new information. It would make
+ // it hard to use DeviceConfig if we did.
+ return;
+ }
Settings.Global.putInt(getContentResolver(),
Settings.Global.ENABLE_TARE,
isChecked ? SETTING_VALUE_ON : SETTING_VALUE_OFF);
@@ -68,6 +78,18 @@
});
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mConfigObserver.start();
+ }
+
+ @Override
+ protected void onPause() {
+ mConfigObserver.stop();
+ super.onPause();
+ }
+
/** Reverts the TARE settings to the original default settings */
public void revertSettings(View v) {
Toast.makeText(this, R.string.tare_settings_reverted_toast, Toast.LENGTH_LONG).show();
@@ -77,7 +99,6 @@
Settings.Global.TARE_ALARM_MANAGER_CONSTANTS, null);
Settings.Global.putString(getApplicationContext().getContentResolver(),
Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS, null);
- setEnabled(Settings.Global.DEFAULT_ENABLE_TARE == SETTING_VALUE_ON);
}
/** Opens up the AlarmManager TARE policy page with its factors to view and edit */
@@ -101,4 +122,42 @@
mJobSchedulerView.setEnabled(tareStatus);
mOnSwitch.setChecked(tareStatus);
}
+
+ private class ConfigObserver extends ContentObserver {
+ private int mEnableTareSetting;
+
+ ConfigObserver(Handler handler) {
+ super(handler);
+ }
+
+ public void start() {
+ getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this);
+ processEnableTareChange();
+ }
+
+ public void stop() {
+ getContentResolver().unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ processEnableTareChange();
+ }
+
+ private void processEnableTareChange() {
+ final String setting =
+ Settings.Global.getString(getContentResolver(), Settings.Global.ENABLE_TARE);
+ if (setting == null ) {
+ mEnableTareSetting = SETTING_VALUE_DEFAULT;
+ } else {
+ try {
+ mEnableTareSetting = Integer.parseInt(setting);
+ } catch (NumberFormatException e) {
+ mEnableTareSetting = Settings.Global.DEFAULT_ENABLE_TARE;
+ }
+ }
+ setEnabled(mEnableTareSetting == SETTING_VALUE_ON);
+ }
+ }
}
diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java
index 25bf852..20795d7 100644
--- a/src/com/android/settings/display/ScreenTimeoutSettings.java
+++ b/src/com/android/settings/display/ScreenTimeoutSettings.java
@@ -210,8 +210,8 @@
if (isScreenAttentionAvailable(getContext())) {
mAdaptiveSleepPermissionController.addToScreen(screen);
mAdaptiveSleepCameraStatePreferenceController.addToScreen(screen);
- mAdaptiveSleepBatterySaverPreferenceController.addToScreen(screen);
mAdaptiveSleepController.addToScreen(screen);
+ mAdaptiveSleepBatterySaverPreferenceController.addToScreen(screen);
screen.addPreference(mPrivacyPreference);
}
diff --git a/src/com/android/settings/homepage/DeepLinkHomepageActivity.java b/src/com/android/settings/homepage/DeepLinkHomepageActivity.java
index 59cfc3c..fce7b66 100644
--- a/src/com/android/settings/homepage/DeepLinkHomepageActivity.java
+++ b/src/com/android/settings/homepage/DeepLinkHomepageActivity.java
@@ -16,6 +16,6 @@
package com.android.settings.homepage;
-/** Activity for other apps to launch Settings deep link page */
+/** Activity for other apps to launch a Settings deep link page */
public class DeepLinkHomepageActivity extends SettingsHomepageActivity {
}
diff --git a/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java b/src/com/android/settings/homepage/DeepLinkHomepageActivityInternal.java
similarity index 75%
rename from src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java
rename to src/com/android/settings/homepage/DeepLinkHomepageActivityInternal.java
index 2ea8a83..7a206a1 100644
--- a/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java
+++ b/src/com/android/settings/homepage/DeepLinkHomepageActivityInternal.java
@@ -16,6 +16,9 @@
package com.android.settings.homepage;
-/** Activity for Slices to launch Settings deep link page */
-public class SliceDeepLinkHomepageActivity extends SettingsHomepageActivity {
+/**
+ * Activity used for search results and slices to launch a deep link page without the cross-app
+ * transition animation
+ */
+public class DeepLinkHomepageActivityInternal extends SettingsHomepageActivity {
}
diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java
index 3ed305e..7aeea11 100644
--- a/src/com/android/settings/homepage/SettingsHomepageActivity.java
+++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java
@@ -344,7 +344,7 @@
}
if (!(this instanceof DeepLinkHomepageActivity
- || this instanceof SliceDeepLinkHomepageActivity)) {
+ || this instanceof DeepLinkHomepageActivityInternal)) {
Log.e(TAG, "Not a deep link component");
finish();
return;
diff --git a/src/com/android/settings/nearby/FastPairSettingsFragment.java b/src/com/android/settings/nearby/FastPairSettingsFragment.java
index 702e90a..434087d 100644
--- a/src/com/android/settings/nearby/FastPairSettingsFragment.java
+++ b/src/com/android/settings/nearby/FastPairSettingsFragment.java
@@ -58,8 +58,7 @@
mainSwitchPreference.addOnSwitchChangeListener(
(switchView, isChecked) ->
NearbyManager.setFastPairScanEnabled(getContext(), isChecked));
- mainSwitchPreference.setChecked(
- NearbyManager.getFastPairScanEnabled(getContext(), false));
+ mainSwitchPreference.setChecked(NearbyManager.getFastPairScanEnabled(getContext()));
Preference savedDevicePref = Objects.requireNonNull(
findPreference(SAVED_DEVICES_PREF_KEY));
diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
index 793f600..73795dd 100644
--- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseFragment.java
@@ -255,7 +255,8 @@
// Device, profile, or secondary user is wiped
final String message = getWipeMessage(userType);
LastTryDialog.show(fragmentManager, null /* title */, message,
- R.string.lock_failed_attempts_now_wiping_dialog_dismiss, true /* dismiss */);
+ com.android.settingslib.R.string.failed_attempts_now_wiping_dialog_dismiss,
+ true /* dismiss */);
}
}
@@ -277,13 +278,15 @@
private String getWipeMessage(int userType) {
switch (userType) {
case USER_TYPE_PRIMARY:
- return getString(R.string.lock_failed_attempts_now_wiping_device);
+ return getString(com.android.settingslib
+ .R.string.failed_attempts_now_wiping_device);
case USER_TYPE_MANAGED_PROFILE:
return mDevicePolicyManager.getResources().getString(
WORK_PROFILE_LOCK_ATTEMPTS_FAILED,
- () -> getString(R.string.lock_failed_attempts_now_wiping_profile));
+ () -> getString(com.android.settingslib
+ .R.string.failed_attempts_now_wiping_profile));
case USER_TYPE_SECONDARY:
- return getString(R.string.lock_failed_attempts_now_wiping_user);
+ return getString(com.android.settingslib.R.string.failed_attempts_now_wiping_user);
default:
throw new IllegalArgumentException("Unrecognized user type:" + userType);
}
diff --git a/src/com/android/settings/safetycenter/LockScreenSafetySource.java b/src/com/android/settings/safetycenter/LockScreenSafetySource.java
index 5e5f6d5..91e9773 100644
--- a/src/com/android/settings/safetycenter/LockScreenSafetySource.java
+++ b/src/com/android/settings/safetycenter/LockScreenSafetySource.java
@@ -62,7 +62,8 @@
final RestrictedLockUtils.EnforcedAdmin admin = RestrictedLockUtilsInternal
.checkIfPasswordQualityIsSet(context, userId);
final PendingIntent pendingIntent = createPendingIntent(context,
- screenLockPreferenceDetailsUtils.getLaunchChooseLockGenericFragmentIntent());
+ screenLockPreferenceDetailsUtils.getLaunchChooseLockGenericFragmentIntent(
+ SettingsEnums.SAFETY_CENTER));
final IconAction gearMenuIconAction = createGearMenuIconAction(context,
screenLockPreferenceDetailsUtils);
final boolean enabled =
@@ -100,8 +101,7 @@
/** Notifies Safety Center of a change in lock screen settings. */
public static void onLockScreenChange(Context context) {
setSafetySourceData(
- context,
- new ScreenLockPreferenceDetailsUtils(context, SettingsEnums.SAFETY_CENTER),
+ context, new ScreenLockPreferenceDetailsUtils(context),
new SafetyEvent.Builder(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build());
// Also send refreshed safety center data for biometrics, since changing lockscreen settings
@@ -114,7 +114,8 @@
return screenLockPreferenceDetailsUtils.shouldShowGearMenu() ? new IconAction(
IconAction.ICON_TYPE_GEAR,
createPendingIntent(context,
- screenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent()))
+ screenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent(
+ SettingsEnums.SAFETY_CENTER)))
: null;
}
diff --git a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
index dec06b0..3ea23f3 100644
--- a/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
+++ b/src/com/android/settings/safetycenter/SafetySourceBroadcastReceiver.java
@@ -22,7 +22,6 @@
import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_DEVICE_REBOOTED;
import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED;
-import android.app.settings.SettingsEnums;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -74,8 +73,7 @@
SafetyEvent safetyEvent) {
if (sourceIds.contains(LockScreenSafetySource.SAFETY_SOURCE_ID)) {
LockScreenSafetySource.setSafetySourceData(context,
- new ScreenLockPreferenceDetailsUtils(context, SettingsEnums.SAFETY_CENTER),
- safetyEvent);
+ new ScreenLockPreferenceDetailsUtils(context), safetyEvent);
}
if (sourceIds.contains(BiometricsSafetySource.SAFETY_SOURCE_ID)) {
@@ -85,8 +83,7 @@
private static void refreshAllSafetySources(Context context, SafetyEvent safetyEvent) {
LockScreenSafetySource.setSafetySourceData(context,
- new ScreenLockPreferenceDetailsUtils(context, SettingsEnums.SAFETY_CENTER),
- safetyEvent);
+ new ScreenLockPreferenceDetailsUtils(context), safetyEvent);
BiometricsSafetySource.setSafetySourceData(context, safetyEvent);
}
}
diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java
index ab2d27c..5e71029 100644
--- a/src/com/android/settings/search/SearchResultTrampoline.java
+++ b/src/com/android/settings/search/SearchResultTrampoline.java
@@ -34,6 +34,7 @@
import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
import com.android.settings.core.FeatureFlags;
+import com.android.settings.homepage.DeepLinkHomepageActivityInternal;
import com.android.settings.homepage.SettingsHomepageActivity;
import com.android.settings.overlay.FeatureFactory;
@@ -101,6 +102,7 @@
} else if (isSettingsIntelligence(callingActivity)) {
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) {
startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey)
+ .setClass(this, DeepLinkHomepageActivityInternal.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS));
} else {
diff --git a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
index 4e54238..3870634 100644
--- a/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
+++ b/src/com/android/settings/security/ChangeScreenLockPreferenceController.java
@@ -62,8 +62,7 @@
mHost = host;
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
- mScreenLockPreferenceDetailUtils =
- new ScreenLockPreferenceDetailsUtils(context, host.getMetricsCategory());
+ mScreenLockPreferenceDetailUtils = new ScreenLockPreferenceDetailsUtils(context);
}
@Override
@@ -106,7 +105,7 @@
if (TextUtils.equals(p.getKey(), getPreferenceKey())) {
mMetricsFeatureProvider.logClickedPreference(p,
p.getExtras().getInt(DashboardFragment.CATEGORY));
- mScreenLockPreferenceDetailUtils.openScreenLockSettings();
+ mScreenLockPreferenceDetailUtils.openScreenLockSettings(mHost.getMetricsCategory());
}
}
@@ -115,7 +114,8 @@
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return super.handlePreferenceTreeClick(preference);
}
- return mScreenLockPreferenceDetailUtils.openChooseLockGenericFragment();
+ return mScreenLockPreferenceDetailUtils.openChooseLockGenericFragment(
+ mHost.getMetricsCategory());
}
protected void updateSummary(Preference preference, int userId) {
diff --git a/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java b/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java
index a191acd..19e70d9 100644
--- a/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java
+++ b/src/com/android/settings/security/ScreenLockPreferenceDetailsUtils.java
@@ -46,16 +46,14 @@
private final LockPatternUtils mLockPatternUtils;
private final int mProfileChallengeUserId;
private final UserManager mUm;
- private final int mSourceMetricsCategory;
- public ScreenLockPreferenceDetailsUtils(Context context, int sourceMetricsCategory) {
+ public ScreenLockPreferenceDetailsUtils(Context context) {
mContext = context;
mUm = context.getSystemService(UserManager.class);
mLockPatternUtils = FeatureFactory.getFactory(context)
.getSecurityFeatureProvider()
.getLockPatternUtils(context);
mProfileChallengeUserId = Utils.getManagedProfileId(mUm, mUserId);
- mSourceMetricsCategory = sourceMetricsCategory;
}
/**
@@ -100,17 +98,17 @@
/**
* Launches the {@link ScreenLockSettings}.
*/
- public void openScreenLockSettings() {
- mContext.startActivity(getLaunchScreenLockSettingsIntent());
+ public void openScreenLockSettings(int sourceMetricsCategory) {
+ mContext.startActivity(getLaunchScreenLockSettingsIntent(sourceMetricsCategory));
}
/**
* Returns {@link Intent} to launch the {@link ScreenLockSettings}.
*/
- public Intent getLaunchScreenLockSettingsIntent() {
+ public Intent getLaunchScreenLockSettingsIntent(int sourceMetricsCategory) {
return new SubSettingLauncher(mContext)
.setDestination(ScreenLockSettings.class.getName())
- .setSourceMetricsCategory(mSourceMetricsCategory)
+ .setSourceMetricsCategory(sourceMetricsCategory)
.toIntent();
}
@@ -120,13 +118,13 @@
*
* @return true if the {@link ChooseLockGenericFragment} is launching.
*/
- public boolean openChooseLockGenericFragment() {
+ public boolean openChooseLockGenericFragment(int sourceMetricsCategory) {
final Intent quietModeDialogIntent = getQuietModeDialogIntent();
if (quietModeDialogIntent != null) {
mContext.startActivity(quietModeDialogIntent);
return false;
}
- mContext.startActivity(getChooseLockGenericFragmentIntent());
+ mContext.startActivity(getChooseLockGenericFragmentIntent(sourceMetricsCategory));
return true;
}
@@ -137,10 +135,10 @@
* to disable the Quiet Mode, otherwise returns {@link Intent} to launch
* {@link ChooseLockGenericFragment}.
*/
- public Intent getLaunchChooseLockGenericFragmentIntent() {
+ public Intent getLaunchChooseLockGenericFragmentIntent(int sourceMetricsCategory) {
final Intent quietModeDialogIntent = getQuietModeDialogIntent();
return quietModeDialogIntent != null ? quietModeDialogIntent
- : getChooseLockGenericFragmentIntent();
+ : getChooseLockGenericFragmentIntent(sourceMetricsCategory);
}
private Intent getQuietModeDialogIntent() {
@@ -159,10 +157,10 @@
return null;
}
- private Intent getChooseLockGenericFragmentIntent() {
+ private Intent getChooseLockGenericFragmentIntent(int sourceMetricsCategory) {
return new SubSettingLauncher(mContext)
.setDestination(ChooseLockGenericFragment.class.getName())
- .setSourceMetricsCategory(mSourceMetricsCategory)
+ .setSourceMetricsCategory(sourceMetricsCategory)
.setTransitionType(SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE)
.toIntent();
}
diff --git a/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java b/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java
index c0f7e1f..c871e9f 100644
--- a/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java
+++ b/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java
@@ -44,8 +44,10 @@
import androidx.preference.PreferenceGroup;
import com.android.settings.R;
+import com.android.settings.Settings;
import com.android.settings.Settings.TetherSettingsActivity;
import com.android.settings.core.BasePreferenceController;
+import com.android.settings.gestures.OneHandedSettingsUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -178,6 +180,12 @@
return null;
}
for (ResolveInfo info : activities) {
+ if (info.activityInfo.name.contains(
+ Settings.OneHandedSettingsActivity.class.getSimpleName())) {
+ if (!OneHandedSettingsUtils.isSupportOneHandedMode()) {
+ continue;
+ }
+ }
if (info.activityInfo.name.endsWith(TetherSettingsActivity.class.getSimpleName())) {
if (!mConnectivityManager.isTetheringSupported()) {
continue;
diff --git a/src/com/android/settings/users/UserDetailsSettings.java b/src/com/android/settings/users/UserDetailsSettings.java
index a3c8e69..f60aec7 100644
--- a/src/com/android/settings/users/UserDetailsSettings.java
+++ b/src/com/android/settings/users/UserDetailsSettings.java
@@ -297,7 +297,7 @@
!mDefaultGuestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS));
mRemoveUserPref.setTitle(mGuestUserAutoCreated
? com.android.settingslib.R.string.guest_reset_guest
- : R.string.user_exit_guest_title);
+ : com.android.settingslib.R.string.guest_exit_guest);
if (mGuestUserAutoCreated) {
mRemoveUserPref.setEnabled((mUserInfo.flags & UserInfo.FLAG_INITIALIZED) != 0);
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 0f2eb66..8895912 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -310,7 +310,7 @@
mAddUser = findPreference(KEY_ADD_USER);
if (!mUserCaps.mCanAddRestrictedProfile) {
// Label should only mention adding a "user", not a "profile"
- mAddUser.setTitle(R.string.user_add_user_menu);
+ mAddUser.setTitle(com.android.settingslib.R.string.user_add_user);
}
mAddUser.setOnPreferenceClickListener(this);
@@ -425,9 +425,9 @@
if (isCurrentUserGuest()) {
// No need to load profile information
mMePreference.setIcon(getEncircledDefaultIcon());
- mMePreference.setTitle(
- mGuestUserAutoCreated ? com.android.settingslib.R.string.guest_reset_guest
- : R.string.user_exit_guest_title);
+ mMePreference.setTitle(mGuestUserAutoCreated
+ ? com.android.settingslib.R.string.guest_reset_guest
+ : com.android.settingslib.R.string.guest_exit_guest);
mMePreference.setSelectable(true);
// removing a guest will result in switching back to the admin user
mMePreference.setEnabled(canSwitchUserNow());
@@ -704,7 +704,7 @@
}
case DIALOG_CONFIRM_EXIT_GUEST: {
Dialog dlg = new AlertDialog.Builder(context)
- .setTitle(R.string.user_exit_guest_confirm_title)
+ .setTitle(com.android.settingslib.R.string.guest_remove_guest_dialog_title)
.setMessage(R.string.user_exit_guest_confirm_message)
.setPositiveButton(R.string.user_exit_guest_dialog_remove,
new DialogInterface.OnClickListener() {
@@ -1157,7 +1157,7 @@
mAddGuest.setIcon(centerAndTint(icon));
mAddGuest.setSelectable(true);
if (mGuestUserAutoCreated && mGuestCreationScheduled.get()) {
- mAddGuest.setTitle(com.android.settingslib.R.string.user_guest);
+ mAddGuest.setTitle(com.android.internal.R.string.guest_name);
mAddGuest.setSummary(R.string.guest_resetting);
mAddGuest.setEnabled(false);
} else {
@@ -1199,8 +1199,7 @@
addUser.setEnabled(canAddMoreUsers && !mAddingUser && canSwitchUserNow());
if (!canAddMoreUsers) {
- addUser.setSummary(
- getString(R.string.user_add_max_count, getRealUsersCount()));
+ addUser.setSummary(getString(R.string.user_add_max_count));
} else {
addUser.setSummary(null);
}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
index b160d90..30f38d2 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
@@ -58,12 +58,17 @@
final static String EXTRA_IS_SPECIFIED_SSID =
"com.android.settings.wifi.extra.REQUEST_IS_FOR_SINGLE_NETWORK";
- @VisibleForTesting NetworkRequestDialogBaseFragment mDialogFragment;
+ @VisibleForTesting
+ NetworkRequestDialogBaseFragment mDialogFragment;
+ @VisibleForTesting
+ boolean mIsSpecifiedSsid;
+ @VisibleForTesting
+ boolean mShowingErrorDialog;
+ @VisibleForTesting
+ ProgressDialog mProgressDialog;
+
private NetworkRequestUserSelectionCallback mUserSelectionCallback;
- private boolean mIsSpecifiedSsid;
- private boolean mShowingErrorDialog;
private WifiConfiguration mMatchedConfig;
- @VisibleForTesting ProgressDialog mProgressDialog;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -103,7 +108,8 @@
mDialogFragment.show(getSupportFragmentManager(), TAG);
}
- private void dismissDialogs() {
+ @VisibleForTesting
+ void dismissDialogs() {
if (mDialogFragment != null) {
mDialogFragment.dismiss();
mDialogFragment = null;
@@ -174,7 +180,9 @@
return;
}
- mDialogFragment.onUserSelectionCallbackRegistration(userSelectionCallback);
+ if (mDialogFragment != null) {
+ mDialogFragment.onUserSelectionCallbackRegistration(userSelectionCallback);
+ }
}
@Override
@@ -201,7 +209,9 @@
return;
}
- mDialogFragment.onMatch(scanResults);
+ if (mDialogFragment != null) {
+ mDialogFragment.onMatch(scanResults);
+ }
}
@Override
diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
index f1e6568..169bcb3 100644
--- a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
+++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java
@@ -56,8 +56,6 @@
final Bundle mBundle = new Bundle();
@VisibleForTesting
IActivityManager mActivityManager = ActivityManager.getService();
- @VisibleForTesting
- boolean mIsAddWifiConfigAllow;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -74,8 +72,6 @@
window.setGravity(Gravity.BOTTOM);
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT);
-
- mIsAddWifiConfigAllow = WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(this);
}
@Override
@@ -90,7 +86,7 @@
@VisibleForTesting
protected boolean showAddNetworksFragment() {
- if (!mIsAddWifiConfigAllow) {
+ if (!isAddWifiConfigAllow()) {
Log.d(TAG, "Not allowed by Enterprise Restriction");
return false;
}
@@ -129,4 +125,9 @@
}
return packageName;
}
+
+ @VisibleForTesting
+ boolean isAddWifiConfigAllow() {
+ return WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(this);
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
index 2ec960e..d3a4be7 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -43,7 +43,7 @@
import com.android.internal.app.chooser.DisplayResolveInfo;
import com.android.internal.app.chooser.TargetInfo;
import com.android.settings.R;
-import com.android.settings.wifi.qrcode.QrCodeGenerator;
+import com.android.settingslib.qrcode.QrCodeGenerator;
import com.google.zxing.WriterException;
diff --git a/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java b/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java
deleted file mode 100644
index d9682d2..0000000
--- a/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java
+++ /dev/null
@@ -1,63 +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.wifi.qrcode;
-
-import android.graphics.Bitmap;
-import android.graphics.Color;
-
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.EncodeHintType;
-import com.google.zxing.MultiFormatWriter;
-import com.google.zxing.WriterException;
-import com.google.zxing.common.BitMatrix;
-
-import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-public final class QrCodeGenerator {
- /**
- * Generates a barcode image with {@code contents}.
- *
- * @param contents The contents to encode in the barcode
- * @param size The preferred image size in pixels
- * @return Barcode bitmap
- */
- public static Bitmap encodeQrCode(String contents, int size)
- throws WriterException, IllegalArgumentException {
- final Map<EncodeHintType, Object> hints = new HashMap<>();
- if (!isIso88591(contents)) {
- hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
- }
-
- final BitMatrix qrBits = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,
- size, size, hints);
- final Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565);
- for (int x = 0; x < size; x++) {
- for (int y = 0; y < size; y++) {
- bitmap.setPixel(x, y, qrBits.get(x, y) ? Color.BLACK : Color.WHITE);
- }
- }
- return bitmap;
- }
-
- private static boolean isIso88591(String contents) {
- CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder();
- return encoder.canEncode(contents);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
index 83bba14..ddc3fe4 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityDialogUtilsTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
+import android.app.Dialog;
import android.content.Context;
import androidx.appcompat.app.AlertDialog;
@@ -58,4 +59,14 @@
assertThat(AccessibilityDialogUtils.updateSoftwareShortcutInDialog(mContext,
dialog)).isFalse();
}
+
+ @Test
+ public void showDialog_createCustomDialog_isShowing() {
+ final Dialog dialog = AccessibilityDialogUtils.createCustomDialog(mContext,
+ "Title", /* customView= */ null, "positiveButton", /* positiveListener= */ null,
+ "negativeButton", /* negativeListener= */ null);
+ dialog.show();
+
+ assertThat(dialog.isShowing()).isTrue();
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
index e3940e7..30ba9b6 100644
--- a/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/MagnificationModePreferenceControllerTest.java
@@ -16,7 +16,6 @@
package com.android.settings.accessibility;
-import static com.android.settings.accessibility.AccessibilityDialogUtils.CustomButton;
import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
import static com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo;
import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
@@ -28,17 +27,24 @@
import android.app.Dialog;
import android.content.Context;
+import android.content.DialogInterface;
import android.os.Bundle;
import android.provider.Settings;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
+import android.widget.TextView;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
+import com.android.settings.utils.AnnotationSpan;
import org.junit.Before;
import org.junit.Rule;
@@ -48,7 +54,6 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
/** Tests for {@link MagnificationModePreferenceController}. */
@RunWith(RobolectricTestRunner.class)
@@ -68,7 +73,8 @@
@Before
public void setUp() {
- mContext = RuntimeEnvironment.application;
+ mContext = ApplicationProvider.getApplicationContext();
+ mContext.setTheme(R.style.Theme_AppCompat);
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
mScreen = preferenceManager.createPreferenceScreen(mContext);
mModePreference = new Preference(mContext);
@@ -83,8 +89,8 @@
public void clickPreference_settingsModeIsDefault_checkedModeInDialogIsDefault() {
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
- assertThat(getCheckedModeFromDialog()).isEqualTo(
- MAGNIFICATION_MODE_DEFAULT);
+ assertThat(getCheckedModeFromDialog()).isEqualTo(MAGNIFICATION_MODE_DEFAULT);
+
}
@Test
@@ -109,52 +115,103 @@
}
@Test
- public void chooseWindowMode_tripleTapEnabled_showSwitchShortcutDialog() {
+ public void chooseFullscreenMode_tripleTapEnabled_notShowTripleTapWarningDialog() {
+ enableTripleTap();
+ mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
+
+ performItemClickWith(MagnificationMode.FULLSCREEN);
+ mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+ DialogInterface.BUTTON_POSITIVE);
+
+ verify(mDialogHelper, never()).showDialog(
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+ }
+
+ @Test
+ public void chooseWindowMode_tripleTapEnabled_showTripleTapWarningDialog() {
enableTripleTap();
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
performItemClickWith(MagnificationMode.WINDOW);
+ mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+ DialogInterface.BUTTON_POSITIVE);
verify(mDialogHelper).showDialog(
- MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
}
@Test
- public void chooseModeAll_modeAllInSettingsAndTripleTapEnabled_notShowShortcutDialog() {
+ public void chooseAllMode_tripleTapEnabled_showTripleTapWarningDialog() {
enableTripleTap();
mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
performItemClickWith(MagnificationMode.ALL);
+ mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+ DialogInterface.BUTTON_POSITIVE);
- verify(mDialogHelper, never()).showDialog(
- MagnificationModePreferenceController.DIALOG_MAGNIFICATION_SWITCH_SHORTCUT);
+ verify(mDialogHelper).showDialog(
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
}
@Test
- public void onSwitchShortcutDialogPositiveButtonClicked_TripleTapEnabled_TripleTapDisabled() {
+ public void onTripleTapWarningDialogNegativeButtonClicked_showModeDialog() {
+ mDialogHelper.showDialog(
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+
+ mController.onMagnificationTripleTapWarningDialogNegativeButtonClicked(
+ mDialogHelper.getDialog(), DialogInterface.BUTTON_NEGATIVE);
+
+ verify(mDialogHelper).showDialog(
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE);
+ }
+
+ @Test
+ public void onTripleTapWarningDialogPositiveButtonClicked_chooseAllMode_returnAllSummary() {
enableTripleTap();
+ mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference);
+ performItemClickWith(MagnificationMode.ALL);
+ mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(),
+ DialogInterface.BUTTON_POSITIVE);
- mController.onSwitchShortcutDialogButtonClicked(CustomButton.POSITIVE);
+ mController.onMagnificationTripleTapWarningDialogPositiveButtonClicked(
+ mDialogHelper.getDialog(), DialogInterface.BUTTON_POSITIVE);
- assertThat(MagnificationModePreferenceController.isTripleTapEnabled(mContext)).isFalse();
+ final String allSummary = mContext.getString(
+ R.string.accessibility_magnification_area_settings_all_summary);
+ assertThat(TextUtils.equals(mController.getSummary(), allSummary)).isTrue();
+ }
+
+ @Test
+ public void checkSpansInTripleTapWarningDialog_existAnnotationSpan() {
+ mDialogHelper.showDialog(
+ MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING);
+ final View contentView = mDialogHelper.getDialog().findViewById(android.R.id.content);
+ final TextView messageView = contentView.findViewById(R.id.message);
+ final CharSequence textInTripleTapWarningDialog = messageView.getText();
+
+ final AnnotationSpan[] annotationSpans =
+ ((SpannableString) textInTripleTapWarningDialog).getSpans(/*queryStart= */ 0,
+ textInTripleTapWarningDialog.length(), AnnotationSpan.class);
+
+ assertThat(annotationSpans[0]).isNotNull();
}
@Test
public void getSummary_saveWindowScreen_shouldReturnWindowScreenSummary() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW);
- assertThat(mController.getSummary())
- .isEqualTo(mContext.getString(
- R.string.accessibility_magnification_area_settings_window_screen_summary));
+ final String windowSummary = mContext.getString(
+ R.string.accessibility_magnification_area_settings_window_screen_summary);
+ assertThat(TextUtils.equals(mController.getSummary(), windowSummary)).isTrue();
}
@Test
public void getSummary_saveAll_shouldReturnAllSummary() {
MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL);
- assertThat(mController.getSummary())
- .isEqualTo(mContext.getString(
- R.string.accessibility_magnification_area_settings_all_summary));
+ final String allSummary = mContext.getString(
+ R.string.accessibility_magnification_area_settings_all_summary);
+ assertThat(TextUtils.equals(mController.getSummary(), allSummary)).isTrue();
}
private int getCheckedModeFromDialog() {
@@ -208,10 +265,11 @@
private static class TestDialogHelper implements DialogCreatable,
MagnificationModePreferenceController.DialogHelper {
private DialogCreatable mDialogDelegate;
+ private Dialog mDialog;
@Override
public void showDialog(int dialogId) {
- onCreateDialog(dialogId);
+ mDialog = onCreateDialog(dialogId);
}
@Override
@@ -228,5 +286,9 @@
public int getDialogMetricsCategory(int dialogId) {
return mDialogDelegate.getDialogMetricsCategory(dialogId);
}
+
+ public Dialog getDialog() {
+ return mDialog;
+ }
}
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java
index 714ef9a..ee271fe 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ShortcutPreferenceTest.java
@@ -23,6 +23,7 @@
import android.view.View;
import androidx.preference.PreferenceViewHolder;
+import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
@@ -30,7 +31,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
/** Tests for {@link ShortcutPreference} */
@RunWith(RobolectricTestRunner.class)
@@ -58,7 +58,7 @@
@Before
public void setUp() {
- final Context context = RuntimeEnvironment.application;
+ final Context context = ApplicationProvider.getApplicationContext();
mShortcutPreference = new ShortcutPreference(context, null);
final LayoutInflater inflater = LayoutInflater.from(context);
@@ -95,4 +95,13 @@
assertThat(mShortcutPreference.isChecked()).isEqualTo(true);
}
+
+ @Test
+ public void performClickOnPreference_settingsClicked() {
+ mShortcutPreference.onBindViewHolder(mPreferenceViewHolder);
+ mShortcutPreference.setOnClickCallback(mListener);
+ mShortcutPreference.performClick();
+
+ assertThat(mResult).isEqualTo(SETTINGS_CLICKED);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
index 2b628f5..40e31fd 100644
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
@@ -26,9 +26,14 @@
import android.content.Context;
import android.os.Vibrator;
+import android.provider.Settings;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
+import com.android.settings.R;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,10 +45,14 @@
public class VibrationPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
+ private static final int OFF = 0;
+ private static final int ON = 1;
@Mock private Vibrator mVibrator;
+ @Mock private PreferenceScreen mScreen;
private Context mContext;
+ private Preference mPreference;
@Before
public void setUp() {
@@ -54,16 +63,14 @@
@Test
public void verifyConstants() {
- VibrationPreferenceController controller =
- new VibrationPreferenceController(mContext, PREFERENCE_KEY);
+ VibrationPreferenceController controller = createPreferenceController();
assertThat(controller.getPreferenceKey()).isEqualTo(PREFERENCE_KEY);
}
@Test
public void getAvailabilityStatus_noVibrator_returnUnsupportedOnDevice() {
when(mVibrator.hasVibrator()).thenReturn(false);
- VibrationPreferenceController controller =
- new VibrationPreferenceController(mContext, PREFERENCE_KEY);
+ VibrationPreferenceController controller = createPreferenceController();
assertThat(controller.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@@ -71,9 +78,52 @@
@Test
public void getAvailabilityStatus_withVibrator_returnAvailable() {
when(mVibrator.hasVibrator()).thenReturn(true);
- VibrationPreferenceController controller =
- new VibrationPreferenceController(mContext, PREFERENCE_KEY);
+ VibrationPreferenceController controller = createPreferenceController();
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
+
+ @Test
+ public void getSummary_vibrateSettingNotSet_returnsOnText() {
+ when(mVibrator.hasVibrator()).thenReturn(true);
+ Settings.System.putString(mContext.getContentResolver(), Settings.System.VIBRATE_ON,
+ /* value= */ null);
+ VibrationPreferenceController controller = createPreferenceController();
+ controller.updateState(mPreference);
+
+ assertThat(mPreference.getSummary().toString()).isEqualTo(
+ mContext.getString(R.string.switch_on_text));
+ }
+
+ @Test
+ public void getSummary_vibrateSettingOn_returnsOnText() {
+ when(mVibrator.hasVibrator()).thenReturn(true);
+ Settings.System.putInt(mContext.getContentResolver(), Settings.System.VIBRATE_ON, ON);
+ VibrationPreferenceController controller = createPreferenceController();
+ controller.updateState(mPreference);
+
+ assertThat(mPreference.getSummary().toString()).isEqualTo(
+ mContext.getString(R.string.switch_on_text));
+ }
+
+ @Test
+ public void getSummary_vibrateSettingOff_returnsOffText() {
+ when(mVibrator.hasVibrator()).thenReturn(true);
+ Settings.System.putInt(mContext.getContentResolver(), Settings.System.VIBRATE_ON, OFF);
+ VibrationPreferenceController controller = createPreferenceController();
+ controller.updateState(mPreference);
+
+ assertThat(mPreference.getSummary().toString()).isEqualTo(
+ mContext.getString(R.string.switch_off_text));
+ }
+
+ private VibrationPreferenceController createPreferenceController() {
+ VibrationPreferenceController controller =
+ new VibrationPreferenceController(mContext, PREFERENCE_KEY);
+ mPreference = new Preference(mContext);
+ mPreference.setSummary("Test summary");
+ when(mScreen.findPreference(controller.getPreferenceKey())).thenReturn(mPreference);
+ controller.displayPreference(mScreen);
+ return controller;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnDetailsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnDetailsTest.java
new file mode 100644
index 0000000..c27ad2b
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnDetailsTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.applications.specialaccess.turnscreenon;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.OP_TURN_SCREEN_ON;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.app.AppOpsManager;
+
+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 TurnScreenOnDetailsTest {
+
+ private static final int UID = 0;
+ private static final String PACKAGE_NAME = "com.android.fake.package";
+
+ @Mock
+ private AppOpsManager mAppOpsManager;
+
+
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void isTurnScreenOnAllowed_appOpErrored_shouldReturnFalse() {
+ when(mAppOpsManager.checkOpNoThrow(eq(OP_TURN_SCREEN_ON), eq(UID),
+ eq(PACKAGE_NAME))).thenReturn(MODE_ERRORED);
+
+ boolean isAllowed = TurnScreenOnDetails.isTurnScreenOnAllowed(mAppOpsManager, UID,
+ PACKAGE_NAME);
+
+ assertThat(isAllowed).isFalse();
+ }
+
+ @Test
+ public void isTurnScreenOnAllowed_appOpAllowed_shouldReturnTrue() {
+ when(mAppOpsManager.checkOpNoThrow(eq(OP_TURN_SCREEN_ON), eq(UID),
+ eq(PACKAGE_NAME))).thenReturn(MODE_ALLOWED);
+
+ boolean isAllowed = TurnScreenOnDetails.isTurnScreenOnAllowed(mAppOpsManager, UID,
+ PACKAGE_NAME);
+
+ assertThat(isAllowed).isTrue();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettingsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettingsTest.java
new file mode 100644
index 0000000..6325d9d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/turnscreenon/TurnScreenOnSettingsTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.applications.specialaccess.turnscreenon;
+
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.UserManager;
+import android.util.Pair;
+
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import com.google.common.collect.ImmutableList;
+
+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 java.util.ArrayList;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+public class TurnScreenOnSettingsTest {
+
+ private static final int PRIMARY_USER_ID = 0;
+ private static final int PROFILE_USER_ID = 10;
+
+ private TurnScreenOnSettings mFragment;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private UserManager mUserManager;
+ private ArrayList<PackageInfo> mPrimaryUserPackages;
+ private ArrayList<PackageInfo> mProfileUserPackages;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest();
+ mFragment = new TurnScreenOnSettings(mPackageManager, mUserManager);
+ mPrimaryUserPackages = new ArrayList<>();
+ mProfileUserPackages = new ArrayList<>();
+ when(mPackageManager.getInstalledPackagesAsUser(anyInt(), eq(PRIMARY_USER_ID)))
+ .thenReturn(mPrimaryUserPackages);
+ when(mPackageManager.getInstalledPackagesAsUser(anyInt(), eq(PROFILE_USER_ID)))
+ .thenReturn(mProfileUserPackages);
+
+ UserInfo primaryUserInfo = new UserInfo();
+ primaryUserInfo.id = PRIMARY_USER_ID;
+ UserInfo profileUserInfo = new UserInfo();
+ profileUserInfo.id = PROFILE_USER_ID;
+
+ when(mUserManager.getProfiles(PRIMARY_USER_ID))
+ .thenReturn(ImmutableList.of(primaryUserInfo, profileUserInfo));
+ }
+
+ @Test
+ public void testCollectTurnScreenOnApps_variousPackages_shouldReturnOnlyPackagesWithTurnScreenOnPermission() {
+ PackageInfo primaryP1 = createPackage("Calculator", true);
+ PackageInfo primaryP2 = createPackage("Clock", false);
+ PackageInfo profileP1 = createPackage("Browser", false);
+ PackageInfo profileP2 = createPackage("Files", true);
+ mPrimaryUserPackages.add(primaryP1);
+ mPrimaryUserPackages.add(primaryP2);
+ mProfileUserPackages.add(profileP1);
+ mProfileUserPackages.add(profileP2);
+
+ List<Pair<ApplicationInfo, Integer>> apps = mFragment.collectTurnScreenOnApps(
+ PRIMARY_USER_ID);
+
+ assertThat(containsPackages(apps, primaryP1, profileP2)).isTrue();
+ assertThat(containsPackages(apps, primaryP2, profileP1)).isFalse();
+ }
+
+ @Test
+ public void collectTurnScreenOnApps_noTurnScreenOnPackages_shouldReturnEmptyList() {
+ PackageInfo primaryP1 = createPackage("Calculator", false);
+ PackageInfo profileP1 = createPackage("Browser", false);
+ mPrimaryUserPackages.add(primaryP1);
+ mProfileUserPackages.add(profileP1);
+
+ List<Pair<ApplicationInfo, Integer>> apps = mFragment.collectTurnScreenOnApps(
+ PRIMARY_USER_ID);
+
+ assertThat(apps).isEmpty();
+ }
+
+ @Test
+ public void sort_multiplePackages_appsShouldBeOrderedByAppName() {
+ PackageInfo primaryP1 = createPackage("Android", true);
+ PackageInfo primaryP2 = createPackage("Boop", true);
+ PackageInfo primaryP3 = createPackage("Deck", true);
+ PackageInfo profileP1 = createPackage("Android", true);
+ PackageInfo profileP2 = createPackage("Cool", true);
+ PackageInfo profileP3 = createPackage("Fast", false);
+ mPrimaryUserPackages.add(primaryP1);
+ mPrimaryUserPackages.add(primaryP2);
+ mPrimaryUserPackages.add(primaryP3);
+ mProfileUserPackages.add(profileP1);
+ mProfileUserPackages.add(profileP2);
+ mProfileUserPackages.add(profileP3);
+ List<Pair<ApplicationInfo, Integer>> apps = mFragment.collectTurnScreenOnApps(
+ PRIMARY_USER_ID);
+
+ apps.sort(new TurnScreenOnSettings.AppComparator(null));
+
+ assertThat(isOrdered(apps, primaryP1, profileP1, primaryP2, profileP2, primaryP3)).isTrue();
+ }
+
+ @Test
+ public void hasTurnScreenOnPermission_ignoredPackages_shouldReturnFalse() {
+ boolean res = false;
+
+ for (String ignoredPackage : TurnScreenOnSettings.IGNORE_PACKAGE_LIST) {
+ res |= TurnScreenOnSettings.hasTurnScreenOnPermission(mPackageManager, ignoredPackage);
+ }
+
+ assertThat(res).isFalse();
+ }
+
+ private boolean containsPackages(List<Pair<ApplicationInfo, Integer>> apps,
+ PackageInfo... packages) {
+ for (PackageInfo aPackage : packages) {
+ boolean found = false;
+ for (Pair<ApplicationInfo, Integer> app : apps) {
+ if (app.first == aPackage.applicationInfo) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean isOrdered(List<Pair<ApplicationInfo, Integer>> apps, PackageInfo... packages) {
+ if (apps.size() != packages.length) {
+ return false;
+ }
+
+ for (int i = 0; i < packages.length; i++) {
+ if (packages[i].applicationInfo != apps.get(i).first) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private PackageInfo createPackage(String packageName, boolean hasTurnScreenOnPermission) {
+ PackageInfo pi = new PackageInfo();
+ when(mPackageManager.checkPermission(Manifest.permission.WAKE_LOCK,
+ packageName)).thenReturn(
+ hasTurnScreenOnPermission ? PackageManager.PERMISSION_GRANTED
+ : PackageManager.PERMISSION_DENIED);
+ pi.packageName = packageName;
+ pi.applicationInfo = new ApplicationInfo();
+ pi.applicationInfo.name = packageName;
+ return pi;
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java
index 2678aff..a1b844b 100644
--- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java
@@ -46,7 +46,6 @@
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -106,7 +105,6 @@
@Test
@Config(shadows = ShadowChooseLockGenericController.class)
- @Ignore
public void createActivity_withShowOptionsButtonExtra_buttonNotVisibleIfNoVisibleLockTypes() {
SetupChooseLockPassword activity = createSetupChooseLockPassword();
Button optionsButton = activity.findViewById(R.id.screen_lock_options);
@@ -206,7 +204,7 @@
@Implements(ChooseLockGenericController.class)
public static class ShadowChooseLockGenericController {
@Implementation
- protected List<ScreenLockType> getVisibleScreenLockTypes() {
+ protected List<ScreenLockType> getVisibleAndEnabledScreenLockTypes() {
return Collections.emptyList();
}
}
diff --git a/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
index cfc9f90..49c1551 100644
--- a/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/shortcut/CreateShortcutPreferenceControllerTest.java
@@ -36,6 +36,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
+import android.os.SystemProperties;
import com.android.settings.Settings;
import com.android.settings.testutils.shadow.ShadowConnectivityManager;
@@ -62,6 +63,8 @@
@Config(shadows = ShadowConnectivityManager.class)
public class CreateShortcutPreferenceControllerTest {
+ static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
+
@Mock
private ShortcutManager mShortcutManager;
@Mock
@@ -152,4 +155,36 @@
assertThat(info.get(0).activityInfo).isEqualTo(ri2.activityInfo);
assertThat(info.get(1).activityInfo).isEqualTo(ri1.activityInfo);
}
+
+ @Test
+ public void queryShortcuts_setSupportOneHandedMode_ShouldEnableShortcuts() {
+ SystemProperties.set(SUPPORT_ONE_HANDED_MODE, "true");
+
+ setupOneHandedModeActivityInfo();
+ final List<ResolveInfo> info = mController.queryShortcuts();
+
+ assertThat(info).hasSize(1);
+ }
+
+ @Test
+ public void queryShortcuts_setUnsupportOneHandedMode_ShouldDisableShortcuts() {
+ SystemProperties.set(SUPPORT_ONE_HANDED_MODE, "false");
+
+ setupOneHandedModeActivityInfo();
+ final List<ResolveInfo> info = mController.queryShortcuts();
+
+ assertThat(info).hasSize(0);
+ }
+
+ private void setupOneHandedModeActivityInfo() {
+ final ResolveInfo ri = new ResolveInfo();
+ ri.activityInfo = new ActivityInfo();
+ ri.activityInfo.name = Settings.OneHandedSettingsActivity.class.getSimpleName();
+ ri.activityInfo.applicationInfo = new ApplicationInfo();
+ ri.activityInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+
+ mPackageManager.setResolveInfosForIntent(
+ new Intent(CreateShortcutPreferenceController.SHORTCUT_PROBE),
+ Arrays.asList(ri));
+ }
}
diff --git a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
index 6b2c076..ccd2190 100644
--- a/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserDetailsSettingsTest.java
@@ -373,7 +373,7 @@
mFragment.initialize(mActivity, mArguments);
verify(mRemoveUserPref).setOnPreferenceClickListener(mFragment);
- verify(mRemoveUserPref).setTitle(R.string.user_exit_guest_title);
+ verify(mRemoveUserPref).setTitle(com.android.settingslib.R.string.guest_exit_guest);
verify(mFragment, never()).removePreference(KEY_REMOVE_USER);
}
diff --git a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
index 1376712..bb7dd75 100644
--- a/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/users/UserSettingsTest.java
@@ -354,7 +354,8 @@
mFragment.updateUserList();
verify(mAddUserPreference).setVisible(true);
- verify(mAddUserPreference).setSummary("You can add up to 4 users");
+ verify(mAddUserPreference).setSummary(
+ "You can\u2019t add any more users. Remove a user to add a new one.");
verify(mAddUserPreference).setEnabled(false);
verify(mAddUserPreference).setSelectable(true);
}
diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java
index fb20045..616cb0b 100644
--- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java
@@ -25,7 +25,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.Context;
import android.content.Intent;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
@@ -42,9 +41,12 @@
import com.android.wifitrackerlib.WifiPickerTracker;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -61,25 +63,26 @@
private static final String TEST_SSID = "testssid";
private static final String TEST_CAPABILITY = "wep";
- NetworkRequestDialogActivity mActivity;
+ @Rule
+ public MockitoRule mRule = MockitoJUnit.rule();
+ @Mock
WifiManager mWifiManager;
- Context mContext;
+ @Mock
+ NetworkRequestUserSelectionCallback mNetworkRequestUserSelectionCallback;
+
+ NetworkRequestDialogActivity mActivity;
+ List<ScanResult> mScanResults = new ArrayList<>();
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = spy(RuntimeEnvironment.application);
FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest();
when(fakeFeatureFactory.wifiTrackerLibProvider.createWifiPickerTracker(
any(), any(), any(), any(), any(), anyLong(), anyLong(), any()))
.thenReturn(mock(WifiPickerTracker.class));
+ mScanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY));
- NetworkRequestDialogActivity activity =
- Robolectric.setupActivity(NetworkRequestDialogActivity.class);
- mActivity = spy(activity);
-
- mWifiManager = mock(WifiManager.class);
- when(mActivity.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+ mActivity = spy(Robolectric.setupActivity(NetworkRequestDialogActivity.class));
+ when(mActivity.getSystemService(WifiManager.class)).thenReturn(mWifiManager);
}
@Test
@@ -169,10 +172,7 @@
public void specifiedSsid_onMatch_shouldShowDialogFragment() {
startSpecifiedActivity();
- final List<ScanResult> scanResults = new ArrayList<>();
- scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY));
-
- mActivity.onMatch(scanResults);
+ mActivity.onMatch(mScanResults);
assertThat(mActivity.mProgressDialog).isNull();
assertThat(mActivity.mDialogFragment).isNotNull();
@@ -193,9 +193,7 @@
public void onUserSelectionConnectFailure_shouldShowDialogFragment() {
WifiConfiguration wifiConfiguration = mock(WifiConfiguration.class);
startSpecifiedActivity();
- final List<ScanResult> scanResults = new ArrayList<>();
- scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY));
- mActivity.onMatch(scanResults);
+ mActivity.onMatch(mScanResults);
mActivity.onUserSelectionConnectFailure(wifiConfiguration);
@@ -205,13 +203,9 @@
@Test
public void onClickConnectButton_shouldShowProgressDialog() {
- NetworkRequestUserSelectionCallback networkRequestUserSelectionCallback = mock(
- NetworkRequestUserSelectionCallback.class);
startSpecifiedActivity();
- final List<ScanResult> scanResults = new ArrayList<>();
- scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY));
- mActivity.onMatch(scanResults);
- mActivity.onUserSelectionCallbackRegistration(networkRequestUserSelectionCallback);
+ mActivity.onMatch(mScanResults);
+ mActivity.onUserSelectionCallbackRegistration(mNetworkRequestUserSelectionCallback);
mActivity.onClickConnectButton();
@@ -222,9 +216,7 @@
@Test
public void onCancel_shouldCloseAllUI() {
startSpecifiedActivity();
- final List<ScanResult> scanResults = new ArrayList<>();
- scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY));
- mActivity.onMatch(scanResults);
+ mActivity.onMatch(mScanResults);
mActivity.onCancel();
@@ -240,4 +232,20 @@
verify(mActivity).finish();
}
+
+ @Test
+ public void onUserSelectionCallbackRegistration_dismissDialogsAndDialogIsNull_shouldNotCrash() {
+ mActivity.dismissDialogs();
+
+ mActivity.onUserSelectionCallbackRegistration(mNetworkRequestUserSelectionCallback);
+ }
+
+ @Test
+ public void onMatch_dismissDialogsAndDialogIsNull_shouldNotCrash() {
+ mActivity.mIsSpecifiedSsid = false;
+ mActivity.mShowingErrorDialog = false;
+ mActivity.dismissDialogs();
+
+ mActivity.onMatch(mScanResults);
+ }
}
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 6cd20fc..8391b8a 100644
--- a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java
@@ -39,15 +39,14 @@
@Mock
private IActivityManager mIActivityManager;
- private AddAppNetworksActivity mActivity;
+ private FakeAddAppNetworksActivity mActivity;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mActivity = Robolectric.buildActivity(AddAppNetworksActivity.class).create().get();
+ mActivity = Robolectric.buildActivity(FakeAddAppNetworksActivity.class).create().get();
mActivity.mActivityManager = mIActivityManager;
- mActivity.mIsAddWifiConfigAllow = true;
}
@Test
@@ -92,4 +91,13 @@
// Do nothing.
}
}
+
+ private static class FakeAddAppNetworksActivity extends AddAppNetworksActivity {
+ boolean mIsAddWifiConfigAllow = true;
+
+ @Override
+ boolean isAddWifiConfigAllow() {
+ return mIsAddWifiConfigAllow;
+ }
+ }
}
diff --git a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
index de0df73..3ad846d 100644
--- a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java
@@ -32,6 +32,8 @@
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
+import com.android.settingslib.qrcode.QrCodeGenerator;
+
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.RGBLuminanceSource;
diff --git a/tests/unit/src/com/android/settings/development/MockModemPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/MockModemPreferenceControllerTest.java
new file mode 100644
index 0000000..f811ac4
--- /dev/null
+++ b/tests/unit/src/com/android/settings/development/MockModemPreferenceControllerTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.development;
+
+import static com.android.settings.development.MockModemPreferenceController
+ .ALLOW_MOCK_MODEM_PROPERTY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.SystemProperties;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class MockModemPreferenceControllerTest {
+
+ private Context mContext;
+ private MockModemPreferenceController mController;
+ private SwitchPreference mPreference;
+
+ @Before
+ public void setUp() {
+ mContext = ApplicationProvider.getApplicationContext();
+ mController = new MockModemPreferenceController(mContext);
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ final PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
+ mPreference = new SwitchPreference(mContext);
+ mPreference.setKey(mController.getPreferenceKey());
+ screen.addPreference(mPreference);
+ mController.displayPreference(screen);
+ }
+
+ @Test
+ public void onPreferenceChanged_settingDisabled_shouldNotAllowedMockModem() {
+ mController.onPreferenceChange(mPreference, false /* new value */);
+
+ final boolean mode = SystemProperties.getBoolean(
+ ALLOW_MOCK_MODEM_PROPERTY, false /* default */);
+
+ assertThat(mode).isFalse();
+ }
+
+ @Test
+ public void onPreferenceChanged_settingEnabled_shouldAllowMockModem() {
+ mController.onPreferenceChange(mPreference, true /* new value */);
+
+ final boolean mode = SystemProperties.getBoolean(
+ ALLOW_MOCK_MODEM_PROPERTY, false /* default */);
+
+ assertThat(mode).isTrue();
+ }
+
+ @Test
+ public void updateState_settingEnabled_preferenceShouldBeChecked() {
+ SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY,
+ Boolean.toString(true));
+
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isTrue();
+ }
+
+ @Test
+ public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
+ SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY,
+ Boolean.toString(false));
+
+ mController.updateState(mPreference);
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+
+ @Test
+ public void onDeveloperOptionsDisabled_shouldDisablePreference() {
+ mController.onDeveloperOptionsSwitchDisabled();
+ final boolean mode = SystemProperties.getBoolean(
+ ALLOW_MOCK_MODEM_PROPERTY,
+ false /* default */);
+
+ mController.updateState(mPreference);
+
+ assertThat(mode).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java b/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java
index 03d2d5a..556ec5f 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/PublicVolumeSettingsTest.java
@@ -26,6 +26,7 @@
import com.android.settings.Settings;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,6 +39,7 @@
new ActivityTestRule<>(Settings.PublicVolumeSettingsActivity.class, true, true);
@Test
+ @Ignore
public void test_invalidSetupDoesNotCrashSettings() {
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
diff --git a/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java b/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
index 7ecbafc..53f4e7c 100644
--- a/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
+++ b/tests/unit/src/com/android/settings/safetycenter/LockScreenSafetySourceTest.java
@@ -384,7 +384,7 @@
whenScreenLockIsEnabled();
when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
final Intent launchScreenLockSettings = new Intent(FAKE_ACTION_SCREEN_LOCK_SETTINGS);
- when(mScreenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent())
+ when(mScreenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent(anyInt()))
.thenReturn(launchScreenLockSettings);
when(mScreenLockPreferenceDetailsUtils.shouldShowGearMenu()).thenReturn(true);
@@ -450,7 +450,7 @@
Intent launchChooseLockGenericFragment = new Intent(
FAKE_ACTION_CHOOSE_LOCK_GENERIC_FRAGMENT);
- when(mScreenLockPreferenceDetailsUtils.getLaunchChooseLockGenericFragmentIntent())
+ when(mScreenLockPreferenceDetailsUtils.getLaunchChooseLockGenericFragmentIntent(anyInt()))
.thenReturn(launchChooseLockGenericFragment);
}
}
diff --git a/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java b/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java
index f471128..ad88687 100644
--- a/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java
+++ b/tests/unit/src/com/android/settings/security/ScreenLockPreferenceDetailsUtilsTest.java
@@ -91,8 +91,7 @@
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
.thenReturn(mLockPatternUtils);
- mScreenLockPreferenceDetailsUtils =
- new ScreenLockPreferenceDetailsUtils(mContext, SOURCE_METRICS_CATEGORY);
+ mScreenLockPreferenceDetailsUtils = new ScreenLockPreferenceDetailsUtils(mContext);
}
@Test
@@ -283,14 +282,15 @@
@Test
public void openScreenLockSettings_shouldSendIntent() {
- mScreenLockPreferenceDetailsUtils.openScreenLockSettings();
+ mScreenLockPreferenceDetailsUtils.openScreenLockSettings(SOURCE_METRICS_CATEGORY);
assertFragmentLaunchRequested(ScreenLockSettings.class.getName());
}
@Test
public void getLaunchScreenLockSettingsIntent_returnsIntent() {
- final Intent intent = mScreenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent();
+ final Intent intent = mScreenLockPreferenceDetailsUtils.getLaunchScreenLockSettingsIntent(
+ SOURCE_METRICS_CATEGORY);
assertFragmentLaunchIntent(intent, ScreenLockSettings.class.getName());
}
@@ -299,7 +299,8 @@
public void openChooseLockGenericFragment_noQuietMode_shouldSendIntent_shouldReturnTrue() {
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
- assertThat(mScreenLockPreferenceDetailsUtils.openChooseLockGenericFragment()).isTrue();
+ assertThat(mScreenLockPreferenceDetailsUtils
+ .openChooseLockGenericFragment(SOURCE_METRICS_CATEGORY)).isTrue();
assertFragmentLaunchRequested(ChooseLockGeneric.ChooseLockGenericFragment.class.getName());
}
@@ -307,8 +308,8 @@
public void getLaunchChooseLockGenericFragmentIntent_noQuietMode_returnsIntent() {
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
- final Intent intent =
- mScreenLockPreferenceDetailsUtils.getLaunchChooseLockGenericFragmentIntent();
+ final Intent intent = mScreenLockPreferenceDetailsUtils
+ .getLaunchChooseLockGenericFragmentIntent(SOURCE_METRICS_CATEGORY);
assertFragmentLaunchIntent(intent,
ChooseLockGeneric.ChooseLockGenericFragment.class.getName());