From 80c3f6d4d84f822d1c3f41e6cb55fc05130e2b17 Mon Sep 17 00:00:00 2001 From: Tsung-Mao Fang Date: Tue, 13 Apr 2021 16:26:12 +0800 Subject: [PATCH 01/11] Prevent HTML Injection on the Device Admin request screen The root issue is that CharSequence is an interface. String implements that interface, however, Spanned class too which is a rich text format that can store HTML code. The solution is enforce to use String type which won't include any HTML function. Test: Rebuilt apk and see the string without HTML style. Bug: 179042963 Change-Id: I53b460b12da918e022d2f2934f114d205dbaadb0 Merged-In: I53b460b12da918e022d2f2934f114d205dbaadb0 --- src/com/android/settings/DeviceAdminAdd.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/DeviceAdminAdd.java b/src/com/android/settings/DeviceAdminAdd.java index 2fd769b42a2..ebad4115318 100644 --- a/src/com/android/settings/DeviceAdminAdd.java +++ b/src/com/android/settings/DeviceAdminAdd.java @@ -95,7 +95,7 @@ public class DeviceAdminAdd extends Activity { DevicePolicyManager mDPM; AppOpsManager mAppOps; DeviceAdminInfo mDeviceAdmin; - CharSequence mAddMsgText; + String mAddMsgText; String mProfileOwnerName; ImageView mAdminIcon; @@ -278,7 +278,11 @@ public class DeviceAdminAdd extends Activity { return; } - mAddMsgText = getIntent().getCharSequenceExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION); + final CharSequence addMsgCharSequence = getIntent().getCharSequenceExtra( + DevicePolicyManager.EXTRA_ADD_EXPLANATION); + if (addMsgCharSequence != null) { + mAddMsgText = addMsgCharSequence.toString(); + } setContentView(R.layout.device_admin_add); @@ -558,7 +562,7 @@ public class DeviceAdminAdd extends Activity { if (mAddingProfileOwner) { mProfileOwnerWarning.setVisibility(View.VISIBLE); } - if (mAddMsgText != null) { + if (!TextUtils.isEmpty(mAddMsgText)) { mAddMsg.setText(mAddMsgText); mAddMsg.setVisibility(View.VISIBLE); } else { From 50efd602b9ad81e026fcb5a4d3e671f12b939890 Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Tue, 27 Apr 2021 13:21:16 +0800 Subject: [PATCH 02/11] Update the BC style for the vision settings in SuW. Bug: 179234608 Test: manual test Change-Id: I152eaab8ad77c7a1fccbc82d7ed8cef406fc1821 --- res/drawable/ic_accessibility_visibility.xml | 26 ++++++++++++ ...ccessibility_settings_for_setup_wizard.xml | 36 ++++++++-------- .../AccessibilitySettingsForSetupWizard.java | 42 ++++++++++++++----- 3 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 res/drawable/ic_accessibility_visibility.xml diff --git a/res/drawable/ic_accessibility_visibility.xml b/res/drawable/ic_accessibility_visibility.xml new file mode 100644 index 00000000000..2c04f390daf --- /dev/null +++ b/res/drawable/ic_accessibility_visibility.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml index 1b9939a10a9..a3f56b534d6 100644 --- a/res/xml/accessibility_settings_for_setup_wizard.xml +++ b/res/xml/accessibility_settings_for_setup_wizard.xml @@ -14,46 +14,44 @@ limitations under the License. --> - - - - - + android:title="@string/title_font_size"/> + android:title="@string/screen_zoom_title"/> + + + android:summary="@string/select_to_speak_summary"/> - + android:summary="@string/talkback_summary"/> diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java index ffc8335c889..b5496a82b9b 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java +++ b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizard.java @@ -16,24 +16,32 @@ package com.android.settings.accessibility; +import static com.android.settings.Utils.getAdaptiveIcon; import static com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE; +import static com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_MEDIUM; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Context; import android.content.pm.ServiceInfo; +import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; +import android.widget.FrameLayout; +import android.widget.ImageView; import androidx.preference.Preference; import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; +import com.android.settingslib.RestrictedPreference; import com.google.android.setupdesign.GlifPreferenceLayout; @@ -61,8 +69,8 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm // Preference controls. private Preference mDisplayMagnificationPreference; - private Preference mScreenReaderPreference; - private Preference mSelectToSpeakPreference; + private RestrictedPreference mScreenReaderPreference; + private RestrictedPreference mSelectToSpeakPreference; @Override public int getMetricsCategory() { @@ -73,16 +81,24 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - GlifPreferenceLayout layout = (GlifPreferenceLayout) view; + final GlifPreferenceLayout layout = (GlifPreferenceLayout) view; layout.setDividerInsets(Integer.MAX_VALUE, 0); - + layout.setDescriptionText(R.string.vision_settings_description); layout.setHeaderText(R.string.vision_settings_title); + layout.setIcon(getResources().getDrawable(R.drawable.ic_accessibility_visibility)); + + final ImageView iconView = layout.findManagedViewById(R.id.sud_layout_icon); + final FrameLayout.LayoutParams params = + (FrameLayout.LayoutParams) iconView.getLayoutParams(); + params.gravity = Gravity.START; + layout.getHeaderTextView().setGravity(Gravity.START); + layout.getDescriptionTextView().setGravity(Gravity.START); } @Override public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { - GlifPreferenceLayout layout = (GlifPreferenceLayout) parent; + final GlifPreferenceLayout layout = (GlifPreferenceLayout) parent; return layout.onCreateRecyclerView(inflater, parent, savedInstanceState); } @@ -145,7 +161,7 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm return null; } - private void updateAccessibilityServicePreference(Preference preference, + private void updateAccessibilityServicePreference(RestrictedPreference preference, String packageName, String serviceName, String targetFragment) { final AccessibilityServiceInfo info = findService(packageName, serviceName); if (info == null) { @@ -153,24 +169,28 @@ public class AccessibilitySettingsForSetupWizard extends SettingsPreferenceFragm return; } - ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo; - String title = info.getResolveInfo().loadLabel(getPackageManager()).toString(); + final ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo; + final Drawable icon = info.getResolveInfo().loadIcon(getPackageManager()); + preference.setIcon(getAdaptiveIcon(getContext(), icon, Color.WHITE)); + preference.setIconSize(ICON_SIZE_MEDIUM); + final String title = info.getResolveInfo().loadLabel(getPackageManager()).toString(); preference.setTitle(title); - ComponentName componentName = new ComponentName(serviceInfo.packageName, serviceInfo.name); + final ComponentName componentName = + new ComponentName(serviceInfo.packageName, serviceInfo.name); preference.setKey(componentName.flattenToString()); if (AccessibilityUtil.getAccessibilityServiceFragmentType(info) == VOLUME_SHORTCUT_TOGGLE) { preference.setFragment(targetFragment); } // Update the extras. - Bundle extras = preference.getExtras(); + final Bundle extras = preference.getExtras(); extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, componentName); extras.putString(AccessibilitySettings.EXTRA_PREFERENCE_KEY, preference.getKey()); extras.putString(AccessibilitySettings.EXTRA_TITLE, title); - String description = info.loadDescription(getPackageManager()); + final String description = info.loadDescription(getPackageManager()); extras.putString(AccessibilitySettings.EXTRA_SUMMARY, description); extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, info.getAnimatedImageRes()); From 4775b90eff2b27e51aa3e7cb150afbb8b6ed1ea8 Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Tue, 27 Apr 2021 13:47:57 -0700 Subject: [PATCH 03/11] Remove icons of Location Services and App location permissions Bug: 180533061 Test: on device Change-Id: I85b88823f730494836677caa489b1e249913e5f4 --- res/xml/location_settings.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml index a950b3a3afc..08a8b76431c 100644 --- a/res/xml/location_settings.xml +++ b/res/xml/location_settings.xml @@ -46,7 +46,6 @@ From e22567d44ec7dfb5fcbb09ae9ed334c959e56bcc Mon Sep 17 00:00:00 2001 From: Amit Mahajan Date: Tue, 27 Apr 2021 17:43:13 -0700 Subject: [PATCH 04/11] Fix incorrect logging. Test: none Bug: 182326102 Change-Id: Ibe9b4dd26eb92327d32dc3447c5a613c3fefa46e --- .../network/telephony/BackupCallingPreferenceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java b/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java index 2b07b5d621b..c4bf6b46250 100644 --- a/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/BackupCallingPreferenceController.java @@ -156,7 +156,7 @@ public class BackupCallingPreferenceController extends TelephonyTogglePreference } // TODO: remove log after fixing b/182326102 Log.d(LOG_TAG, "config " + CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL - + "=" + featureEnableStatus + " for subId=" + mSubId); + + "=" + featureEnableStatus + " for subId=" + subscriptionId); return (featureEnableStatus != null) && featureEnableStatus.booleanValue(); } From c80e4ce3a1060ddc1816401201427eed840e4f41 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Wed, 28 Apr 2021 14:43:09 +0100 Subject: [PATCH 05/11] Settings: Turn Privacy hub on by default. Bug: 176902658 Test: manual Change-Id: I44027f29ce1a6b5a0c5eeba1e68cabb7476e7cc6 --- .../settings/privacy/PrivacyHubPreferenceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/privacy/PrivacyHubPreferenceController.java b/src/com/android/settings/privacy/PrivacyHubPreferenceController.java index b07b5f5e640..0de4f06c89c 100644 --- a/src/com/android/settings/privacy/PrivacyHubPreferenceController.java +++ b/src/com/android/settings/privacy/PrivacyHubPreferenceController.java @@ -35,6 +35,6 @@ public final class PrivacyHubPreferenceController extends BasePreferenceControll @Override public int getAvailabilityStatus() { return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY, - PROPERTY_PRIVACY_HUB_ENABLED, false) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + PROPERTY_PRIVACY_HUB_ENABLED, true) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } } From a3f00c0d184e658926cbeb2b4f4cfa2b54960452 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Thu, 29 Apr 2021 01:07:20 +0800 Subject: [PATCH 06/11] [ApnEditor] Create another string id for translation - make translation of MVNO value be diversity. Bug: 185209214 Test: Maunal test passed - https://screenshot.googleplex.com/33vyFFBp8EnTpQ8 - atest passed Change-Id: I9b26e23bf61f06a987682fe64d9ce079e2194818 --- res/values/strings.xml | 2 ++ src/com/android/settings/network/apn/ApnEditor.java | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 22f6c91a988..c9baef5a0b8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3768,6 +3768,8 @@ Edit access point Not set + + Not set Name diff --git a/src/com/android/settings/network/apn/ApnEditor.java b/src/com/android/settings/network/apn/ApnEditor.java index afc68d5bb29..0b751620ad1 100644 --- a/src/com/android/settings/network/apn/ApnEditor.java +++ b/src/com/android/settings/network/apn/ApnEditor.java @@ -632,7 +632,7 @@ public class ApnEditor extends SettingsPreferenceFragment checkNull(bearerMultiDescription(mBearerMulti.getValues()))); mMvnoType.setSummary( checkNull(mvnoDescription(mMvnoType.getValue()))); - mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText())); + mMvnoMatchData.setSummary(checkNullforMvnoValue(mMvnoMatchData.getText())); // allow user to edit carrier_enabled for some APN final boolean ceEditable = getResources().getBoolean( R.bool.config_allow_edit_carrier_enabled); @@ -791,7 +791,7 @@ public class ApnEditor extends SettingsPreferenceFragment } mMvnoType.setValue((String) newValue); mMvnoType.setSummary(mvno); - mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText())); + mMvnoMatchData.setSummary(checkNullforMvnoValue(mMvnoMatchData.getText())); } else if (KEY_PASSWORD.equals(key)) { mPassword.setSummary(starify(newValue != null ? String.valueOf(newValue) : "")); } else if (KEY_CARRIER_ENABLED.equals(key)) { @@ -1216,6 +1216,14 @@ public class ApnEditor extends SettingsPreferenceFragment return TextUtils.isEmpty(value) ? sNotSet : value; } + /** + * To make traslation be diversity, use another string id for MVNO value. + */ + private String checkNullforMvnoValue(String value) { + String notSetForMvnoValue = getResources().getString(R.string.apn_not_set_for_mvno); + return TextUtils.isEmpty(value) ? notSetForMvnoValue : value; + } + /** * Returns null if the given string {@code value} equals to {@link #sNotSet}. This method * should be used when convert a string value from preference to database. From 558ace6acae5c522cab6f023c136278d23d06786 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Wed, 28 Apr 2021 10:01:54 -0400 Subject: [PATCH 07/11] SUW - Apply theme to FRP PIN pages It is safe to always attempt to copy SUW intent extras, as they will only be applied if they exist. Fixes: 171950236 Fixes: 181212237 Fixes: 183711331 Test: SUW FRP verify, settings confirm existing PIN Change-Id: I6d35683abdc864aea7b1ed0190d6776a75b3e116 --- .../settings/password/ChooseLockSettingsHelper.java | 9 +++++---- .../password/ConfirmDeviceCredentialBaseActivity.java | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java index 29330f54872..5ed43fa21fb 100644 --- a/src/com/android/settings/password/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java @@ -359,21 +359,22 @@ public final class ChooseLockSettingsHelper { requestGatekeeperPasswordHandle); intent.setClassName(SETTINGS_PACKAGE_NAME, activityClass.getName()); + + Intent inIntent = mFragment != null ? mFragment.getActivity().getIntent() : + mActivity.getIntent(); + copyInternalExtras(inIntent, intent); if (external) { intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + copyOptionalExtras(inIntent, intent); if (mFragment != null) { - copyOptionalExtras(mFragment.getActivity().getIntent(), intent); mFragment.startActivity(intent); } else { - copyOptionalExtras(mActivity.getIntent(), intent); mActivity.startActivity(intent); } } else { if (mFragment != null) { - copyInternalExtras(mFragment.getActivity().getIntent(), intent); mFragment.startActivityForResult(intent, request); } else { - copyInternalExtras(mActivity.getIntent(), intent); mActivity.startActivityForResult(intent, request); } } diff --git a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java index f0b50a1bfec..40297551152 100644 --- a/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java +++ b/src/com/android/settings/password/ConfirmDeviceCredentialBaseActivity.java @@ -30,6 +30,8 @@ import com.android.settings.SettingsActivity; import com.android.settings.SetupWizardUtils; import com.android.settings.Utils; +import com.google.android.setupdesign.util.ThemeHelper; + public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivity { private static final String STATE_IS_KEYGUARD_LOCKED = "STATE_IS_KEYGUARD_LOCKED"; @@ -74,6 +76,7 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi setTheme(SetupWizardUtils.getTheme(this, getIntent())); mConfirmCredentialTheme = ConfirmCredentialTheme.NORMAL; } + ThemeHelper.trySetDynamicColor(this); super.onCreate(savedState); if (mConfirmCredentialTheme == ConfirmCredentialTheme.NORMAL) { From 1f0cd17e3e40827545c74040cb24b31ada65d0eb Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Wed, 28 Apr 2021 12:37:55 -0700 Subject: [PATCH 08/11] Fix several challenge paths 1) Combined settings page should finish() when losing foreground (but not if fingerprint or face settings are launched from it) 2) Challenge should be generated when entering FaceSettings or FingerprintSettings each time. This allows us to leave the existing revokeChallenge paths in FaceSettings and FingerprintSettings. Fixes: 186257202 Test: Manual Change-Id: I1b6452f787279001a71628f220c01fcb86b88f3d --- .../combination/BiometricsSettingsBase.java | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java index 4260c7c9130..c449ff4bfce 100644 --- a/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java +++ b/src/com/android/settings/biometrics/combination/BiometricsSettingsBase.java @@ -48,16 +48,15 @@ public abstract class BiometricsSettingsBase extends DashboardFragment { private static final int CHOOSE_LOCK_REQUEST = 2002; private static final String SAVE_STATE_CONFIRM_CREDETIAL = "confirm_credential"; + private static final String DO_NOT_FINISH_ACTIVITY = "do_not_finish_activity"; protected int mUserId; - protected long mFaceChallenge; - protected long mFingerprintChallenge; - protected int mFaceSensorId; - protected int mFingerprintSensorId; protected long mGkPwHandle; private boolean mConfirmCredential; @Nullable private FaceManager mFaceManager; @Nullable private FingerprintManager mFingerprintManager; + // Do not finish() if choosing/confirming credential, or showing fp/face settings + private boolean mDoNotFinishActivity; @Override public void onAttach(Context context) { @@ -78,6 +77,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment { if (savedInstanceState != null) { mConfirmCredential = savedInstanceState.getBoolean(SAVE_STATE_CONFIRM_CREDETIAL); + mDoNotFinishActivity = savedInstanceState.getBoolean(DO_NOT_FINISH_ACTIVITY); if (savedInstanceState.containsKey( ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE)) { mGkPwHandle = savedInstanceState.getLong( @@ -92,31 +92,47 @@ public abstract class BiometricsSettingsBase extends DashboardFragment { } @Override - public void onDestroy() { - super.onDestroy(); - if (getActivity().isFinishing()) { - mFaceManager.revokeChallenge(mFaceSensorId, mUserId, mFaceChallenge); - mFingerprintManager.revokeChallenge(mUserId, mFingerprintChallenge); + public void onResume() { + super.onResume(); + if (!mConfirmCredential) { + mDoNotFinishActivity = false; + } + } + + @Override + public void onStop() { + super.onStop(); + if (!getActivity().isChangingConfigurations() && !mDoNotFinishActivity) { BiometricUtils.removeGatekeeperPasswordHandle(getActivity(), mGkPwHandle); + getActivity().finish(); } } @Override public boolean onPreferenceTreeClick(Preference preference) { final String key = preference.getKey(); + + // Generate challenge (and request LSS to create a HAT) each time the preference is clicked, + // since FingerprintSettings and FaceSettings revoke the challenge when finishing. if (getFacePreferenceKey().equals(key)) { - final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle, - mUserId, mFaceChallenge); - final Bundle extras = preference.getExtras(); - extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); - extras.putInt(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, mFaceSensorId); - extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mFaceChallenge); + mDoNotFinishActivity = true; + mFaceManager.generateChallenge((sensorId, challenge) -> { + final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle, + mUserId, challenge); + final Bundle extras = preference.getExtras(); + extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); + extras.putInt(BiometricEnrollBase.EXTRA_KEY_SENSOR_ID, sensorId); + extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); + }); } else if (getFingerprintPreferenceKey().equals(key)) { - final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle, - mUserId, mFingerprintChallenge); - final Bundle extras = preference.getExtras(); - extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); - extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mFingerprintChallenge); + mDoNotFinishActivity = true; + mFingerprintManager.generateChallenge(mUserId, (sensorId, challenge) -> { + final byte[] token = BiometricUtils.requestGatekeeperHat(getActivity(), mGkPwHandle, + mUserId, challenge); + final Bundle extras = preference.getExtras(); + extras.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); + extras.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge); + }); } return super.onPreferenceTreeClick(preference); } @@ -125,6 +141,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment { public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(SAVE_STATE_CONFIRM_CREDETIAL, mConfirmCredential); + outState.putBoolean(DO_NOT_FINISH_ACTIVITY, mDoNotFinishActivity); if (mGkPwHandle != 0L) { outState.putLong(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, mGkPwHandle); } @@ -135,17 +152,10 @@ public abstract class BiometricsSettingsBase extends DashboardFragment { super.onActivityResult(requestCode, resultCode, data); if (requestCode == CONFIRM_REQUEST || requestCode == CHOOSE_LOCK_REQUEST) { mConfirmCredential = false; + mDoNotFinishActivity = false; if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) { - if (data != null && BiometricUtils.containsGatekeeperPasswordHandle(data)) { + if (BiometricUtils.containsGatekeeperPasswordHandle(data)) { mGkPwHandle = BiometricUtils.getGatekeeperPasswordHandle(data); - mFaceManager.generateChallenge((sensorId, challenge) -> { - mFaceSensorId = sensorId; - mFaceChallenge = challenge; - }); - mFingerprintManager.generateChallenge(mUserId, (sensorId, challenge) -> { - mFingerprintSensorId = sensorId; - mFingerprintChallenge = challenge; - }); } else { Log.d(getLogTag(), "Data null or GK PW missing."); finish(); @@ -178,6 +188,7 @@ public abstract class BiometricsSettingsBase extends DashboardFragment { if (mUserId != UserHandle.USER_NULL) { builder.setUserId(mUserId); } + mDoNotFinishActivity = true; final boolean launched = builder.show(); if (!launched) { From 86a6a0d32c7470f1d1fb98f716348939b19b9a48 Mon Sep 17 00:00:00 2001 From: "Wesley.CW Wang" Date: Mon, 26 Apr 2021 20:30:03 +0800 Subject: [PATCH 09/11] Make app usage page active time support time period - Add time slot into active time text Screenshot: https://screenshot.googleplex.com/hzj5cJ3eDJD5iW7.png Bug: 178197718 Test: make SettingsRoboTests Change-Id: I0904e78ca9ab0a5b454e093388f667e978e8722f --- res/values/strings.xml | 16 +-- .../fuelgauge/AdvancedPowerUsageDetail.java | 98 +++++++++++++++---- .../AdvancedPowerUsageDetailTest.java | 86 ++++++++++++++-- 3 files changed, 168 insertions(+), 32 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 0ec17dc012a..d0d0c0536b7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6322,9 +6322,9 @@ Manage battery usage - ^1 total • ^2 background for past 24 hr + ^1 total • ^2 background for past 24 hr - ^1 total • ^2 background for ^3 + ^1 total • ^2 background for ^3 Total less than a minute for past 24 hr @@ -6332,9 +6332,9 @@ Total less than a minute for ^1 - Background less than a minute for past 24 hr + Background less than a minute for past 24 hr - Background less than a minute for ^1 + Background less than a minute for ^1 ^1 total for past 24 hr @@ -6342,14 +6342,14 @@ ^1 total for ^2 - ^1 background for past 24 hr + ^1 background for past 24 hr - ^1 background for ^2 + ^1 background for ^2 - ^1 total • background less than a minute for past 24 hr + ^1 total • background less than a minute for past 24 hr - ^1 total • background less than a minute for ^2 + ^1 total • background less than a minute for ^2 No usage for past 24 hr diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java index 4dbde251276..21160d70cf4 100644 --- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java +++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java @@ -70,6 +70,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements public static final String EXTRA_PACKAGE_NAME = "extra_package_name"; public static final String EXTRA_FOREGROUND_TIME = "extra_foreground_time"; public static final String EXTRA_BACKGROUND_TIME = "extra_background_time"; + public static final String EXTRA_SLOT_TIME = "extra_slot_time"; public static final String EXTRA_LABEL = "extra_label"; public static final String EXTRA_ICON_ID = "extra_icon_id"; public static final String EXTRA_POWER_USAGE_PERCENT = "extra_power_usage_percent"; @@ -184,6 +185,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements args.putInt(EXTRA_UID, launchArgs.mUid); args.putLong(EXTRA_BACKGROUND_TIME, launchArgs.mBackgroundTimeMs); args.putLong(EXTRA_FOREGROUND_TIME, launchArgs.mForegroundTimeMs); + args.putString(EXTRA_SLOT_TIME, launchArgs.mSlotInformation); args.putString(EXTRA_POWER_USAGE_PERCENT, launchArgs.mUsagePercent); args.putInt(EXTRA_POWER_USAGE_AMOUNT, launchArgs.mConsumedPower); final int userId = launchArgs.mIsUserEntry ? ActivityManager.getCurrentUser() @@ -294,8 +296,9 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements if (enableTriState) { final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME); final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME); + final String slotTime = bundle.getString(EXTRA_SLOT_TIME, null); //TODO(b/178197718) Update layout to support multiple lines - controller.setSummary(getAppActiveTime(foregroundTimeMs, backgroundTimeMs)); + controller.setSummary(getAppActiveTime(foregroundTimeMs, backgroundTimeMs, slotTime)); } controller.done(context, true /* rebindActions */); @@ -430,32 +433,46 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements getContext(), getArguments().getInt(EXTRA_UID), packageName); } - //TODO(b/178197718) Update method to support time period - private CharSequence getAppActiveTime(long foregroundTimeMs, long backgroundTimeMs) { + private CharSequence getAppActiveTime( + long foregroundTimeMs, long backgroundTimeMs, String slotTime) { final long totalTimeMs = foregroundTimeMs + backgroundTimeMs; final CharSequence usageTimeSummary; if (totalTimeMs == 0) { usageTimeSummary = getText(R.string.battery_not_usage); + } else if (slotTime == null) { + // Shows summary text with past 24 hr if slot time is null. + usageTimeSummary = + getAppPast24HrActiveSummary(foregroundTimeMs, backgroundTimeMs, totalTimeMs); + } else { + // Shows summary text with slot time. + usageTimeSummary = getAppActiveSummaryWithSlotTime( + foregroundTimeMs, backgroundTimeMs, totalTimeMs, slotTime); + } + return usageTimeSummary; + } + + private CharSequence getAppPast24HrActiveSummary( + long foregroundTimeMs, long backgroundTimeMs, long totalTimeMs) { // Shows background summary only if we don't have foreground usage time. - } else if (foregroundTimeMs == 0 && backgroundTimeMs != 0) { - usageTimeSummary = backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS ? - getText(R.string.battery_background_usage_less_minute) : - TextUtils.expandTemplate(getText(R.string.battery_background_usage), - StringUtil.formatElapsedTime( - getContext(), - backgroundTimeMs, - /* withSeconds */ false, - /* collapseTimeUnit */ false)); + if (foregroundTimeMs == 0 && backgroundTimeMs != 0) { + return backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS ? + getText(R.string.battery_bg_usage_less_minute) : + TextUtils.expandTemplate(getText(R.string.battery_bg_usage), + StringUtil.formatElapsedTime( + getContext(), + backgroundTimeMs, + /* withSeconds */ false, + /* collapseTimeUnit */ false)); // Shows total usage summary only if total usage time is small. } else if (totalTimeMs < DateUtils.MINUTE_IN_MILLIS) { - usageTimeSummary = getText(R.string.battery_total_usage_less_minute); + return getText(R.string.battery_total_usage_less_minute); // Shows different total usage summary when background usage time is small. } else if (backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS) { - usageTimeSummary = TextUtils.expandTemplate( + return TextUtils.expandTemplate( getText(backgroundTimeMs == 0 ? R.string.battery_total_usage : - R.string.battery_total_usage_and_background_less_minute_usage), + R.string.battery_total_usage_and_bg_less_minute_usage), StringUtil.formatElapsedTime( getContext(), totalTimeMs, @@ -463,8 +480,8 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements /* collapseTimeUnit */ false)); // Shows default summary. } else { - usageTimeSummary = TextUtils.expandTemplate( - getText(R.string.battery_total_and_background_usage), + return TextUtils.expandTemplate( + getText(R.string.battery_total_and_bg_usage), StringUtil.formatElapsedTime( getContext(), totalTimeMs, @@ -476,6 +493,51 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements /* withSeconds */ false, /* collapseTimeUnit */ false)); } - return usageTimeSummary; + } + + private CharSequence getAppActiveSummaryWithSlotTime( + long foregroundTimeMs, long backgroundTimeMs, long totalTimeMs, String slotTime) { + // Shows background summary only if we don't have foreground usage time. + if (foregroundTimeMs == 0 && backgroundTimeMs != 0) { + return backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS ? + TextUtils.expandTemplate( + getText(R.string.battery_bg_usage_less_minute_with_period), + slotTime) : + TextUtils.expandTemplate(getText(R.string.battery_bg_usage_with_period), + StringUtil.formatElapsedTime( + getContext(), + backgroundTimeMs, + /* withSeconds */ false, + /* collapseTimeUnit */ false), slotTime); + // Shows total usage summary only if total usage time is small. + } else if (totalTimeMs < DateUtils.MINUTE_IN_MILLIS) { + return TextUtils.expandTemplate( + getText(R.string.battery_total_usage_less_minute_with_period), slotTime); + // Shows different total usage summary when background usage time is small. + } else if (backgroundTimeMs < DateUtils.MINUTE_IN_MILLIS) { + return TextUtils.expandTemplate( + getText(backgroundTimeMs == 0 ? + R.string.battery_total_usage_with_period : + R.string.battery_total_usage_and_bg_less_minute_usage_with_period), + StringUtil.formatElapsedTime( + getContext(), + totalTimeMs, + /* withSeconds */ false, + /* collapseTimeUnit */ false), slotTime); + // Shows default summary. + } else { + return TextUtils.expandTemplate( + getText(R.string.battery_total_and_bg_usage_with_period), + StringUtil.formatElapsedTime( + getContext(), + totalTimeMs, + /* withSeconds */ false, + /* collapseTimeUnit */ false), + StringUtil.formatElapsedTime( + getContext(), + backgroundTimeMs, + /* withSeconds */ false, + /* collapseTimeUnit */ false), slotTime); + } } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java index 5185593e8b7..1c2c0596231 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java @@ -81,6 +81,7 @@ public class AdvancedPowerUsageDetailTest { private static final String SUMMARY = "summary"; private static final String[] PACKAGE_NAME = {"com.android.app"}; private static final String USAGE_PERCENT = "16%"; + private static final String SLOT_TIME = "12 am-2 am"; private static final int ICON_ID = 123; private static final int UID = 1; private static final int POWER_MAH = 150; @@ -284,7 +285,7 @@ public class AdvancedPowerUsageDetailTest { } @Test - public void testInitHeader_backgroundTwoMinutesForegroundZero_hasCorrectSummary() { + public void testInitHeader_backgroundTwoMinForegroundZero_hasCorrectSummary() { final long backgroundTimeTwoMinutes = 120000; final long foregroundTimeZero = 0; Bundle bundle = new Bundle(2); @@ -301,7 +302,7 @@ public class AdvancedPowerUsageDetailTest { } @Test - public void testInitHeader_backgroundLessThanAMinutesForegroundZero_hasCorrectSummary() { + public void testInitHeader_backgroundLessThanAMinForegroundZero_hasCorrectSummary() { final long backgroundTimeLessThanAMinute = 59999; final long foregroundTimeZero = 0; Bundle bundle = new Bundle(2); @@ -319,7 +320,7 @@ public class AdvancedPowerUsageDetailTest { } @Test - public void testInitHeader_totalUsageLessThanAMinutes_hasCorrectSummary() { + public void testInitHeader_totalUsageLessThanAMin_hasCorrectSummary() { final long backgroundTimeLessThanHalfMinute = 20000; final long foregroundTimeLessThanHalfMinute = 20000; Bundle bundle = new Bundle(2); @@ -338,7 +339,7 @@ public class AdvancedPowerUsageDetailTest { } @Test - public void testInitHeader_TotalAMinutesBackgroundLessThanAMinutes_hasCorrectSummary() { + public void testInitHeader_TotalAMinutesBackgroundLessThanAMin_hasCorrectSummary() { final long backgroundTimeZero = 59999; final long foregroundTimeTwoMinutes = 1; Bundle bundle = new Bundle(2); @@ -355,7 +356,7 @@ public class AdvancedPowerUsageDetailTest { } @Test - public void testInitHeader_TotalAMinutesBackgroundZero_hasCorrectSummary() { + public void testInitHeader_TotalAMinBackgroundZero_hasCorrectSummary() { final long backgroundTimeZero = 0; final long foregroundTimeAMinutes = 60000; Bundle bundle = new Bundle(2); @@ -372,7 +373,7 @@ public class AdvancedPowerUsageDetailTest { } @Test - public void testInitHeader_foregroundTwoMinutesBackgroundFourMinutes_hasCorrectSummary() { + public void testInitHeader_foregroundTwoMinBackgroundFourMin_hasCorrectSummary() { final long backgroundTimeFourMinute = 240000; final long foregroundTimeTwoMinutes = 120000; Bundle bundle = new Bundle(2); @@ -387,6 +388,79 @@ public class AdvancedPowerUsageDetailTest { .isEqualTo("6 min total • 4 min background for past 24 hr"); } + @Test + public void testInitHeader_totalUsageLessThanAMinWithSlotTime_hasCorrectSummary() { + final long backgroundTimeLessThanHalfMinute = 20000; + final long foregroundTimeLessThanHalfMinute = 20000; + Bundle bundle = new Bundle(2); + bundle.putLong( + AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeLessThanHalfMinute); + bundle.putLong( + AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeLessThanHalfMinute); + bundle.putString(AdvancedPowerUsageDetail.EXTRA_SLOT_TIME, SLOT_TIME); + when(mFragment.getArguments()).thenReturn(bundle); + + mFragment.initHeader(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(CharSequence.class); + verify(mEntityHeaderController).setSummary(captor.capture()); + assertThat(captor.getValue().toString()) + .isEqualTo("Total less than a minute for 12 am-2 am"); + } + + @Test + public void testInitHeader_TotalAMinBackgroundLessThanAMinWithSlotTime_hasCorrectSummary() { + final long backgroundTimeZero = 59999; + final long foregroundTimeTwoMinutes = 1; + Bundle bundle = new Bundle(2); + bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeZero); + bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeTwoMinutes); + bundle.putString(AdvancedPowerUsageDetail.EXTRA_SLOT_TIME, SLOT_TIME); + when(mFragment.getArguments()).thenReturn(bundle); + + mFragment.initHeader(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(CharSequence.class); + verify(mEntityHeaderController).setSummary(captor.capture()); + assertThat(captor.getValue().toString()) + .isEqualTo("1 min total • background less than a minute for 12 am-2 am"); + } + + @Test + public void testInitHeader_TotalAMinBackgroundZeroWithSlotTime_hasCorrectSummary() { + final long backgroundTimeZero = 0; + final long foregroundTimeAMinutes = 60000; + Bundle bundle = new Bundle(2); + bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeZero); + bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeAMinutes); + bundle.putString(AdvancedPowerUsageDetail.EXTRA_SLOT_TIME, SLOT_TIME); + when(mFragment.getArguments()).thenReturn(bundle); + + mFragment.initHeader(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(CharSequence.class); + verify(mEntityHeaderController).setSummary(captor.capture()); + assertThat(captor.getValue().toString()) + .isEqualTo("1 min total for 12 am-2 am"); + } + + @Test + public void testInitHeader_foregroundTwoMinBackgroundFourMinWithSlotTime_hasCorrectSummary() { + final long backgroundTimeFourMinute = 240000; + final long foregroundTimeTwoMinutes = 120000; + Bundle bundle = new Bundle(2); + bundle.putLong(AdvancedPowerUsageDetail.EXTRA_BACKGROUND_TIME, backgroundTimeFourMinute); + bundle.putLong(AdvancedPowerUsageDetail.EXTRA_FOREGROUND_TIME, foregroundTimeTwoMinutes); + bundle.putString(AdvancedPowerUsageDetail.EXTRA_SLOT_TIME, SLOT_TIME); + when(mFragment.getArguments()).thenReturn(bundle); + mFragment.initHeader(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(CharSequence.class); + verify(mEntityHeaderController).setSummary(captor.capture()); + assertThat(captor.getValue().toString()) + .isEqualTo("6 min total • 4 min background for 12 am-2 am"); + } + @Test public void testStartBatteryDetailPage_hasBasicData() { AdvancedPowerUsageDetail.startBatteryDetailPage(mActivity, mFragment, From 20d1da2b6298ade2a2390a66f98a1d12381e5e8f Mon Sep 17 00:00:00 2001 From: Yi Jiang Date: Fri, 2 Apr 2021 11:46:53 -0700 Subject: [PATCH 10/11] Fixes 'no ripple effect' issue for screen attention setting Preferences shouldn't be initialized at onAttach() because the settings style hasn't been loaded yet. This change defers the preferences initialization so that they comply with the settings style. Test: manually Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.display Bug: 183909540 Change-Id: I4dc4503924a1dcd5b8d41f7d27e576befb11f976 --- ...veSleepPermissionPreferenceController.java | 29 ++++++++------ .../AdaptiveSleepPreferenceController.java | 39 +++++++++++-------- .../display/ScreenTimeoutSettings.java | 18 ++++++--- ...AdaptiveSleepPreferenceControllerTest.java | 1 + .../display/ScreenTimeoutSettingsTest.java | 4 +- 5 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/com/android/settings/display/AdaptiveSleepPermissionPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPermissionPreferenceController.java index 0d21e9caf80..8e4db0d26ad 100644 --- a/src/com/android/settings/display/AdaptiveSleepPermissionPreferenceController.java +++ b/src/com/android/settings/display/AdaptiveSleepPermissionPreferenceController.java @@ -37,26 +37,18 @@ public class AdaptiveSleepPermissionPreferenceController { @VisibleForTesting BannerMessagePreference mPreference; private final PackageManager mPackageManager; + private final Context mContext; public AdaptiveSleepPermissionPreferenceController(Context context) { - final String packageName = context.getPackageManager().getAttentionServicePackageName(); mPackageManager = context.getPackageManager(); - final Intent intent = new Intent( - android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - intent.setData(Uri.parse("package:" + packageName)); - mPreference = new BannerMessagePreference(context); - mPreference.setTitle(R.string.adaptive_sleep_title_no_permission); - mPreference.setSummary(R.string.adaptive_sleep_summary_no_permission); - mPreference.setPositiveButtonText(R.string.adaptive_sleep_manage_permission_button); - mPreference.setPositiveButtonOnClickListener(p -> { - context.startActivity(intent); - }); + mContext = context; } /** * Adds the controlled preference to the provided preference screen. */ public void addToScreen(PreferenceScreen screen) { + initializePreference(); if (!hasSufficientPermission(mPackageManager)) { screen.addPreference(mPreference); } @@ -68,4 +60,19 @@ public class AdaptiveSleepPermissionPreferenceController { public void updateVisibility() { mPreference.setVisible(!hasSufficientPermission(mPackageManager)); } + + private void initializePreference() { + final String packageName = mContext.getPackageManager().getAttentionServicePackageName(); + final Intent intent = new Intent( + android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setData(Uri.parse("package:" + packageName)); + mPreference = new BannerMessagePreference(mContext); + mPreference.setTitle(R.string.adaptive_sleep_title_no_permission); + mPreference.setSummary(R.string.adaptive_sleep_summary_no_permission); + mPreference.setPositiveButtonText(R.string.adaptive_sleep_manage_permission_button); + mPreference.setPositiveButtonOnClickListener(p -> { + mContext.startActivity(intent); + }); + } + } diff --git a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java index 70d8a79f390..aa02ce51c81 100644 --- a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java +++ b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java @@ -49,10 +49,10 @@ public class AdaptiveSleepPreferenceController { public static final String PREFERENCE_KEY = "adaptive_sleep"; private static final int DEFAULT_VALUE = 0; private final SensorPrivacyManager mPrivacyManager; - private RestrictionUtils mRestrictionUtils; - private PackageManager mPackageManager; - private Context mContext; - private MetricsFeatureProvider mMetricsFeatureProvider; + private final RestrictionUtils mRestrictionUtils; + private final PackageManager mPackageManager; + private final Context mContext; + private final MetricsFeatureProvider mMetricsFeatureProvider; @VisibleForTesting RestrictedSwitchPreference mPreference; @@ -62,19 +62,6 @@ public class AdaptiveSleepPreferenceController { mRestrictionUtils = restrictionUtils; mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mPrivacyManager = SensorPrivacyManager.getInstance(context); - mPreference = new RestrictedSwitchPreference(context); - mPreference.setTitle(R.string.adaptive_sleep_title); - mPreference.setSummary(R.string.adaptive_sleep_description); - mPreference.setChecked(isChecked()); - mPreference.setKey(PREFERENCE_KEY); - mPreference.setOnPreferenceClickListener(preference -> { - final boolean isChecked = ((RestrictedSwitchPreference) preference).isChecked(); - mMetricsFeatureProvider.action(context, SettingsEnums.ACTION_SCREEN_ATTENTION_CHANGED, - isChecked); - Settings.Secure.putInt(context.getContentResolver(), - Settings.Secure.ADAPTIVE_SLEEP, isChecked ? 1 : DEFAULT_VALUE); - return true; - }); mPackageManager = context.getPackageManager(); } @@ -86,6 +73,7 @@ public class AdaptiveSleepPreferenceController { * Adds the controlled preference to the provided preference screen. */ public void addToScreen(PreferenceScreen screen) { + initializePreference(); updatePreference(); screen.addPreference(mPreference); } @@ -103,6 +91,23 @@ public class AdaptiveSleepPreferenceController { } } + @VisibleForTesting + void initializePreference() { + mPreference = new RestrictedSwitchPreference(mContext); + mPreference.setTitle(R.string.adaptive_sleep_title); + mPreference.setSummary(R.string.adaptive_sleep_description); + mPreference.setChecked(isChecked()); + mPreference.setKey(PREFERENCE_KEY); + mPreference.setOnPreferenceChangeListener((preference, value) -> { + final boolean isChecked = (Boolean) value; + mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_SCREEN_ATTENTION_CHANGED, + isChecked); + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ADAPTIVE_SLEEP, isChecked ? 1 : DEFAULT_VALUE); + return true; + }); + } + @VisibleForTesting boolean isChecked() { return hasSufficientPermission(mContext.getPackageManager()) && !isCameraLocked() diff --git a/src/com/android/settings/display/ScreenTimeoutSettings.java b/src/com/android/settings/display/ScreenTimeoutSettings.java index 27e1e1bfc45..6dfb22529fe 100644 --- a/src/com/android/settings/display/ScreenTimeoutSettings.java +++ b/src/com/android/settings/display/ScreenTimeoutSettings.java @@ -71,11 +71,15 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements private CharSequence[] mInitialEntries; private CharSequence[] mInitialValues; private FooterPreference mPrivacyPreference; - private MetricsFeatureProvider mMetricsFeatureProvider; + private final MetricsFeatureProvider mMetricsFeatureProvider; private SensorPrivacyManager mPrivacyManager; + @VisibleForTesting + Context mContext; + @VisibleForTesting RestrictedLockUtils.EnforcedAdmin mAdmin; + @VisibleForTesting Preference mDisableOptionsPreference; @@ -97,6 +101,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements @Override public void onAttach(Context context) { super.onAttach(context); + mContext = context; mInitialEntries = getResources().getStringArray(R.array.screen_timeout_entries); mInitialValues = getResources().getStringArray(R.array.screen_timeout_values); mAdaptiveSleepController = new AdaptiveSleepPreferenceController(context); @@ -104,11 +109,6 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements context); mAdaptiveSleepCameraStatePreferenceController = new AdaptiveSleepCameraStatePreferenceController(context); - mPrivacyPreference = new FooterPreference(context); - mPrivacyPreference.setIcon(R.drawable.ic_privacy_shield_24dp); - mPrivacyPreference.setTitle(R.string.adaptive_sleep_privacy); - mPrivacyPreference.setSelectable(false); - mPrivacyPreference.setLayoutResource(R.layout.preference_footer); mPrivacyManager = SensorPrivacyManager.getInstance(context); mPrivacyManager.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> mAdaptiveSleepController.updatePreference()); @@ -167,6 +167,12 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements preferenceWithLargestTimeout.setChecked(true); } + mPrivacyPreference = new FooterPreference(mContext); + mPrivacyPreference.setIcon(R.drawable.ic_privacy_shield_24dp); + mPrivacyPreference.setTitle(R.string.adaptive_sleep_privacy); + mPrivacyPreference.setSelectable(false); + mPrivacyPreference.setLayoutResource(R.layout.preference_footer); + if (isScreenAttentionAvailable(getContext())) { mAdaptiveSleepPermissionController.addToScreen(screen); mAdaptiveSleepCameraStatePreferenceController.addToScreen(screen); diff --git a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java index 843870d0a9e..880f9ccdcaf 100644 --- a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java @@ -84,6 +84,7 @@ public class AdaptiveSleepPreferenceControllerTest { eq(UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT))).thenReturn(null); mController = new AdaptiveSleepPreferenceController(mContext, mRestrictionUtils); + mController.initializePreference(); when(mController.isCameraLocked()).thenReturn(false); } diff --git a/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java b/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java index c4f55808870..24bcde871e4 100644 --- a/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java +++ b/tests/robotests/src/com/android/settings/display/ScreenTimeoutSettingsTest.java @@ -60,8 +60,6 @@ public class ScreenTimeoutSettingsTest { private ScreenTimeoutSettings mSettings; private Context mContext; private ContentResolver mContentResolver; - - @Mock private Resources mResources; @Mock @@ -85,7 +83,9 @@ public class ScreenTimeoutSettingsTest { FakeFeatureFactory.setupForTest(); mContext = spy(getApplicationContext()); mSettings = spy(new ScreenTimeoutSettings()); + mSettings.mContext = mContext; mContentResolver = mContext.getContentResolver(); + mResources = spy(mContext.getResources()); doReturn(TIMEOUT_ENTRIES).when(mResources).getStringArray(R.array.screen_timeout_entries); doReturn(TIMEOUT_VALUES).when(mResources).getStringArray(R.array.screen_timeout_entries); From ac584f2911674822114e49fba9f2dc74e01485e2 Mon Sep 17 00:00:00 2001 From: Almaz Mingaleev Date: Thu, 29 Apr 2021 16:48:58 +0000 Subject: [PATCH 11/11] Place GeoTZ toggle under auto time zone toggle. This moves the two toggles that control the time zone detection behavior next to each other, rather than having them either side of the current device time zone. This is intended to making it clear they are both influencing detection behavior. It will ensure that future text we put under the auto time zone toggle for the tablet use case (where there is no telephony detection) explaining that "Use location to set time zone" has to be on will be right next to the toggle that needs to change. Bug: 152746236 Bug: 186625820 Test: flashed device, checked manually Change-Id: Ifd43db3d5cc7e764b12f8da20e552b1a5479ac4a --- res/xml/date_time_prefs.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml index 27311322e28..a0801f9df1b 100644 --- a/res/xml/date_time_prefs.xml +++ b/res/xml/date_time_prefs.xml @@ -48,6 +48,12 @@ settings:allowDividerAbove="true" settings:userRestriction="no_config_date_time"/> + + + - -