Merge "Add generateChallenge() in onResume()" into qt-r1-dev
diff --git a/res/drawable/ic_notifications_alert.xml b/res/drawable/ic_notifications_alert.xml
new file mode 100644
index 0000000..5a25459
--- /dev/null
+++ b/res/drawable/ic_notifications_alert.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18 17v-6c0-3.07-1.63-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5s-1.5 0.67 -1.5 1.5v0.68C7.64 5.36 6 7.92 6 11v6H4v2h16v-2h-2zm-2 0H8v-6c0-2.48 1.51-4.5 4-4.5s4 2.02 4 4.5v6zm-6 3h4c0 1.1-0.9 2-2 2s-2-0.9-2-2zm12-9h-2c0-2.74-1.23-5.19-3.16-6.84l1.41-1.41C20.54 4.77 22 7.71 22 11zM5.75 2.75l1.41 1.41C5.23 5.81 4 8.26 4 11H2c0-3.29 1.46-6.23 3.75-8.25z" />
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_settings_adaptive_sleep.xml b/res/drawable/ic_settings_adaptive_sleep.xml
new file mode 100644
index 0000000..765ed94
--- /dev/null
+++ b/res/drawable/ic_settings_adaptive_sleep.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M10.67,21H7v-1h3.13c-0.27-0.63-0.46-1.3-0.56-2H7V6h10v3.5c0.69,0,1.36,0.1,2,0.28V3 c0-1.1-0.9-1.99-2-1.99L7,1C5.9,1,5,1.9,5,3v18c0,1.1,0.9,2,2,2h5.52C11.79,22.45,11.16,21.77,10.67,21z M7,3h10v1H7V3z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M17,12.5c2.48,0,4.5,2.02,4.5,4.5s-2.02,4.5-4.5,4.5s-4.5-2.02-4.5-4.5S14.52,12.5,17,12.5 M17,11 c-3.31,0-6,2.69-6,6s2.69,6,6,6c3.31,0,6-2.69,6-6S20.31,11,17,11L17,11z" />
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M17,14v3l-2.12,2.12C15.42,19.66,16.17,20,17,20c1.66,0,3-1.34,3-3S18.66,14,17,14z" />
+</vector>
\ No newline at end of file
diff --git a/res/layout/dialog_mobile_network_color_picker_item.xml b/res/layout/dialog_mobile_network_color_picker_item.xml
new file mode 100644
index 0000000..b6f4092
--- /dev/null
+++ b/res/layout/dialog_mobile_network_color_picker_item.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:background="?android:attr/selectableItemBackground" >
+
+ <ImageView
+ android:id="@+id/color_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/sim_label_padding"
+ android:layout_gravity="center_vertical" />
+
+ <TextView
+ android:id="@+id/color_label"
+ android:gravity="center_vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:paddingBottom="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_mobile_network_rename.xml b/res/layout/dialog_mobile_network_rename.xml
index d67f0dc..921ab86 100644
--- a/res/layout/dialog_mobile_network_rename.xml
+++ b/res/layout/dialog_mobile_network_rename.xml
@@ -21,44 +21,89 @@
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="@dimen/sim_content_padding">
+ android:layout_height="wrap_content">
- <EditText
- android:id="@+id/edittext"
+ <LinearLayout
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:inputType="text"
- android:maxLength="50"
- android:singleLine="true">
- <requestFocus/>
- </EditText>
+ android:paddingEnd="@dimen/sim_content_padding"
+ android:paddingStart="@dimen/sim_content_padding">
- <TextView
- style="@style/device_info_dialog_label"
- android:id="@+id/operator_name_label"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/status_operator"/>
- <TextView
- style="@style/device_info_dialog_value"
- android:id="@+id/operator_name_value"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/device_info_not_available"/>
+ <TextView
+ android:id="@+id/name_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/mobile_network_sim_name_label"/>
- <TextView
- style="@style/device_info_dialog_label"
- android:id="@+id/number_label"
+ <EditText
+ android:id="@+id/name_edittext"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="text"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:maxLength="50"
+ android:singleLine="true"/>
+
+ <TextView
+ android:id="@+id/color_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/mobile_network_sim_color_label"/>
+
+ </LinearLayout>
+
+ <Spinner
+ android:id="@+id/color_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/status_number_sim_status"/>
- <TextView
- style="@style/device_info_dialog_value"
- android:id="@+id/number_value"
+ android:layout_marginStart="@dimen/sim_color_spinner_padding"
+ android:layout_marginEnd="@dimen/sim_color_spinner_padding"/>
+
+ <LinearLayout
+ android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/device_info_not_available"/>
+ android:paddingEnd="@dimen/sim_content_padding"
+ android:paddingStart="@dimen/sim_content_padding">
+
+ <TextView
+ android:id="@+id/operator_name_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/status_operator"/>
+
+ <TextView
+ android:id="@+id/operator_name_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ android:id="@+id/number_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/sim_label_padding"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+ android:textColor="?android:attr/textColorPrimary"
+ android:text="@string/status_number_sim_status"/>
+
+ <TextView
+ android:id="@+id/number_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ </LinearLayout>
</LinearLayout>
</ScrollView>
diff --git a/res/layout/notif_importance_preference.xml b/res/layout/notif_importance_preference.xml
index 2fc2740..29c337a 100644
--- a/res/layout/notif_importance_preference.xml
+++ b/res/layout/notif_importance_preference.xml
@@ -24,7 +24,7 @@
android:padding="@dimen/notification_importance_toggle_marginTop"
android:orientation="vertical">
- <RelativeLayout
+ <com.android.settings.notification.NotificationButtonRelativeLayout
android:id="@+id/alert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -33,7 +33,7 @@
android:focusable="true">
<ImageView
android:id="@+id/alert_icon"
- android:src="@drawable/ic_notifications"
+ android:src="@drawable/ic_notifications_alert"
android:background="@android:color/transparent"
android:layout_gravity="center"
android:layout_width="wrap_content"
@@ -65,7 +65,7 @@
android:layout_below="@id/alert_icon"
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"
android:visibility="gone" />
- </RelativeLayout>
+ </com.android.settings.notification.NotificationButtonRelativeLayout>
<RelativeLayout
android:id="@+id/silence"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 09ab682..fbf1a24 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -166,6 +166,7 @@
<dimen name="sim_dialog_margin_bottom">16dip</dimen>
<!-- SIM Dialog padding -->
<dimen name="sim_dialog_padding">8dip</dimen>
+ <dimen name="sim_color_spinner_padding">12dip</dimen>
<dimen name="sim_label_padding">16dip</dimen>
<dimen name="sim_content_padding">24dip</dimen>
<!-- Sim Card Name length -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index edc62c5..3390831 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -885,7 +885,7 @@
<!-- Message shown in summary field when face unlock is set up. [CHAR LIMIT=40] -->
<string name="security_settings_face_preference_summary">Face added</string>
<!-- Message shown in summary field when face unlock is not set up. [CHAR LIMIT=54] -->
- <string name="security_settings_face_preference_summary_none">Tap to set up face unlock</string>
+ <string name="security_settings_face_preference_summary_none">Set up face unlock</string>
<!-- Title shown for menu item that launches face settings or enrollment. [CHAR LIMIT=32] -->
<string name="security_settings_face_preference_title">Face unlock</string>
<!-- Introduction title shown in face enrollment education screen [CHAR LIMIT=40] -->
@@ -955,25 +955,25 @@
<!-- Text shown on a toggle which allows or disallows the device to use face unlock for apps. This will be presented to the user together with the context of security_settings_face_settings_use_face_category. [CHAR LIMIT=30] -->
<string name="security_settings_face_settings_use_face_for_apps">App sign-in \u0026 payments</string>
<!-- Title for a category shown for the face settings page, followed by items that the user can toggle on/off to require/disable. -->
- <string name="security_settings_face_settings_require_category">Require for face unlock</string>
+ <string name="security_settings_face_settings_require_category">Requirements for face unlock</string>
<!-- Text shown on a toggle which disables/enables face unlock, depending if the user's eyes are open. [CHAR LIMIT=30] -->
- <string name="security_settings_face_settings_require_attention">Open eyes looking at screen</string>
+ <string name="security_settings_face_settings_require_attention">Require eyes to be open</string>
<!-- Text shown on the details of a toggle which disables/enables face unlock, depending if the user's eyes are open. [CHAR LIMIT=70] -->
- <string name="security_settings_face_settings_require_attention_details">To unlock the phone, always require looking at the screen with your eyes open</string>
+ <string name="security_settings_face_settings_require_attention_details">To unlock the phone, your eyes must be open</string>
<!-- When authenticating in apps, always require confirmation (e.g. confirm button) after a face is authenticated. [CHAR LIMIT=50] -->
- <string name="security_settings_face_settings_require_confirmation">Confirm button</string>
+ <string name="security_settings_face_settings_require_confirmation">Always require confirmation</string>
<!-- When authenticating in apps, always require confirmation (e.g. confirm button) after a face is authenticated. [CHAR LIMIT=70] -->
- <string name="security_settings_face_settings_require_confirmation_details">When authenticating for apps, always require confirmation</string>
+ <string name="security_settings_face_settings_require_confirmation_details">When using face unlock in apps, always require confirmation step</string>
<!-- Button text in face settings which removes the user's faces from the device [CHAR LIMIT=20] -->
<string name="security_settings_face_settings_remove_face_data">Delete face data</string>
<!-- Button text in face settings which lets the user enroll their face [CHAR LIMIT=40] -->
- <string name="security_settings_face_settings_enroll">Set up new face unlock</string>
+ <string name="security_settings_face_settings_enroll">Set up face unlock</string>
<!-- Text shown in face settings explaining what your face can be used for. [CHAR LIMIT=NONE] -->
<string name="security_settings_face_settings_footer">Use face unlock to unlock your device, sign in to apps, and confirm payments.\n\nKeep in mind:\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face while your eyes are open.\n\nYour phone can be unlocked by someone who looks a lot like you, say, an identical sibling.</string>
<!-- Dialog title shown when the user removes an enrollment [CHAR LIMIT=35] -->
<string name="security_settings_face_settings_remove_dialog_title">Delete face data?</string>
<!-- Dialog contents shown when the user removes an enrollment [CHAR LIMIT=NONE] -->
- <string name="security_settings_face_settings_remove_dialog_details">Data recorded by face unlock will be permanently and securely deleted. After removal, you will need your PIN, pattern, or password to unlock your phone, sign in to apps, and confirm payments.</string>
+ <string name="security_settings_face_settings_remove_dialog_details">The images and biometric data used by face unlock will be permanently and securely deleted. After removal, you will need your PIN, pattern, or password to unlock your phone, sign in to apps, and confirm payments.</string>
<!-- Fingerprint enrollment and settings --><skip />
@@ -1075,11 +1075,11 @@
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set fingerprint. (default) [CHAR LIMIT=NONE] -->
<string name="fingerprint_lock_screen_setup_skip_dialog_text" product="default">Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN, pattern, or password.</string>
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set face unlock. (tablet) [CHAR LIMIT=NONE] -->
- <string name="face_lock_screen_setup_skip_dialog_text" product="tablet">Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. Tap Cancel, then set a PIN, pattern, or password.</string>
+ <string name="face_lock_screen_setup_skip_dialog_text" product="tablet">By protecting your tablet with a screen lock option, no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. To go back, tap Cancel. </string>
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set face unlock. (device) [CHAR LIMIT=NONE] -->
- <string name="face_lock_screen_setup_skip_dialog_text" product="device">Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. Tap Cancel, then set a PIN, pattern, or password.</string>
+ <string name="face_lock_screen_setup_skip_dialog_text" product="device">By protecting your device with a screen lock option, no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. To go back, tap Cancel. </string>
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set face unlock. (default) [CHAR LIMIT=NONE] -->
- <string name="face_lock_screen_setup_skip_dialog_text" product="default">Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. Tap Cancel, then set a PIN, pattern, or password.</string>
+ <string name="face_lock_screen_setup_skip_dialog_text" product="default">By protecting your phone with a screen lock option, no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face unlock. To go back, tap Cancel.</string>
<!-- Title of dialog shown when the user tries to skip setting up a PIN, warning them of potential consequences of not doing so [CHAR LIMIT=48]-->
<string name="lock_screen_pin_skip_title">Skip PIN setup?</string>
<!-- Title of dialog shown when the user tries to skip setting up a password, warning them of potential consequences of not doing so [CHAR LIMIT=48]-->
@@ -2833,7 +2833,7 @@
<!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] -->
<string name="adaptive_sleep_summary_off">Off</string>
<!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]-->
- <string name="adaptive_sleep_description">Prevents your screen from turning off if you’re looking at it.</string>
+ <string name="adaptive_sleep_description">Keep screen on when viewing it</string>
<!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]-->
<string name="adaptive_sleep_privacy">Screen attention uses the front camera to see if someone is looking at the screen. It works on device, and images are never stored or sent to Google.</string>
@@ -10208,7 +10208,7 @@
<!-- Message for the alert dialog which says that the current default home app does not support gesture navigation. [CHAR LIMIT=NONE] -->
<string name="gesture_not_supported_dialog_message">Not supported by your default home app, <xliff:g id="default_home_app" example="Pixel Launcher">%s</xliff:g></string>
- <!-- Positive button for the alert dialog when gesture nav not supported by launcher [CHAR LIMIT=40] -->
+ <!-- Positive button for the alert dialog when gesture nav not supported by launcher [CHAR LIMIT=60] -->
<string name="gesture_not_supported_positive_button">Switch default home app</string>
<!-- Content description for the Information icon [CHAR LIMIT=30] -->
@@ -10961,10 +10961,14 @@
subscription in various places in the Settings app. The default name is typically just the
carrier name, but especially in multi-SIM configurations users may want to use a different
name. [CHAR LIMIT=40] -->
- <string name="mobile_network_sim_name">SIM name</string>
- <!-- Label on the confirmation button of a dialog that lets a user set the display name of a
- mobile network subscription [CHAR LIMIT=20] -->
- <string name="mobile_network_sim_name_rename">Rename</string>
+ <string name="mobile_network_sim_name">SIM name & color</string>
+ <!-- Label for an item listing the name of the SIM that the user has specified. [CHAR LIMIT=40] -->
+ <string name="mobile_network_sim_name_label">Name</string>
+ <!-- Label for an item listing the color of the SIM that the user has specified. [CHAR LIMIT=40] -->
+ <string name="mobile_network_sim_color_label">Color (used by compatible apps)</string>
+ <!-- Label on the confirmation button of a dialog that lets a user set the display name and
+ color of a mobile network subscription [CHAR LIMIT=20] -->
+ <string name="mobile_network_sim_name_rename">Save</string>
<!-- Label for the on position of a switch on the mobile network details page which allows
disabling/enabling a SIM. The SIM is enabled in this state. [CHAR LIMIT=40] -->
<string name="mobile_network_use_sim_on">Use SIM</string>
diff --git a/src/com/android/settings/FallbackHome.java b/src/com/android/settings/FallbackHome.java
index 59347ad..e3944a6 100644
--- a/src/com/android/settings/FallbackHome.java
+++ b/src/com/android/settings/FallbackHome.java
@@ -25,6 +25,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ResolveInfo;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -65,7 +66,7 @@
@Override
public void onColorsChanged(WallpaperColors colors, int which) {
if (colors != null) {
- View decorView = getWindow().getDecorView();
+ final View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
updateVisibilityFlagsFromColors(colors, decorView.getSystemUiVisibility()));
mWallManager.removeOnColorsChangedListener(this);
@@ -81,7 +82,7 @@
// we don't flash the wallpaper before SUW
mProvisioned = Settings.Global.getInt(getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
- int flags;
+ final int flags;
if (!mProvisioned) {
setTheme(R.style.FallbackHome_SetupWizard);
flags = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
@@ -91,18 +92,11 @@
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
- // Set the system ui flags to light status bar if the wallpaper supports dark text to match
- // current system ui color tints. Use a listener to wait for colors if not ready yet.
mWallManager = getSystemService(WallpaperManager.class);
if (mWallManager == null) {
Log.w(TAG, "Wallpaper manager isn't ready, can't listen to color changes!");
} else {
- WallpaperColors colors = mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
- if (colors == null) {
- mWallManager.addOnColorsChangedListener(mColorsChangedListener, null /* handler */);
- } else {
- flags = updateVisibilityFlagsFromColors(colors, flags);
- }
+ loadWallpaperColors(flags);
}
getWindow().getDecorView().setSystemUiVisibility(flags);
@@ -139,6 +133,33 @@
}
};
+ private void loadWallpaperColors(int flags) {
+ final AsyncTask loadWallpaperColorsTask = new AsyncTask<Object, Void, Integer>() {
+ @Override
+ protected Integer doInBackground(Object... params) {
+ final WallpaperColors colors =
+ mWallManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+
+ // Use a listener to wait for colors if not ready yet.
+ if (colors == null) {
+ mWallManager.addOnColorsChangedListener(mColorsChangedListener,
+ null /* handler */);
+ return null;
+ }
+ return updateVisibilityFlagsFromColors(colors, flags);
+ }
+
+ @Override
+ protected void onPostExecute(Integer flagsToUpdate) {
+ if (flagsToUpdate == null) {
+ return;
+ }
+ getWindow().getDecorView().setSystemUiVisibility(flagsToUpdate);
+ }
+ };
+ loadWallpaperColorsTask.execute();
+ }
+
private void maybeFinish() {
if (getSystemService(UserManager.class).isUserUnlocked()) {
final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
@@ -162,6 +183,8 @@
}
}
+ // Set the system ui flags to light status bar if the wallpaper supports dark text to match
+ // current system ui color tints.
private int updateVisibilityFlagsFromColors(WallpaperColors colors, int flags) {
if ((colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0) {
return flags | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
index d532a76..1c1b81d 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -64,7 +64,7 @@
builder.setTitle(R.string.security_settings_face_settings_remove_dialog_title)
.setMessage(R.string.security_settings_face_settings_remove_dialog_details)
- .setPositiveButton(R.string.okay, mOnClickListener)
+ .setPositiveButton(R.string.delete, mOnClickListener)
.setNegativeButton(R.string.cancel, mOnClickListener);
AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
diff --git a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
index 6b91792..e83410d 100644
--- a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
+++ b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java
@@ -25,9 +25,9 @@
public class AdaptiveSleepPreferenceController extends TogglePreferenceController {
-
- private final String SYSTEM_KEY = ADAPTIVE_SLEEP;
- private final int DEFAULT_VALUE = 0;
+ public static final String PREF_NAME = "adaptive_sleep";
+ private static final String SYSTEM_KEY = ADAPTIVE_SLEEP;
+ private static final int DEFAULT_VALUE = 0;
final boolean hasSufficientPermissions;
@@ -35,9 +35,7 @@
super(context, key);
final PackageManager packageManager = mContext.getPackageManager();
- final String attentionPackage = packageManager.getAttentionServicePackageName();
- hasSufficientPermissions = attentionPackage != null && packageManager.checkPermission(
- Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
+ hasSufficientPermissions = hasSufficientPermission(packageManager);
}
@Override
@@ -46,7 +44,6 @@
SYSTEM_KEY, DEFAULT_VALUE) != DEFAULT_VALUE;
}
-
@Override
public boolean setChecked(boolean isChecked) {
Settings.System.putInt(mContext.getContentResolver(), SYSTEM_KEY,
@@ -57,10 +54,7 @@
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {
- return mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_adaptive_sleep_available)
- ? AVAILABLE_UNSEARCHABLE
- : UNSUPPORTED_ON_DEVICE;
+ return isControllerAvailable(mContext);
}
@Override
@@ -69,4 +63,17 @@
? R.string.adaptive_sleep_summary_on
: R.string.adaptive_sleep_summary_off);
}
+
+ public static int isControllerAvailable(Context context) {
+ return context.getResources().getBoolean(
+ com.android.internal.R.bool.config_adaptive_sleep_available)
+ ? AVAILABLE_UNSEARCHABLE
+ : UNSUPPORTED_ON_DEVICE;
+ }
+
+ private static boolean hasSufficientPermission(PackageManager packageManager) {
+ final String attentionPackage = packageManager.getAttentionServicePackageName();
+ return attentionPackage != null && packageManager.checkPermission(
+ Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
+ }
}
diff --git a/src/com/android/settings/display/AdaptiveSleepSettings.java b/src/com/android/settings/display/AdaptiveSleepSettings.java
index 4c17a67..d0f2c9a 100644
--- a/src/com/android/settings/display/AdaptiveSleepSettings.java
+++ b/src/com/android/settings/display/AdaptiveSleepSettings.java
@@ -16,10 +16,15 @@
package com.android.settings.display;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_INTERACTED;
+
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
+import android.util.Log;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
@@ -40,8 +45,15 @@
super.onCreate(icicle);
final FooterPreference footerPreference =
mFooterPreferenceMixin.createFooterPreference();
+ final Context context = getContext();
+
footerPreference.setIcon(R.drawable.ic_privacy_shield_24dp);
footerPreference.setTitle(R.string.adaptive_sleep_privacy);
+
+ context.getSharedPreferences(PREF, Context.MODE_PRIVATE)
+ .edit()
+ .putBoolean(PREF_KEY_INTERACTED, true)
+ .apply();
}
@Override
diff --git a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
index 86fee03..aaae076 100644
--- a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
+++ b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java
@@ -64,12 +64,21 @@
.setCardName(contextualNotificationChannelSliceUri)
.setCardCategory(ContextualCard.Category.POSSIBLE)
.build();
+ final String contextualAdaptiveSleepSliceUri =
+ CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI.toString();
+ final ContextualCard contextualAdaptiveSleepCard =
+ ContextualCard.newBuilder()
+ .setSliceUri(contextualAdaptiveSleepSliceUri)
+ .setCardName(contextualAdaptiveSleepSliceUri)
+ .setCardCategory(ContextualCard.Category.DEFAULT)
+ .build();
final ContextualCardList cards = ContextualCardList.newBuilder()
.addCard(wifiCard)
.addCard(connectedDeviceCard)
.addCard(lowStorageCard)
.addCard(batteryFixCard)
.addCard(notificationChannelCard)
+ .addCard(contextualAdaptiveSleepCard)
.build();
return cards;
diff --git a/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java b/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java
new file mode 100644
index 0000000..2c091fa
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSlice.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.homepage.contextualcards.slices;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.display.AdaptiveSleepPreferenceController.PREF_NAME;
+import static com.android.settings.display.AdaptiveSleepPreferenceController.isControllerAvailable;
+import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI;
+
+import android.app.PendingIntent;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+
+import androidx.core.graphics.drawable.IconCompat;
+import androidx.slice.Slice;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.SliceAction;
+
+import com.android.settings.R;
+import com.android.settings.SubSettings;
+import com.android.settings.display.AdaptiveSleepSettings;
+import com.android.settings.slices.CustomSliceable;
+import com.android.settings.slices.SliceBuilderUtils;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import java.util.concurrent.TimeUnit;
+
+public class ContextualAdaptiveSleepSlice implements CustomSliceable {
+ private static final String TAG = "ContextualAdaptiveSleepSlice";
+ private static final long DEFAULT_SETUP_TIME = 0;
+ private Context mContext;
+
+ @VisibleForTesting
+ static final long DEFERRED_TIME_DAYS = TimeUnit.DAYS.toMillis(14);
+ @VisibleForTesting
+ static final String PREF_KEY_SETUP_TIME = "adaptive_sleep_setup_time";
+
+ public static final String PREF_KEY_INTERACTED = "adaptive_sleep_interacted";
+ public static final String PREF = "adaptive_sleep_slice";
+
+ public ContextualAdaptiveSleepSlice(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Slice getSlice() {
+ final long setupTime = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getLong(
+ PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
+ if (setupTime == DEFAULT_SETUP_TIME) {
+ // Set the first setup time.
+ mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE)
+ .edit()
+ .putLong(PREF_KEY_SETUP_TIME, System.currentTimeMillis())
+ .apply();
+ return null;
+ }
+
+ // Display the contextual card only if all the following 3 conditions hold:
+ // 1. The Screen Attention is enabled in Settings.
+ // 2. The device is not recently set up.
+ // 3. Current user hasn't opened Screen Attention's settings page before.
+ if (isSettingsAvailable() && !isUserInteracted() && !isRecentlySetup()) {
+ final IconCompat icon = IconCompat.createWithResource(mContext,
+ R.drawable.ic_settings_adaptive_sleep);
+ final CharSequence title = mContext.getText(R.string.adaptive_sleep_title);
+ final CharSequence subtitle = mContext.getText(R.string.adaptive_sleep_description);
+
+ final SliceAction pAction = SliceAction.createDeeplink(getPrimaryAction(),
+ icon,
+ ListBuilder.ICON_IMAGE,
+ title);
+ final ListBuilder listBuilder = new ListBuilder(mContext,
+ CONTEXTUAL_ADAPTIVE_SLEEP_URI,
+ ListBuilder.INFINITY)
+ .addRow(new ListBuilder.RowBuilder()
+ .setTitleItem(icon, ListBuilder.ICON_IMAGE)
+ .setTitle(title)
+ .setSubtitle(subtitle)
+ .setPrimaryAction(pAction));
+ return listBuilder.build();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Uri getUri() {
+ return CONTEXTUAL_ADAPTIVE_SLEEP_URI;
+ }
+
+ @Override
+ public Intent getIntent() {
+ final CharSequence screenTitle = mContext.getText(R.string.adaptive_sleep_title);
+ final Uri contentUri = new Uri.Builder().appendPath(PREF_NAME).build();
+ return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
+ AdaptiveSleepSettings.class.getName(), PREF_NAME, screenTitle.toString(),
+ SettingsEnums.SLICE).setClassName(mContext.getPackageName(),
+ SubSettings.class.getName()).setData(contentUri);
+ }
+
+ private PendingIntent getPrimaryAction() {
+ final Intent intent = getIntent();
+ return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent, 0 /* flags */);
+ }
+
+ /**
+ * @return {@code true} if the current user has opened the Screen Attention settings page
+ * before, otherwise {@code false}.
+ */
+ private boolean isUserInteracted() {
+ return mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE).getBoolean(
+ PREF_KEY_INTERACTED, false);
+ }
+
+ /**
+ * The device is recently set up means its first settings-open time is within 2 weeks ago.
+ *
+ * @return {@code true} if the device is recently set up, otherwise {@code false}.
+ */
+ private boolean isRecentlySetup() {
+ final long endTime = System.currentTimeMillis() - DEFERRED_TIME_DAYS;
+ final long firstSetupTime = mContext.getSharedPreferences(PREF,
+ Context.MODE_PRIVATE).getLong(PREF_KEY_SETUP_TIME, DEFAULT_SETUP_TIME);
+ return firstSetupTime > endTime;
+ }
+
+ /**
+ * Check whether the screen attention settings is enabled. Contextual card will only appear
+ * when the screen attention settings is available.
+ *
+ * @return {@code true} if screen attention settings is enabled, otherwise {@code false}
+ */
+ @VisibleForTesting
+ boolean isSettingsAvailable() {
+ return isControllerAvailable(mContext) == AVAILABLE;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
index 82554c2..a28fc91 100644
--- a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
+++ b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
@@ -19,6 +19,10 @@
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Paint;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
@@ -30,7 +34,12 @@
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Spinner;
import android.widget.TextView;
import com.android.settings.R;
@@ -42,9 +51,12 @@
import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
-/** A dialog allowing the display name of a mobile network subscription to be changed */
+/**
+ * A dialog allowing the display name of a mobile network subscription to be changed
+ */
public class RenameMobileNetworkDialogFragment extends InstrumentedDialogFragment {
- public static final String TAG ="RenameMobileNetwork";
+
+ public static final String TAG = "RenameMobileNetwork";
private static final String KEY_SUBSCRIPTION_ID = "subscription_id";
@@ -52,6 +64,8 @@
private SubscriptionManager mSubscriptionManager;
private int mSubId;
private EditText mNameView;
+ private Spinner mColorSpinner;
+ private Color[] mColors;
public static RenameMobileNetworkDialogFragment newInstance(int subscriptionId) {
final Bundle args = new Bundle(1);
@@ -76,6 +90,11 @@
return mNameView;
}
+ @VisibleForTesting
+ protected Spinner getColorSpinnerView() {
+ return mColorSpinner;
+ }
+
@Override
public void onAttach(Context context) {
super.onAttach(context);
@@ -87,6 +106,8 @@
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ mColors = getColors();
+
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
final LayoutInflater layoutInflater = builder.getContext().getSystemService(
LayoutInflater.class);
@@ -95,9 +116,11 @@
builder.setTitle(R.string.mobile_network_sim_name)
.setView(view)
.setPositiveButton(R.string.mobile_network_sim_name_rename, (dialog, which) -> {
- String newName = mNameView.getText().toString();
- mSubscriptionManager.setDisplayName(newName, mSubId,
+ mSubscriptionManager.setDisplayName(mNameView.getText().toString(), mSubId,
SubscriptionManager.NAME_SOURCE_USER_INPUT);
+ mSubscriptionManager.setIconTint(
+ mColors[mColorSpinner.getSelectedItemPosition()].getColor(),
+ mSubId);
})
.setNegativeButton(android.R.string.cancel, null);
return builder.create();
@@ -105,7 +128,7 @@
@VisibleForTesting
protected void populateView(View view) {
- mNameView = view.findViewById(R.id.edittext);
+ mNameView = view.findViewById(R.id.name_edittext);
final SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
if (info == null) {
Log.w(TAG, "got null SubscriptionInfo for mSubId:" + mSubId);
@@ -117,6 +140,17 @@
mNameView.setSelection(displayName.length());
}
+ mColorSpinner = view.findViewById(R.id.color_spinner);
+ final ColorAdapter adapter = new ColorAdapter(getContext(),
+ R.layout.dialog_mobile_network_color_picker_item, mColors);
+ mColorSpinner.setAdapter(adapter);
+ for (int i = 0; i < mColors.length; i++) {
+ if (mColors[i].getColor() == info.getIconTint()) {
+ mColorSpinner.setSelection(i);
+ break;
+ }
+ }
+
final TextView operatorName = view.findViewById(R.id.operator_name_value);
final ServiceState serviceState = mTelephonyManager.getServiceStateForSubscriber(mSubId);
operatorName.setText(serviceState.getOperatorAlphaLong());
@@ -134,4 +168,80 @@
public int getMetricsCategory() {
return SettingsEnums.MOBILE_NETWORK_RENAME_DIALOG;
}
+
+ private class ColorAdapter extends ArrayAdapter<Color> {
+
+ private Context mContext;
+ private int mItemResId;
+
+ public ColorAdapter(Context context, int resource, Color[] colors) {
+ super(context, resource, colors);
+ mContext = context;
+ mItemResId = resource;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final LayoutInflater inflater = (LayoutInflater)
+ mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ if (convertView == null) {
+ convertView = inflater.inflate(mItemResId, null);
+ }
+ ((ImageView) convertView.findViewById(R.id.color_icon))
+ .setImageDrawable(getItem(position).getDrawable());
+ ((TextView) convertView.findViewById(R.id.color_label))
+ .setText(getItem(position).getLabel());
+
+ return convertView;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return getView(position, convertView, parent);
+ }
+ }
+
+ private Color[] getColors() {
+ final Resources res = getContext().getResources();
+ final int[] colorInts = res.getIntArray(com.android.internal.R.array.sim_colors);
+ final String[] colorStrings = res.getStringArray(R.array.color_picker);
+ final int iconSize = res.getDimensionPixelSize(R.dimen.color_swatch_size);
+ final int strokeWidth = res.getDimensionPixelSize(R.dimen.color_swatch_stroke_width);
+ final Color[] colors = new Color[colorInts.length];
+ for (int i = 0; i < colors.length; i++) {
+ colors[i] = new Color(colorStrings[i], colorInts[i], iconSize, strokeWidth);
+ }
+ return colors;
+ }
+
+ private static class Color {
+
+ private String mLabel;
+ private int mColor;
+ private ShapeDrawable mDrawable;
+
+ private Color(String label, int color, int iconSize, int strokeWidth) {
+ mLabel = label;
+ mColor = color;
+ mDrawable = new ShapeDrawable(new OvalShape());
+ mDrawable.setIntrinsicHeight(iconSize);
+ mDrawable.setIntrinsicWidth(iconSize);
+ mDrawable.getPaint().setStrokeWidth(strokeWidth);
+ mDrawable.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
+ mDrawable.getPaint().setColor(color);
+ }
+
+ private String getLabel() {
+ return mLabel;
+ }
+
+ private int getColor() {
+ return mColor;
+ }
+
+ private ShapeDrawable getDrawable() {
+ return mDrawable;
+ }
+ }
}
diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java
index 0d39c8f..3e81d0c 100644
--- a/src/com/android/settings/notification/ImportancePreference.java
+++ b/src/com/android/settings/notification/ImportancePreference.java
@@ -117,11 +117,13 @@
case IMPORTANCE_LOW:
mAlertButton.setBackground(unselectedBackground);
mSilenceButton.setBackground(selectedBackground);
+ mSilenceButton.setSelected(true);
break;
case IMPORTANCE_HIGH:
default:
mSilenceButton.setBackground(unselectedBackground);
mAlertButton.setBackground(selectedBackground);
+ mAlertButton.setSelected(true);
break;
}
setImportanceSummary((ViewGroup) holder.itemView, mImportance, false);
diff --git a/src/com/android/settings/notification/NotificationButtonRelativeLayout.java b/src/com/android/settings/notification/NotificationButtonRelativeLayout.java
new file mode 100644
index 0000000..358cbf3
--- /dev/null
+++ b/src/com/android/settings/notification/NotificationButtonRelativeLayout.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Button;
+import android.widget.RelativeLayout;
+
+public class NotificationButtonRelativeLayout extends RelativeLayout {
+
+ public NotificationButtonRelativeLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public CharSequence getAccessibilityClassName() {
+ return Button.class.getName();
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index fdd71e5..2a728c5 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -281,7 +281,7 @@
}
private Drawable getAlertingIcon() {
- Drawable icon = getContext().getDrawable(R.drawable.ic_notifications);
+ Drawable icon = getContext().getDrawable(R.drawable.ic_notifications_alert);
icon.setTintList(Utils.getColorAccent(getContext()));
return icon;
}
diff --git a/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
index 809bfbd..77aab34 100644
--- a/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
+++ b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
@@ -96,18 +96,23 @@
for (UserInfo info: userInfos) {
userHandles.add(info.getUserHandle());
}
-
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- UserAdapter adapter = UserAdapter.createUserAdapter(userManager, context, userHandles);
- builder.setTitle(com.android.settingslib.R.string.choose_profile)
- .setAdapter(adapter, (DialogInterface dialog, int which) -> {
- final UserHandle user = userHandles.get(which);
- // Show menu on top level items.
- final Intent intent = pref.getIntent();
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
- context.startActivityAsUser(intent, user);
- })
- .show();
+ if (userHandles.size() == 1) {
+ final Intent intent = pref.getIntent().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivityAsUser(intent, userHandles.get(0));
+ } else {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ UserAdapter adapter = UserAdapter.createUserAdapter(userManager, context,
+ userHandles);
+ builder.setTitle(com.android.settingslib.R.string.choose_profile)
+ .setAdapter(adapter, (DialogInterface dialog, int which) -> {
+ final UserHandle user = userHandles.get(which);
+ // Show menu on top level items.
+ final Intent intent = pref.getIntent()
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ context.startActivityAsUser(intent, user);
+ })
+ .show();
+ }
}
}
diff --git a/src/com/android/settings/slices/CustomSliceRegistry.java b/src/com/android/settings/slices/CustomSliceRegistry.java
index dc3324b..ebfd7b3 100644
--- a/src/com/android/settings/slices/CustomSliceRegistry.java
+++ b/src/com/android/settings/slices/CustomSliceRegistry.java
@@ -26,6 +26,7 @@
import androidx.annotation.VisibleForTesting;
+import com.android.settings.display.AdaptiveSleepPreferenceController;
import com.android.settings.flashlight.FlashlightSlice;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice;
@@ -34,6 +35,7 @@
import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice;
import com.android.settings.homepage.contextualcards.slices.BatteryFixSlice;
import com.android.settings.homepage.contextualcards.slices.BluetoothDevicesSlice;
+import com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice;
import com.android.settings.homepage.contextualcards.slices.ContextualNotificationChannelSlice;
import com.android.settings.homepage.contextualcards.slices.LowStorageSlice;
import com.android.settings.homepage.contextualcards.slices.NotificationChannelSlice;
@@ -65,6 +67,16 @@
.build();
/**
+ * Uri for Contextual Adaptive Sleep Slice
+ */
+ public static final Uri CONTEXTUAL_ADAPTIVE_SLEEP_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SettingsSliceProvider.SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+ .appendPath(AdaptiveSleepPreferenceController.PREF_NAME)
+ .build();
+
+ /**
* Uri for Battery Fix Slice.
*/
public static final Uri BATTERY_FIX_SLICE_URI = new Uri.Builder()
@@ -328,6 +340,7 @@
sUriToSlice.put(BATTERY_FIX_SLICE_URI, BatteryFixSlice.class);
sUriToSlice.put(BLUETOOTH_DEVICES_SLICE_URI, BluetoothDevicesSlice.class);
+ sUriToSlice.put(CONTEXTUAL_ADAPTIVE_SLEEP_URI, ContextualAdaptiveSleepSlice.class);
sUriToSlice.put(CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI,
ContextualNotificationChannelSlice.class);
sUriToSlice.put(CONTEXTUAL_WIFI_SLICE_URI, ContextualWifiSlice.class);
@@ -337,12 +350,12 @@
sUriToSlice.put(FLASHLIGHT_SLICE_URI, FlashlightSlice.class);
sUriToSlice.put(LOCATION_SLICE_URI, LocationSlice.class);
sUriToSlice.put(LOW_STORAGE_SLICE_URI, LowStorageSlice.class);
+ sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class);
+ sUriToSlice.put(MEDIA_OUTPUT_SLICE_URI, MediaOutputSlice.class);
sUriToSlice.put(MOBILE_DATA_SLICE_URI, MobileDataSlice.class);
sUriToSlice.put(NOTIFICATION_CHANNEL_SLICE_URI, NotificationChannelSlice.class);
sUriToSlice.put(STORAGE_SLICE_URI, StorageSlice.class);
sUriToSlice.put(WIFI_SLICE_URI, WifiSlice.class);
- sUriToSlice.put(MEDIA_OUTPUT_SLICE_URI, MediaOutputSlice.class);
- sUriToSlice.put(MEDIA_OUTPUT_INDICATOR_SLICE_URI, MediaOutputIndicatorSlice.class);
}
public static Class<? extends CustomSliceable> getSliceClassByUri(Uri uri) {
diff --git a/src/com/android/settings/slices/SlicePreferenceController.java b/src/com/android/settings/slices/SlicePreferenceController.java
index 89294c7..2432c99 100644
--- a/src/com/android/settings/slices/SlicePreferenceController.java
+++ b/src/com/android/settings/slices/SlicePreferenceController.java
@@ -40,7 +40,8 @@
LifecycleObserver, OnStart, OnStop, Observer<Slice> {
@VisibleForTesting
LiveData<Slice> mLiveData;
- private SlicePreference mSlicePreference;
+ @VisibleForTesting
+ SlicePreference mSlicePreference;
private Uri mUri;
public SlicePreferenceController(Context context, String preferenceKey) {
@@ -82,8 +83,6 @@
@Override
public void onChanged(Slice slice) {
- if (slice != null) {
- mSlicePreference.onSliceUpdated(slice);
- }
+ mSlicePreference.onSliceUpdated(slice);
}
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSliceTest.java
new file mode 100644
index 0000000..54fb2c3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ContextualAdaptiveSleepSliceTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.homepage.contextualcards.slices;
+
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.DEFERRED_TIME_DAYS;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF;
+import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_SETUP_TIME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+
+import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settings.slices.CustomSliceRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class ContextualAdaptiveSleepSliceTest {
+
+ private static final String pkgName = "adaptive_sleep";
+ private Context mContext;
+ private ContextualAdaptiveSleepSlice mContextualAdaptiveSleepSlice;
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private SharedPreferences mSharedPreferences;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
+ mContext = spy(RuntimeEnvironment.application);
+ mContextualAdaptiveSleepSlice = spy(new ContextualAdaptiveSleepSlice(mContext));
+
+ doReturn(mPackageManager).when(mContext).getPackageManager();
+ doReturn(mSharedPreferences).when(mContext).getSharedPreferences(eq(PREF), anyInt());
+ doReturn(true).when(mContextualAdaptiveSleepSlice).isSettingsAvailable();
+ doReturn(pkgName).when(mPackageManager).getAttentionServicePackageName();
+ doReturn(-DEFERRED_TIME_DAYS).when(mSharedPreferences).getLong(eq(PREF_KEY_SETUP_TIME),
+ anyLong());
+ }
+
+ @Test
+ public void getUri_shouldReturnContextualAdaptiveSleepSliceUri() {
+ final Uri uri = mContextualAdaptiveSleepSlice.getUri();
+
+ assertThat(uri).isEqualTo(CustomSliceRegistry.CONTEXTUAL_ADAPTIVE_SLEEP_URI);
+ }
+
+ @Test
+ public void getSlice_ShowIfFeatureIsAvailable() {
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNotNull();
+ }
+
+ @Test
+ public void getSlice_DoNotShowIfFeatureIsUnavailable() {
+ doReturn(false).when(mContextualAdaptiveSleepSlice).isSettingsAvailable();
+
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNull();
+ }
+
+ @Test
+ public void getSlice_ShowIfNotRecentlySetup() {
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNotNull();
+ }
+
+ @Test
+ public void getSlice_DoNotShowIfRecentlySetup() {
+ doReturn(System.currentTimeMillis()).when(mSharedPreferences).getLong(
+ eq(PREF_KEY_SETUP_TIME), anyLong());
+
+ final Slice slice = mContextualAdaptiveSleepSlice.getSlice();
+
+ assertThat(slice).isNull();
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
index 5b008be..53b4f00 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
@@ -30,6 +30,7 @@
import static org.mockito.Mockito.when;
import android.content.DialogInterface;
+import android.graphics.Color;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -38,6 +39,7 @@
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.Spinner;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
@@ -58,6 +60,7 @@
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowAlertDialogCompat.class)
public class RenameMobileNetworkDialogFragmentTest {
+
@Mock
private TelephonyManager mTelephonyMgr;
@Mock
@@ -95,7 +98,7 @@
}
@Test
- public void dialog_cancelButtonClicked_setDisplayNameNotCalled() {
+ public void dialog_cancelButtonClicked_setDisplayNameAndIconTintNotCalled() {
when(mSubscriptionMgr.getActiveSubscriptionInfo(mSubscriptionId)).thenReturn(
mSubscriptionInfo);
final AlertDialog dialog = startDialog();
@@ -106,10 +109,11 @@
negativeButton.performClick();
verify(mSubscriptionMgr, never()).setDisplayName(anyString(), anyInt(), anyInt());
+ verify(mSubscriptionMgr, never()).setIconTint(anyInt(), anyInt());
}
@Test
- public void dialog_renameButtonClicked_setDisplayNameCalled() {
+ public void dialog_saveButtonClicked_setDisplayNameAndIconTint() {
when(mSubscriptionMgr.getActiveSubscriptionInfo(mSubscriptionId)).thenReturn(
mSubscriptionInfo);
@@ -117,6 +121,9 @@
final EditText nameView = mFragment.getNameView();
nameView.setText("test2");
+ final Spinner colorSpinnerView = mFragment.getColorSpinnerView();
+ colorSpinnerView.setSelection(0);
+
final Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positiveButton.performClick();
@@ -124,6 +131,8 @@
verify(mSubscriptionMgr).setDisplayName(captor.capture(), eq(mSubscriptionId),
eq(SubscriptionManager.NAME_SOURCE_USER_INPUT));
assertThat(captor.getValue()).isEqualTo("test2");
+ verify(mSubscriptionMgr)
+ .setIconTint(eq(Color.parseColor("#ff00796b" /* teal */)), eq(mSubscriptionId));
}
@Test
@@ -140,7 +149,9 @@
assertThat(view.findViewById(R.id.number_label).getVisibility()).isEqualTo(View.GONE);
}
- /** Helper method to start the dialog */
+ /**
+ * Helper method to start the dialog
+ */
private AlertDialog startDialog() {
mFragment.show(mActivity.getSupportFragmentManager(), null);
return ShadowAlertDialogCompat.getLatestAlertDialog();
diff --git a/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
index 364fb60..65eaddd 100644
--- a/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SlicePreferenceControllerTest.java
@@ -41,6 +41,8 @@
@Mock
private LiveData<Slice> mLiveData;
+ @Mock
+ private SlicePreference mSlicePreference;
private Context mContext;
private SlicePreferenceController mController;
private Uri mUri;
@@ -53,6 +55,7 @@
mContext = spy(RuntimeEnvironment.application);
mController = new SlicePreferenceController(mContext, KEY);
mController.mLiveData = mLiveData;
+ mController.mSlicePreference = mSlicePreference;
mUri = Uri.EMPTY;
}
@@ -78,4 +81,11 @@
mController.onStop();
verify(mLiveData).removeObserver(mController);
}
+
+ @Test
+ public void onChanged_nullSlice_updateSlice() {
+ mController.onChanged(null);
+
+ verify(mController.mSlicePreference).onSliceUpdated(null);
+ }
}
\ No newline at end of file