Snap for 9541950 from c88ad2f866 to udc-release

Change-Id: Ie2ad2cc62d85d9f81208247b41de9fb27d183310
This commit is contained in:
Android Build Coastguard Worker
2023-01-31 04:27:45 +00:00
28 changed files with 634 additions and 45 deletions

View File

@@ -3636,7 +3636,7 @@
android:label="@string/notification_channel_title"
android:theme="@style/Theme.Panel"
android:excludeFromRecents="true"
android:configChanges="orientation|keyboardHidden|screenSize"
android:configChanges="keyboardHidden|screenSize"
android:exported="true">
<intent-filter android:priority="1">
<action android:name="android.settings.CHANNEL_NOTIFICATION_SETTINGS" />

View File

@@ -245,6 +245,12 @@
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (tablet) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="tablet">Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase. \n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your tablet in different ways.</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (device) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your device in different ways.</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your phone in different ways.</string>
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set up fingerprint. (tablet) [CHAR LIMIT=NONE] -->
<string name="lock_screen_pin_skip_message" product="tablet">A PIN protects the tablet if it\u2019s lost or stolen</string>
<!-- Dialog text shown when the user tries to skip setting up a screen lock, warning that they can't continue to set up fingerprint. (tablet) [CHAR LIMIT=NONE] -->

View File

@@ -0,0 +1,24 @@
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:drawable="@drawable/ic_check_circle_filled_24dp" />
<item
android:state_checked="false"
android:drawable="@drawable/ic_circle_outline_24dp" />
</selector>

View File

@@ -0,0 +1,27 @@
<!--
~ Copyright (C) 2023 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"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?androidprv:attr/colorAccentPrimaryVariant">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10c5.52,0 10,-4.48 10,-10S17.52,2 12,2zM10.59,16.6l-4.24,-4.24l1.41,-1.41l2.83,2.83l5.66,-5.66l1.41,1.41L10.59,16.6z"/>
</vector>

View File

@@ -0,0 +1,26 @@
<!--
~ Copyright (C) 2023 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"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>

View File

@@ -19,12 +19,13 @@
android:width="18dp"
android:height="18dp"
android:viewportWidth="48"
android:viewportHeight="48">
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
<group>
<clip-path
android:pathData="M0,0h48v48H0z M 0,0"/>
<path
android:pathData="M46,11v29c0,4.4 -3.6,8 -8,8H23.4c-2.16,0 -4.2,-0.86 -5.7,-2.38L2,29.66s2.52,-2.46 2.6,-2.5c0.44,-0.38 0.98,-0.58 1.58,-0.58 0.44,0 0.84,0.12 1.2,0.32 0.08,0.02 8.62,4.92 8.62,4.92V8c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v14h2V3c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v19h2V5c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v17h2V11c0,-1.66 1.34,-3 3,-3s3,1.34 3,3z"
android:fillColor="#757575"/>
android:fillColor="#FFFFFF"/>
</group>
</vector>

View File

@@ -19,8 +19,9 @@
android:width="18dp"
android:height="18dp"
android:viewportWidth="48"
android:viewportHeight="48">
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
<path
android:pathData="M24,9C14,9 5.46,15.22 2,24c3.46,8.78 12,15 22,15 10.01,0 18.54,-6.22 22,-15 -3.46,-8.78 -11.99,-15 -22,-15zM24,34c-5.52,0 -10,-4.48 -10,-10s4.48,-10 10,-10 10,4.48 10,10 -4.48,10 -10,10zM24,18c-3.31,0 -6,2.69 -6,6s2.69,6 6,6 6,-2.69 6,-6 -2.69,-6 -6,-6z"
android:fillColor="#757575"/>
android:fillColor="#FFFFFF"/>
</vector>

View File

@@ -67,8 +67,31 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<CheckBox
android:id="@+id/auto_pin_confirm_enabler"
android:layout_marginTop="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:paddingLeft="14dp"
android:text="@string/auto_pin_confirm_user_message"
android:textSize="16sp"
android:button="@drawable/checkbox_circle_shape"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/auto_pin_confirm_security_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:text="@string/auto_pin_confirm_opt_in_security_message"
android:textSize="16sp"
android:visibility="gone" />
<Button
android:id="@+id/screen_lock_options"
style="@style/SudGlifButton.Tertiary"

View File

@@ -17,6 +17,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_content"
android:layout_height="@dimen/output_switcher_slice_max_height"
android:maxHeight="@dimen/output_switcher_slice_max_height"
android:background="@drawable/settings_panel_background"
android:orientation="vertical"
android:layout_width="match_parent">

View File

@@ -19,4 +19,5 @@
<dimen name="biometric_auth_pattern_view_size">248dp</dimen>
<dimen name="biometric_auth_pattern_view_max_size">348dp</dimen>
<dimen name="output_switcher_slice_max_height">300dp</dimen>
</resources>

View File

@@ -101,6 +101,14 @@
-->
</string-array>
<!-- List containing the component names of pre-installed speech services. -->
<string-array name="config_preinstalled_speech_services" translatable="false">
<!--
<item>com.example.package.first/com.example.class.FirstService</item>
<item>com.example.package.second/com.example.class.SecondService</item>
-->
</string-array>
<!-- List containing the component names of pre-installed interaction control services. -->
<string-array name="config_preinstalled_interaction_control_services" translatable="false">
<!--
@@ -109,8 +117,9 @@
-->
</string-array>
<!-- List containing the order of services in screen reader category by componentname.
All componentnames in a category need to be specified to guarantee correct behavior.-->
<!-- List containing the order of services in screen reader category by {@link ComponentName}.
All {@link ComponentName} in a category need to be specified to guarantee correct
behavior.-->
<string-array name="config_order_screen_reader_services" translatable="false">
<!--
<item>com.example.package.first/com.example.class.FirstService</item>
@@ -119,8 +128,8 @@
</string-array>
<!-- List containing the order of services in captions category by preference key or
componentname. All preference keys in a category need to be specified to guarantee correct
behavior.-->
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
correct behavior.-->
<string-array name="config_order_captions_services" translatable="false">
<!--
<item>com.example.package.first/com.example.class.FirstService</item>
@@ -131,8 +140,8 @@
-->
</string-array>
<!-- List containing the order of services in audio and caption category by preference key
or componentname. All preference keys in a category need to be specified to guarantee
<!-- List containing the order of services in audio and caption category by preference key or
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
correct behavior.-->
<string-array name="config_order_audio_services" translatable="false">
<!--
@@ -144,8 +153,8 @@
-->
</string-array>
<!-- List containing the order of services in display category by preference key
or componentname. All preference keys in a category need to be specified to guarantee
<!-- List containing the order of services in display category by preference key or
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
correct behavior.-->
<string-array name="config_order_display_services" translatable="false">
<!--
@@ -157,8 +166,21 @@
-->
</string-array>
<!-- List containing the order of services in interaction control category by preference key
or componentname. All preference keys in a category need to be specified to guarantee
<!-- List containing the order of services in speech category by preference key or
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
correct behavior.-->
<string-array name="config_order_speech_services" translatable="false">
<!--
<item>com.example.package.first/com.example.class.FirstService</item>
<item>com.example.package.second/com.example.class.SecondService</item>
<item>font_size_preference_screen</item>
<item>dark_ui_mode_accessibility</item>
<item>...</item>
-->
</string-array>
<!-- List containing the order of services in interaction control category by preference key or
{@link ComponentName}. All preference keys in a category need to be specified to guarantee
correct behavior.-->
<string-array name="config_order_interaction_control_services" translatable="false">
<!--

View File

@@ -932,18 +932,6 @@
<string name="security_settings_udfps_enroll_progress_a11y_message">Enrolling fingerprint <xliff:g id="percentage" example="10">%d</xliff:g> percent</string>
<!-- Title shown in fingerprint enrollment dialog once enrollment is completed [CHAR LIMIT=29] -->
<string name="security_settings_fingerprint_enroll_finish_title">Fingerprint added</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (tablet) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="tablet">Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (device) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (tablet) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="tablet">Now you can use your fingerprint to unlock your tablet or verify it\u2019s you, like when you sign in to apps or approve a purchase. \n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your tablet in different ways.</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (device) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="device">Now you can use your fingerprint to unlock your device or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your device in different ways.</string>
<!-- Message shown in fingerprint enrollment dialog once enrollment is completed (default) [CHAR LIMIT=NONE] -->
<string name="security_settings_fingerprint_enroll_finish_v2_add_fingerprint_message" product="default">Now you can use your fingerprint to unlock your phone or verify it\u2019s you, like when you sign in to apps or approve a purchase.\n\nAdd another fingerprint so it\u2019s easier to unlock when you hold your phone in different ways.</string>
<!-- Title for require screen on to auth toggle shown in fingerprint enrollment dialog once enrollment is completed. [CHAR LIMIT=NONE] -->
<string name="security_settings_require_screen_on_to_auth_title">Touch to unlock anytime</string>
<!-- Description for require screen on to auth toggle shown in fingerprint enrollment dialog once enrollment is completed. [CHAR LIMIT=NONE] -->
@@ -1102,6 +1090,15 @@
<!-- Title for dialog in screen lock settings, allowing users to choose other types of screen locks. [CHAR LIMIT=40] -->
<string name="setup_lock_settings_options_dialog_title">Screen lock options</string>
<!-- Title of the lock screen auto pin confirm setting. [CHAR LIMIT=NONE] -->
<string name="lock_screen_auto_pin_confirm_title">Auto-confirm unlock</string>
<!-- Summary of the lock screen auto pin confirm setting. [CHAR LIMIT=NONE] -->
<string name="lock_screen_auto_pin_confirm_summary">Unlock automatically if you input a correct PIN of 6 digits or more. This is slightly less secure than tapping Enter to confirm.</string>
<!-- Message shown to check auto pin confirmation feature when the user is updating the PIN. [CHAR LIMIT=NONE] -->
<string name="auto_pin_confirm_user_message">Auto-confirm correct PIN</string>
<!-- Message shown to explain the security concern if a user opts-in to the auto-pin feature. [CHAR LIMIT=NONE] -->
<string name="auto_pin_confirm_opt_in_security_message">Confirming your PIN by tapping Enter is more secure than using auto-confirm</string>
<!-- Main Security lock settings --><skip />
<!-- Title for PreferenceScreen to launch picker for security method when there is none [CHAR LIMIT=22] -->
<string name="unlock_set_unlock_launch_picker_title">Screen lock</string>
@@ -1262,6 +1259,12 @@
other {PIN must be at least # digits}
}</string>
<!-- Hint shown in dialog screen when PIN is too short with Additional text indicating minAutoConfirmLen(eg: 6) digits PIN offer additional security -->
<string name="lockpassword_pin_too_short_autoConfirm_extra_message">{count, plural,
=1 {PIN must contain at least # digit, but a {minAutoConfirmLen}-digit PIN is recommended for added security}
other {PIN must be at least # digits, but a {minAutoConfirmLen}-digit PIN is recommended for added security}
}</string>
<!-- Error shown in popup when password is too long -->
<string name="lockpassword_password_too_long">{count, plural,
=1 {Must be fewer than # character}

View File

@@ -169,6 +169,11 @@
</PreferenceCategory>
<PreferenceCategory
android:key="speech_category"
android:persistent="false"
android:title="@string/speech_category_title"/>
<PreferenceCategory
android:persistent="false"
android:title="@string/general_category_title">

View File

@@ -27,6 +27,12 @@
android:key="visiblepattern"
android:title="@string/lockpattern_settings_enable_visible_pattern_title" />
<!-- available in pin -->
<SwitchPreference
android:key="auto_pin_confirm"
android:title="@string/lock_screen_auto_pin_confirm_title"
android:summary="@string/lock_screen_auto_pin_confirm_summary" />
<!-- available in pin/pattern/password -->
<com.android.settings.display.TimeoutListPreference
android:key="lock_after_timeout"

View File

@@ -63,6 +63,7 @@ public class AccessibilitySettings extends DashboardFragment {
private static final String CATEGORY_SCREEN_READER = "screen_reader_category";
private static final String CATEGORY_CAPTIONS = "captions_category";
private static final String CATEGORY_AUDIO = "audio_category";
private static final String CATEGORY_SPEECH = "speech_category";
private static final String CATEGORY_DISPLAY = "display_category";
private static final String CATEGORY_DOWNLOADED_SERVICES = "user_installed_services_category";
@VisibleForTesting
@@ -70,7 +71,7 @@ public class AccessibilitySettings extends DashboardFragment {
private static final String[] CATEGORIES = new String[]{
CATEGORY_SCREEN_READER, CATEGORY_CAPTIONS, CATEGORY_AUDIO, CATEGORY_DISPLAY,
CATEGORY_INTERACTION_CONTROL, CATEGORY_DOWNLOADED_SERVICES
CATEGORY_SPEECH, CATEGORY_INTERACTION_CONTROL, CATEGORY_DOWNLOADED_SERVICES
};
// Extras passed to sub-fragments.
@@ -351,6 +352,8 @@ public class AccessibilitySettings extends DashboardFragment {
R.array.config_preinstalled_audio_services);
initializePreBundledServicesMapFromArray(CATEGORY_DISPLAY,
R.array.config_preinstalled_display_services);
initializePreBundledServicesMapFromArray(CATEGORY_SPEECH,
R.array.config_preinstalled_speech_services);
initializePreBundledServicesMapFromArray(CATEGORY_INTERACTION_CONTROL,
R.array.config_preinstalled_interaction_control_services);
@@ -390,6 +393,8 @@ public class AccessibilitySettings extends DashboardFragment {
R.array.config_order_interaction_control_services);
updateCategoryOrderFromArray(CATEGORY_DISPLAY,
R.array.config_order_display_services);
updateCategoryOrderFromArray(CATEGORY_SPEECH,
R.array.config_order_speech_services);
// Need to check each time when updateServicePreferences() called.
if (downloadedServicesCategory.getPreferenceCount() == 0) {
@@ -398,8 +403,9 @@ public class AccessibilitySettings extends DashboardFragment {
getPreferenceScreen().addPreference(downloadedServicesCategory);
}
// Hide screen reader category if it is empty.
// Hide category if it is empty.
updatePreferenceCategoryVisibility(CATEGORY_SCREEN_READER);
updatePreferenceCategoryVisibility(CATEGORY_SPEECH);
}
private List<RestrictedPreference> getInstalledAccessibilityList(Context context) {

View File

@@ -650,6 +650,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
new SubSettingLauncher(context)
.setDestination(destination.getName())
.setArguments(args)
.setUserHandle(UserHandle.getUserHandleForUid(app.uid))
.setSourceMetricsCategory(sourceMetricsCategory)
.launch();
}

View File

@@ -25,6 +25,7 @@ import androidx.preference.PreferenceScreen;
import com.android.settings.applications.AppStateBaseBridge;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.widget.AppCheckBoxPreference;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
@@ -126,9 +127,9 @@ public class BridgedAppsPreferenceController extends BasePreferenceController im
final AppEntry entry = apps.get(i);
final String prefKey = entry.info.packageName + "|" + entry.info.uid;
appsKeySet.add(prefKey);
CheckBoxPreference preference = mScreen.findPreference(prefKey);
AppCheckBoxPreference preference = mScreen.findPreference(prefKey);
if (preference == null) {
preference = new CheckBoxPreference(mScreen.getContext());
preference = new AppCheckBoxPreference(mScreen.getContext());
preference.setIcon(AppUtils.getIcon(mContext, entry));
preference.setTitle(entry.label);
preference.setKey(prefKey);

View File

@@ -49,10 +49,11 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory {
private static final String TAG = "BiometricsViewModelFact";
public static final CreationExtras.Key<ChallengeGenerator> CHALLENGE_GENERATOR_KEY =
new CreationExtras.Key<>() {};
new CreationExtras.Key<ChallengeGenerator>() {};
public static final CreationExtras.Key<EnrollmentRequest> ENROLLMENT_REQUEST_KEY =
new CreationExtras.Key<>() {};
public static final CreationExtras.Key<Integer> USER_ID_KEY = new CreationExtras.Key<>() {};
new CreationExtras.Key<EnrollmentRequest>() {};
public static final CreationExtras.Key<Integer> USER_ID_KEY =
new CreationExtras.Key<Integer>() {};
@NonNull
@Override

View File

@@ -71,6 +71,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.CheckBox;
import android.widget.ImeAwareEditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -101,7 +102,9 @@ import com.google.android.setupdesign.util.ThemeHelper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ChooseLockPassword extends SettingsActivity {
private static final String TAG = "ChooseLockPassword";
@@ -223,6 +226,8 @@ public class ChooseLockPassword extends SettingsActivity {
private static final String KEY_CURRENT_CREDENTIAL = "current_credential";
private static final String FRAGMENT_TAG_SAVE_AND_FINISH = "save_and_finish_worker";
private static final int MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6;
private LockscreenCredential mCurrentCredential;
private LockscreenCredential mChosenPassword;
private boolean mRequestGatekeeperPassword;
@@ -255,6 +260,9 @@ public class ChooseLockPassword extends SettingsActivity {
protected FooterButton mSkipOrClearButton;
private FooterButton mNextButton;
private TextView mMessage;
protected CheckBox mAutoPinConfirmOption;
protected TextView mAutoConfirmSecurityMessage;
protected boolean mIsAutoPinConfirmOptionSetManually;
private TextChangedHandler mTextChangedHandler;
@@ -515,6 +523,16 @@ public class ChooseLockPassword extends SettingsActivity {
mPasswordEntry.requestFocus();
mPasswordEntryInputDisabler = new TextViewInputDisabler(mPasswordEntry);
// Fetch the AutoPinConfirmOption
mAutoPinConfirmOption = view.findViewById(R.id.auto_pin_confirm_enabler);
mAutoConfirmSecurityMessage = view.findViewById(R.id.auto_pin_confirm_security_message);
mIsAutoPinConfirmOptionSetManually = false;
setOnAutoConfirmOptionClickListener();
if (mAutoPinConfirmOption != null) {
mAutoPinConfirmOption.setVisibility(View.GONE);
mAutoPinConfirmOption.setChecked(false);
}
final Activity activity = getActivity();
int currentType = mPasswordEntry.getInputType();
@@ -808,10 +826,22 @@ public class ChooseLockPassword extends SettingsActivity {
R.string.lockpassword_password_requires_nonnumerical));
break;
case TOO_SHORT:
messages.add(StringUtil.getIcuPluralsString(getContext(), error.requirement,
String message = StringUtil.getIcuPluralsString(getContext(),
error.requirement,
mIsAlphaMode
? R.string.lockpassword_password_too_short
: R.string.lockpassword_pin_too_short));
: R.string.lockpassword_pin_too_short);
if (mLockPatternUtils.isAutoPinConfirmFeatureAvailable()
&& !mIsAlphaMode
&& error.requirement < MIN_AUTO_PIN_REQUIREMENT_LENGTH) {
Map<String, Object> arguments = new HashMap<>();
arguments.put("count", error.requirement);
arguments.put("minAutoConfirmLen", MIN_AUTO_PIN_REQUIREMENT_LENGTH);
message = StringUtil.getIcuPluralsString(getContext(),
arguments,
R.string.lockpassword_pin_too_short_autoConfirm_extra_message);
}
messages.add(message);
break;
case TOO_SHORT_WHEN_ALL_NUMERIC:
messages.add(
@@ -864,6 +894,8 @@ public class ChooseLockPassword extends SettingsActivity {
String[] messages = convertErrorCodeToMessages();
// Update the fulfillment of requirements.
mPasswordRequirementAdapter.setRequirements(messages);
// set the visibility of pin_auto_confirm option accordingly
setAutoPinConfirmOption(passwordCompliant, length);
// Enable/Disable the next button accordingly.
setNextEnabled(passwordCompliant);
} else {
@@ -896,6 +928,36 @@ public class ChooseLockPassword extends SettingsActivity {
return visibleOrGone ? View.VISIBLE : View.GONE;
}
private void setAutoPinConfirmOption(boolean enabled, int length) {
if (!mLockPatternUtils.isAutoPinConfirmFeatureAvailable()
|| mAutoPinConfirmOption == null) {
return;
}
if (enabled && !mIsAlphaMode && isAutoPinConfirmPossible(length)) {
mAutoPinConfirmOption.setVisibility(View.VISIBLE);
mAutoConfirmSecurityMessage.setVisibility(View.VISIBLE);
if (!mIsAutoPinConfirmOptionSetManually) {
mAutoPinConfirmOption.setChecked(length == MIN_AUTO_PIN_REQUIREMENT_LENGTH);
}
} else {
mAutoPinConfirmOption.setVisibility(View.GONE);
mAutoConfirmSecurityMessage.setVisibility(View.GONE);
mAutoPinConfirmOption.setChecked(false);
}
}
private boolean isAutoPinConfirmPossible(int currentPinLength) {
return currentPinLength >= MIN_AUTO_PIN_REQUIREMENT_LENGTH;
}
private void setOnAutoConfirmOptionClickListener() {
if (mAutoPinConfirmOption != null) {
mAutoPinConfirmOption.setOnClickListener((v) -> {
mIsAutoPinConfirmOptionSetManually = true;
});
}
}
private void setHeaderText(String text) {
// Only set the text if it is different than the existing one to avoid announcing again.
if (!TextUtils.isEmpty(mLayout.getHeaderText())
@@ -951,6 +1013,10 @@ public class ChooseLockPassword extends SettingsActivity {
}
mSaveAndFinishWorker.start(mLockPatternUtils, mRequestGatekeeperPassword,
mChosenPassword, mCurrentCredential, mUserId);
// update the pin_auto_confirm setting accordingly.
mLockPatternUtils.setAutoPinConfirm(
(mAutoPinConfirmOption != null && mAutoPinConfirmOption.isChecked()),
mUserId);
}
@Override

View File

@@ -170,6 +170,12 @@ public class SetupChooseLockPassword extends ChooseLockPassword {
mOptionsButton.setVisibility(
mUiStage == Stage.Introduction ? View.VISIBLE : View.GONE);
}
// Visibility of auto pin confirm opt-in/out option should always be invisible.
if (mAutoPinConfirmOption != null) {
mAutoPinConfirmOption.setVisibility(View.GONE);
mAutoConfirmSecurityMessage.setVisibility(View.GONE);
}
}
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security.screenlock;
import android.content.Context;
import androidx.preference.Preference;
import androidx.preference.TwoStatePreference;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.AbstractPreferenceController;
/**
* Preference controller for the pin_auto_confirm setting.
*/
public class AutoPinConfirmPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
private static final String PREF_KEY_PIN_AUTO_CONFIRM = "auto_pin_confirm";
private static final long MIN_AUTO_PIN_REQUIREMENT_LENGTH = 6L;
private final int mUserId;
private final LockPatternUtils mLockPatternUtils;
public AutoPinConfirmPreferenceController(Context context, int userId,
LockPatternUtils lockPatternUtils) {
super(context);
mUserId = userId;
mLockPatternUtils = lockPatternUtils;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
setPinAutoConfirmSettingState((boolean) newValue);
return true;
}
@Override
public void updateState(Preference preference) {
((TwoStatePreference) preference).setChecked(getPinAutoConfirmSettingState());
}
@Override
public boolean isAvailable() {
return mLockPatternUtils.isAutoPinConfirmFeatureAvailable() && isPinLock()
&& isPinLengthEligibleForAutoConfirmation();
}
@Override
public String getPreferenceKey() {
return PREF_KEY_PIN_AUTO_CONFIRM;
}
private boolean isPinLock() {
return mLockPatternUtils.getCredentialTypeForUser(mUserId)
== LockPatternUtils.CREDENTIAL_TYPE_PIN;
}
private boolean isPinLengthEligibleForAutoConfirmation() {
return mLockPatternUtils.getPinLength(mUserId) >= MIN_AUTO_PIN_REQUIREMENT_LENGTH;
}
private boolean getPinAutoConfirmSettingState() {
return mLockPatternUtils.isAutoPinConfirmEnabled(mUserId);
}
private void setPinAutoConfirmSettingState(boolean state) {
mLockPatternUtils.setAutoPinConfirm(state, mUserId);
}
}

View File

@@ -75,6 +75,8 @@ public class ScreenLockSettings extends DashboardFragment
context, MY_USER_ID, lockPatternUtils));
controllers.add(new LockAfterTimeoutPreferenceController(
context, MY_USER_ID, lockPatternUtils));
controllers.add(new AutoPinConfirmPreferenceController(
context, MY_USER_ID, lockPatternUtils));
controllers.add(new OwnerInfoPreferenceController(context, parent));
return controllers;
}

View File

@@ -40,7 +40,9 @@ import com.android.settings.fuelgauge.batteryusage.BatteryChartPreferenceControl
import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spaprivileged.framework.common.asUser
import com.android.settingslib.spaprivileged.model.app.installed
import com.android.settingslib.spaprivileged.model.app.userHandle
import com.android.settingslib.spaprivileged.model.app.userId
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -63,6 +65,7 @@ fun AppBatteryPreference(app: ApplicationInfo) {
}
private class AppBatteryPresenter(private val context: Context, private val app: ApplicationInfo) {
private val userContext = context.asUser(app.userHandle)
private var batteryDiffEntryState: LoadingState<BatteryDiffEntry?>
by mutableStateOf(LoadingState.Loading)
@@ -84,7 +87,7 @@ private class AppBatteryPresenter(private val context: Context, private val app:
private suspend fun getBatteryDiffEntry(): BatteryDiffEntry? = withContext(Dispatchers.IO) {
BatteryChartPreferenceController.getAppBatteryUsageData(
context, app.packageName, app.userId
userContext, app.packageName, app.userId
).also {
Log.d(TAG, "loadBatteryDiffEntries():\n$it")
}
@@ -141,6 +144,7 @@ private class AppBatteryPresenter(private val context: Context, private val app:
.setDestination(AdvancedPowerUsageDetail::class.java.name)
.setTitleRes(R.string.battery_details_title)
.setArguments(args)
.setUserHandle(app.userHandle)
.setSourceMetricsCategory(AppInfoSettingsProvider.METRICS_CATEGORY)
.launch()
}

View File

@@ -98,7 +98,7 @@ public final class ScreenOnTimeControllerTest {
ArgumentCaptor<CharSequence> argumentCaptor = ArgumentCaptor.forClass(CharSequence.class);
verify(mScreenOnTimeTextPreference).setText(argumentCaptor.capture());
assertThat(argumentCaptor.getValue().toString()).isEqualTo("18 days, 12 hr, 27 min");
assertThat(argumentCaptor.getValue().toString()).isEqualTo("18 days 12 hr 27 min");
verify(mScreenOnTimeTextPreference).setVisible(true);
}
}

View File

@@ -27,8 +27,10 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import static android.provider.DeviceConfig.NAMESPACE_AUTO_PIN_CONFIRMATION;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static com.android.internal.widget.LockPatternUtils.FLAG_ENABLE_AUTO_PIN_CONFIRMATION;
import static com.android.internal.widget.LockPatternUtils.PASSWORD_TYPE_KEY;
import static com.android.settings.password.ChooseLockGeneric.CONFIRM_CREDENTIALS;
@@ -43,15 +45,21 @@ import android.app.admin.PasswordMetrics;
import android.app.admin.PasswordPolicy;
import android.content.Intent;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import com.android.internal.widget.LockscreenCredential;
import com.android.settings.R;
import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment;
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settings.widget.ScrollToParentEditText;
import com.google.android.setupdesign.GlifLayout;
@@ -71,9 +79,9 @@ import org.robolectric.shadows.ShadowDrawable;
ShadowLockPatternUtils.class,
ShadowUtils.class,
ShadowDevicePolicyManager.class,
ShadowDeviceConfig.class,
})
public class ChooseLockPasswordTest {
@Before
public void setUp() {
SettingsShadowResources.overrideResource(
@@ -387,7 +395,9 @@ public class ChooseLockPasswordTest {
}
@Test
public void processAndValidatePasswordRequirements_defaultPinMinimumLength() {
public void processAndValidatePasswordRequirements_autoPinDisabled_defaultPinMinimumLength() {
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
/* value= */ "false", /* makeDefault= */ false);
PasswordPolicy policy = new PasswordPolicy();
policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
@@ -399,6 +409,22 @@ public class ChooseLockPasswordTest {
"PIN must be at least 4 digits");
}
@Test
public void processAndValidatePasswordRequirements_autoPinEnabled_defaultPinMinimumLength() {
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
/* value= */ "true", /* makeDefault= */ false);
PasswordPolicy policy = new PasswordPolicy();
policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
assertPasswordValidationResult(
/* minMetrics */ policy.getMinMetrics(),
/* minComplexity= */ PASSWORD_COMPLEXITY_NONE,
/* passwordType= */ PASSWORD_QUALITY_NUMERIC,
/* userEnteredPassword= */ LockscreenCredential.createPassword("11"),
"PIN must be at least 4 digits"
+ ", but a 6-digit PIN is recommended for added security");
}
@Test
public void processAndValidatePasswordRequirements_maximumLength() {
PasswordPolicy policy = new PasswordPolicy();
@@ -424,6 +450,123 @@ public class ChooseLockPasswordTest {
"PIN must be at least 8 digits");
}
@Test
public void autoPinConfirmOption_featureEnabledAndUntouchedByUser_changeStateAsPerRules() {
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
/* value= */ "true", /* makeDefault= */ false);
ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
CheckBox pinAutoConfirmOption = passwordActivity
.findViewById(R.id.auto_pin_confirm_enabler);
TextView securityMessage =
passwordActivity.findViewById(R.id.auto_pin_confirm_security_message);
passwordEntry.setText("1234");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
passwordEntry.setText("123456");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(pinAutoConfirmOption.isChecked()).isTrue();
passwordEntry.setText("12345678");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
passwordEntry.setText("123456");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(pinAutoConfirmOption.isChecked()).isTrue();
}
@Test
public void autoPinConfirmOption_featureEnabledAndModifiedByUser_shouldChangeStateAsPerRules() {
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
/* value= */ "true", /* makeDefault= */ false);
ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
CheckBox pinAutoConfirmOption = passwordActivity
.findViewById(R.id.auto_pin_confirm_enabler);
TextView securityMessage =
passwordActivity.findViewById(R.id.auto_pin_confirm_security_message);
passwordEntry.setText("123456");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(pinAutoConfirmOption.isChecked()).isTrue();
pinAutoConfirmOption.performClick();
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
passwordEntry.setText("12345678");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
passwordEntry.setText("123456");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
}
@Test
public void autoPinConfirmOption_featureDisabled_shouldRemainInvisibleAndUnchecked() {
DeviceConfig.setProperty(NAMESPACE_AUTO_PIN_CONFIRMATION, FLAG_ENABLE_AUTO_PIN_CONFIRMATION,
/* value= */ "false", /* makeDefault= */ false);
ChooseLockPassword passwordActivity = setupActivityWithPinTypeAndDefaultPolicy();
ChooseLockPasswordFragment fragment = getChooseLockPasswordFragment(passwordActivity);
ScrollToParentEditText passwordEntry = passwordActivity.findViewById(R.id.password_entry);
CheckBox pinAutoConfirmOption = passwordActivity
.findViewById(R.id.auto_pin_confirm_enabler);
TextView securityMessage =
passwordActivity.findViewById(R.id.auto_pin_confirm_security_message);
passwordEntry.setText("1234");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
passwordEntry.setText("123456");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
passwordEntry.setText("12345678");
fragment.updateUi();
assertThat(pinAutoConfirmOption.getVisibility()).isEqualTo(View.GONE);
assertThat(securityMessage.getVisibility()).isEqualTo(View.GONE);
assertThat(pinAutoConfirmOption.isChecked()).isFalse();
}
private ChooseLockPassword setupActivityWithPinTypeAndDefaultPolicy() {
PasswordPolicy policy = new PasswordPolicy();
policy.quality = PASSWORD_QUALITY_UNSPECIFIED;
return buildChooseLockPasswordActivity(
new IntentBuilder(application)
.setUserId(UserHandle.myUserId())
.setPasswordType(PASSWORD_QUALITY_NUMERIC)
.setPasswordRequirement(PASSWORD_COMPLEXITY_NONE, policy.getMinMetrics())
.build());
}
private ChooseLockPassword buildChooseLockPasswordActivity(Intent intent) {
return Robolectric.buildActivity(ChooseLockPassword.class, intent).setup().get();
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.security.screenlock;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.widget.LockPatternUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class AutoPinConfirmPreferenceControllerTest {
private static final Integer TEST_USER_ID = 1;
@Mock
private LockPatternUtils mLockPatternUtils;
private AutoPinConfirmPreferenceController mController;
private SwitchPreference mPreference;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Context context = ApplicationProvider.getApplicationContext();
mController =
new AutoPinConfirmPreferenceController(context, TEST_USER_ID, mLockPatternUtils);
mPreference = new SwitchPreference(context);
}
@Test
public void isAvailable_featureEnabledAndLockSetToNone_shouldReturnFalse() {
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_featureEnabledAndLockSetToPassword_shouldReturnFalse() {
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_featureEnabledAndLockSetToPIN_lengthLessThanSix_shouldReturnFalse() {
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
when(mLockPatternUtils.getPinLength(TEST_USER_ID)).thenReturn(5L);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void isAvailable_featureEnabledAndLockSetToPIN_lengthMoreThanEqSix_shouldReturnTrue() {
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
when(mLockPatternUtils.getPinLength(TEST_USER_ID)).thenReturn(6L);
assertThat(mController.isAvailable()).isTrue();
}
@Test
public void isAvailable_featureDisabledAndLockSetToPIN_shouldReturnFalse() {
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(false);
when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
when(mLockPatternUtils.getCredentialTypeForUser(TEST_USER_ID))
.thenReturn(LockPatternUtils.CREDENTIAL_TYPE_PIN);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void updateState_ChangingSettingState_shouldSetPreferenceToAppropriateCheckedState() {
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
// When auto_pin_confirm setting is disabled, switchPreference is unchecked
when(mLockPatternUtils.isAutoPinConfirmEnabled(TEST_USER_ID)).thenReturn(false);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isFalse();
// When auto_pin_confirm setting is enabled, switchPreference is checked
when(mLockPatternUtils.isAutoPinConfirmEnabled(TEST_USER_ID)).thenReturn(true);
mController.updateState(mPreference);
assertThat(mPreference.isChecked()).isTrue();
}
@Test
public void onPreferenceChange_shouldUpdatePinAutoConfirmSetting() {
when(mLockPatternUtils.isAutoPinConfirmFeatureAvailable()).thenReturn(true);
mController.onPreferenceChange(mPreference, /* newValue= */ true);
verify(mLockPatternUtils).setAutoPinConfirm(true, TEST_USER_ID);
}
}

View File

@@ -36,6 +36,9 @@ import com.android.settings.R
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail
import com.android.settings.fuelgauge.batteryusage.BatteryChartPreferenceController
import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry
import com.android.settings.testutils.mockAsUser
import com.android.settingslib.spaprivileged.framework.common.asUser
import com.android.settingslib.spaprivileged.model.app.userHandle
import com.android.settingslib.spaprivileged.model.app.userId
import org.junit.After
import org.junit.Before
@@ -69,6 +72,7 @@ class AppBatteryPreferenceTest {
.mockStatic(AdvancedPowerUsageDetail::class.java)
.strictness(Strictness.LENIENT)
.startMocking()
context.mockAsUser()
whenever(context.resources).thenReturn(resources)
whenever(resources.getBoolean(R.bool.config_show_app_info_settings_battery))
.thenReturn(true)

View File

@@ -34,7 +34,6 @@ import android.os.Looper;
import android.service.notification.NotificationListenerFilter;
import android.util.ArraySet;
import androidx.preference.CheckBoxPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
@@ -42,6 +41,7 @@ import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.widget.AppCheckBoxPreference;
import com.android.settingslib.applications.ApplicationsState;
import org.junit.Before;
@@ -120,7 +120,7 @@ public class BridgedAppsPreferenceControllerTest {
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
when(mNm.getListenerFilter(mCn, 0)).thenReturn(new NotificationListenerFilter());
CheckBoxPreference p = mock(CheckBoxPreference.class);
AppCheckBoxPreference p = mock(AppCheckBoxPreference.class);
when(p.getKey()).thenReturn("pkg|12300");
mScreen.addPreference(p);
@@ -161,7 +161,7 @@ public class BridgedAppsPreferenceControllerTest {
mController.onRebuildComplete(entries);
CheckBoxPreference actual = mScreen.findPreference("pkg|12300");
AppCheckBoxPreference actual = mScreen.findPreference("pkg|12300");
assertThat(actual.isChecked()).isTrue();
assertThat(actual.getTitle()).isEqualTo("hi");
@@ -178,7 +178,7 @@ public class BridgedAppsPreferenceControllerTest {
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
CheckBoxPreference pref = new CheckBoxPreference(mContext);
AppCheckBoxPreference pref = new AppCheckBoxPreference(mContext);
pref.setKey("pkg|567");
mController.onPreferenceChange(pref, false);
@@ -204,7 +204,7 @@ public class BridgedAppsPreferenceControllerTest {
when(mNm.isNotificationListenerAccessGranted(mCn)).thenReturn(true);
when(mNm.getListenerFilter(mCn, 0)).thenReturn(nlf);
CheckBoxPreference pref = new CheckBoxPreference(mContext);
AppCheckBoxPreference pref = new AppCheckBoxPreference(mContext);
pref.setKey("pkg|567");
mController.onPreferenceChange(pref, true);