Snap for 9981223 from 76e769cdb0 to udc-release

Change-Id: I0897cbcd7786d7b7eafaf643b45d4cec25382cef
This commit is contained in:
Android Build Coastguard Worker
2023-04-20 23:28:17 +00:00
31 changed files with 413 additions and 184 deletions

View File

@@ -131,6 +131,7 @@
<uses-permission android:name="android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS" />
<uses-permission android:name="android.permission.CUSTOMIZE_SYSTEM_UI" />
<uses-permission android:name="android.permission.REMAP_MODIFIER_KEYS" />
<uses-permission android:name="android.permission.ACCESS_GPU_SERVICE" />
<application
android:name=".SettingsApplication"

View File

@@ -1,7 +1,7 @@
<!--
Copyright (C) 2017 The Android Open Source Project
Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
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
@@ -13,20 +13,15 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorError">
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11,7h2v2h-2z"/>
android:fillColor="?android:attr/colorAccent"
android:pathData="M13,17h-2v-2h2V17zM13,13h-2V8h2V13z"/>
<path
android:fillColor="#FF000000"
android:pathData="M11,11h2v6h-2z"/>
<path
android:fillColor="#FF000000"
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7z"/>
android:fillColor="?android:attr/colorAccent"
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
</vector>

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"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?android:attr/colorAccent"
android:pathData="M16.2,22.5H7.8c-1.3,0 -2.3,-1 -2.3,-2.3V5.8c0,-1.3 1,-2.3 2.3,-2.3h0.7v-2h7v2h0.7c1.3,0 2.3,1.1 2.3,2.3v14.3C18.5,21.5 17.5,22.5 16.2,22.5zM7.8,5.5c-0.2,0 -0.3,0.2 -0.3,0.3v14.3c0,0.2 0.2,0.3 0.3,0.3h8.3c0.2,0 0.3,-0.1 0.3,-0.3V5.8c0,-0.2 -0.1,-0.3 -0.3,-0.3h-2.7v-2h-3v2H7.8z"/>
<path
android:fillColor="?android:attr/colorAccent"
android:pathData="M16.1,11.1l-1.4,-1.5l-3.9,3.9l-1.5,-1.4l-1.4,1.4l2.9,2.9z"/>
</vector>

View File

@@ -1,5 +1,5 @@
<!--
Copyright (C) 2018 The Android Open Source Project
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.
@@ -13,19 +13,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#0F9D58"
android:fillColor="?android:attr/colorAccent"
android:pathData="M11,7h2v2h-2z"/>
<path
android:fillColor="#0F9D58"
android:fillColor="?android:attr/colorAccent"
android:pathData="M11,11h2v6h-2z"/>
<path
android:fillColor="#0F9D58"
android:fillColor="?android:attr/colorAccent"
android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7z"/>
</vector>

View File

@@ -14,12 +14,12 @@
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/listPreferredItemHeightSmall"
style="?attr/materialAlertDialogBodyTextStyle"
style="@style/SettingsLibActionButton"
android:gravity="center"
android:paddingTop="?attr/listPreferredItemPaddingStart"
android:paddingBottom="?attr/listPreferredItemPaddingEnd"

View File

@@ -19,6 +19,7 @@
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textDirection="locale"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:ellipsize="marquee"
android:gravity="center_vertical"

View File

@@ -5474,9 +5474,9 @@
<!-- [CHAR_LIMIT=NONE] Device screen on time category for a selected slot -->
<string name="screen_time_category_for_slot">Screen time for <xliff:g id="slot">%s</xliff:g></string>
<!-- [CHAR_LIMIT=NONE] The spinner item text in the battery usage breakdown. -->
<string name="battery_usage_spinner_breakdown_by_apps">Breakdown by apps</string>
<string name="battery_usage_spinner_by_apps">By apps</string>
<!-- [CHAR_LIMIT=NONE] The spinner item text in the battery usage breakdown. -->
<string name="battery_usage_spinner_breakdown_by_system">Breakdown by system</string>
<string name="battery_usage_spinner_by_systems">By systems</string>
<!-- [CHAR_LIMIT=NONE] Less than some percentage, e.g. < 1% -->
<string name="battery_usage_less_than_percent">&lt; <xliff:g id="percentage">%1$s</xliff:g></string>
<!-- Process Stats strings -->
@@ -9141,13 +9141,13 @@
<string name="filter_manage_external_storage">Can access all files</string>
<!-- Manage full screen intent permission title [CHAR LIMIT=40] -->
<string name="full_screen_intent_title">Manage full screen intents</string>
<string name="full_screen_intent_title">Show full screen notifications</string>
<!-- Label for setting that allows apps to send full screen intents. [CHAR LIMIT=NONE] -->
<string name="permit_full_screen_intent">Allow apps to send full screen intents</string>
<string name="permit_full_screen_intent">Allow app to show full screen notifications when the device is locked</string>
<!-- Description for setting that allows apps to send full screen intents. [CHAR LIMIT=NONE] -->
<string name="footer_description_full_screen_intent">Allow this app to send full screen intent notifications that cover the entire screen.</string>
<string name="footer_description_full_screen_intent">Allow the app to show notifications that take up the full screen when the device is locked. Apps may use these to highlight alarms, incoming calls, or other urgent notifications.</string>
<!-- Media management apps settings title [CHAR LIMIT=40] -->
<string name="media_management_apps_title">Media management apps</string>

View File

@@ -85,7 +85,7 @@
<Preference
android:key="battery"
android:title="@string/app_battery_usage_title"
android:title="@string/battery_details_title"
android:summary="@string/summary_placeholder" />
<Preference

View File

@@ -41,6 +41,8 @@ import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
import com.android.settingslib.utils.ThreadUtils;
import com.android.internal.content.PackageMonitor;
import android.util.IconDrawableFactory;
import android.util.Log;
@@ -236,20 +238,11 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
@OnLifecycleEvent(ON_CREATE)
void onCreate(LifecycleOwner lifecycleOwner) {
if (mCredentialManager == null) {
return;
}
setAvailableServices(
lifecycleOwner,
mCredentialManager.getCredentialProviderServices(
getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY),
null);
update();
}
@VisibleForTesting
void setAvailableServices(
LifecycleOwner lifecycleOwner,
List<CredentialProviderInfo> availableServices,
String flagOverrideForTest) {
mFlagOverrideForTest = flagOverrideForTest;
@@ -642,6 +635,40 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
void setActivityResult(int resultCode);
}
/**
* Monitor coming and going credman services and calls {@link #update()} when necessary
*/
private final PackageMonitor mSettingsPackageMonitor = new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> update());
}
@Override
public void onPackageModified(String packageName) {
ThreadUtils.postOnMainThread(() -> update());
}
@Override
public void onPackageRemoved(String packageName, int uid) {
ThreadUtils.postOnMainThread(() -> update());
}
};
/**
* Update the data in this UI.
*/
private void update() {
if (mCredentialManager == null) {
return;
}
setAvailableServices(
mCredentialManager.getCredentialProviderServices(
getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY),
null);
}
/** Dialog fragment parent class. */
private abstract static class CredentialManagerDialogFragment extends DialogFragment
implements DialogInterface.OnClickListener {

View File

@@ -281,12 +281,18 @@ public class AppLaunchSettings extends AppInfoBase implements
final List<String> verifiedLinksList = IntentPickerUtils.getLinksList(
mDomainVerificationManager, mPackageName, DOMAIN_STATE_VERIFIED);
return new AlertDialog.Builder(mContext)
AlertDialog dialog = new AlertDialog.Builder(mContext)
.setCustomTitle(titleView)
.setCancelable(true)
.setItems(verifiedLinksList.toArray(new String[0]), /* listener= */ null)
.setPositiveButton(R.string.app_launch_dialog_ok, /* listener= */ null)
.create();
if (dialog.getListView() != null) {
dialog.getListView().setTextDirection(View.TEXT_DIRECTION_LOCALE);
} else {
Log.w(TAG, "createVerifiedLinksDialog: dialog.getListView() is null, please check it.");
}
return dialog;
}
@VisibleForTesting

View File

@@ -17,6 +17,8 @@
package com.android.settings.applications.intentpicker;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -29,6 +31,7 @@ import java.util.List;
/** This adapter is for supported links dialog. */
public class SupportedLinksAdapter extends BaseAdapter {
private static final String TAG = "SupportedLinksAdapter";
private final Context mContext;
private final List<SupportedLinkWrapper> mWrapperList;
@@ -62,6 +65,14 @@ public class SupportedLinksAdapter extends BaseAdapter {
R.layout.supported_links_dialog_item, /* root= */ null);
}
final CheckedTextView textView = convertView.findViewById(android.R.id.text1);
Drawable[] drawables = textView.getCompoundDrawables();
if (mContext.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL && drawables[0] != null) {
Log.d(TAG, "getView: RTL direction.");
// Set a checkbox position. It is same as the android:drawableRight attribute.
textView.setCompoundDrawables(/* left= */ null, /* top= */ null, drawables[0],
/* bottom= */ null);
}
textView.setText(mWrapperList.get(position).getDisplayTitle(mContext));
textView.setEnabled(mWrapperList.get(position).isEnabled());
textView.setChecked(mWrapperList.get(position).isChecked());

View File

@@ -66,7 +66,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.viewmodel.CreationExtras;
@@ -194,11 +193,13 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
// fragment
setContentView(R.layout.biometric_enrollment_container);
final Fragment fragment = getSupportFragmentManager().findFragmentById(
R.id.fragment_container_view);
if (DEBUG) {
Log.e(TAG, "onCreate() has savedInstance:" + (savedInstanceState != null));
Log.d(TAG, "onCreate() has savedInstance:" + (savedInstanceState != null)
+ ", fragment:" + fragment);
}
if (savedInstanceState == null) {
Log.d(TAG, "onCreate()"); // Use to differentiate biometrics v2
if (fragment == null) {
checkCredential();
final EnrollmentRequest request = mViewModel.getRequest();
if (request.isSkipFindSensor()) {
@@ -209,42 +210,26 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
startIntroFragment();
}
} else {
final FragmentManager manager = getSupportFragmentManager();
String[] tags = new String[] {
FINISH_TAG,
ENROLLING_UDFPS_TAG,
ENROLLING_SFPS_TAG,
ENROLLING_RFPS_TAG,
FIND_UDFPS_TAG,
FIND_SFPS_TAG,
FIND_RFPS_TAG,
INTRO_TAG
};
for (String tag: tags) {
final Fragment fragment = manager.findFragmentByTag(tag);
if (fragment == null) {
continue;
}
if (DEBUG) {
Log.e(TAG, "onCreate() currentFragment:" + tag);
}
if (tag.equals(INTRO_TAG)) {
attachIntroViewModel();
} else if (tag.equals(FIND_UDFPS_TAG) || tag.equals(FIND_SFPS_TAG)
|| tag.equals(FIND_RFPS_TAG)) {
attachFindSensorViewModel();
attachIntroViewModel();
} else if (tag.equals(ENROLLING_UDFPS_TAG) || tag.equals(ENROLLING_SFPS_TAG)
|| tag.equals(ENROLLING_RFPS_TAG)) {
attachEnrollingViewModel();
attachFindSensorViewModel();
attachIntroViewModel();
} else { // FINISH_TAG
attachFinishViewModel();
attachFindSensorViewModel();
attachIntroViewModel();
}
break;
final String tag = fragment.getTag();
if (INTRO_TAG.equals(tag)) {
attachIntroViewModel();
} else if (FIND_UDFPS_TAG.equals(tag) || FIND_SFPS_TAG.equals(tag)
|| FIND_RFPS_TAG.equals(tag)) {
attachFindSensorViewModel();
attachIntroViewModel();
} else if (ENROLLING_UDFPS_TAG.equals(tag) || ENROLLING_SFPS_TAG.equals(tag)
|| ENROLLING_RFPS_TAG.equals(tag)) {
attachEnrollingViewModel();
attachFindSensorViewModel();
attachIntroViewModel();
} else if (FINISH_TAG.equals(tag)) {
attachFinishViewModel();
attachFindSensorViewModel();
attachIntroViewModel();
} else {
Log.e(TAG, "fragment tag " + tag + " not found");
finish();
return;
}
}

View File

@@ -88,8 +88,7 @@ public class PeakRefreshRatePreferenceController extends TogglePreferenceControl
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
int defaultPeakRefreshRate = mContext.getResources().getInteger(
com.android.internal.R.integer.config_defaultPeakRefreshRate);
int defaultPeakRefreshRate = Math.round(mPeakRefreshRate);
mPreference = screen.findPreference(getPreferenceKey());
mPreference.setSummary(mContext.getString(

View File

@@ -55,7 +55,7 @@ public class BatteryDefenderTip extends BatteryTip {
@Override
public int getIconId() {
return R.drawable.ic_battery_status_good_24dp;
return R.drawable.ic_battery_status_good_theme;
}
@Override

View File

@@ -71,7 +71,7 @@ public class HighUsageTip extends BatteryTip {
@Override
public int getIconId() {
return R.drawable.ic_perm_device_information_red_24dp;
return R.drawable.ic_perm_device_information_theme;
}
@Override

View File

@@ -48,7 +48,7 @@ public final class IncompatibleChargerTip extends BatteryTip {
@Override
public int getIconId() {
return R.drawable.ic_battery_alert_24dp;
return R.drawable.ic_battery_alert_theme;
}
@Override

View File

@@ -51,12 +51,7 @@ public class LowBatteryTip extends BatteryTip {
@Override
public int getIconId() {
return mState = R.drawable.ic_battery_status_bad_24dp;
}
@Override
public int getIconTintColorId() {
return mState = R.color.battery_bad_color_light;
return mState = R.drawable.ic_battery_saver_accent_24dp;
}
@Override

View File

@@ -93,8 +93,8 @@ public class RestrictAppTip extends BatteryTip {
@Override
public int getIconId() {
return mState == StateType.HANDLED
? R.drawable.ic_perm_device_information_green_24dp
: R.drawable.ic_battery_alert_24dp;
? R.drawable.ic_perm_device_information_theme
: R.drawable.ic_battery_alert_theme;
}
@Override

View File

@@ -48,7 +48,7 @@ public class SmartBatteryTip extends BatteryTip {
@Override
public int getIconId() {
return R.drawable.ic_perm_device_information_red_24dp;
return R.drawable.ic_perm_device_information_theme;
}
@Override

View File

@@ -177,8 +177,8 @@ public class BatteryUsageBreakdownController extends BasePreferenceController
mAppListPreferenceGroup.setOrderingAsAdded(false);
mSpinnerPreference.initializeSpinner(
new String[]{
mPrefContext.getString(R.string.battery_usage_spinner_breakdown_by_apps),
mPrefContext.getString(R.string.battery_usage_spinner_breakdown_by_system)
mPrefContext.getString(R.string.battery_usage_spinner_by_apps),
mPrefContext.getString(R.string.battery_usage_spinner_by_systems)
},
new AdapterView.OnItemSelectedListener() {
@Override

View File

@@ -43,7 +43,7 @@ public class AppDataSharingUpdatesPreferenceController extends BasePreferenceCon
private boolean isPrivacySafetyLabelChangeNotificationsEnabled(Context context) {
PackageManager packageManager = context.getPackageManager();
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED, false)
SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED, true)
&& !packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
&& !packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
&& !packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);

View File

@@ -22,7 +22,9 @@ import android.content.Intent;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.safetycenter.SafetyEvent;
import android.safetycenter.SafetySourceData;
import android.safetycenter.SafetySourceStatus;
@@ -43,8 +45,7 @@ public final class BiometricsSafetySource {
private static final int REQUEST_CODE_FACE_SETTING = 20;
private static final int REQUEST_CODE_FINGERPRINT_SETTING = 30;
private BiometricsSafetySource() {
}
private BiometricsSafetySource() {}
/** Sets biometric safety data for Safety Center. */
public static void setSafetySourceData(Context context, SafetyEvent safetyEvent) {
@@ -52,41 +53,59 @@ public final class BiometricsSafetySource {
return;
}
final int userId = UserHandle.myUserId();
final UserHandle userHandle = Process.myUserHandle();
final int userId = userHandle.getIdentifier();
final UserManager userManager = UserManager.get(context);
UserHandle profileParentUserHandle = userManager.getProfileParent(userHandle);
if (profileParentUserHandle == null) {
profileParentUserHandle = userHandle;
}
final Context profileParentContext =
context.createContextAsUser(profileParentUserHandle, 0);
final BiometricNavigationUtils biometricNavigationUtils = new BiometricNavigationUtils(
userId);
final BiometricNavigationUtils biometricNavigationUtils =
new BiometricNavigationUtils(userId);
final CombinedBiometricStatusUtils combinedBiometricStatusUtils =
new CombinedBiometricStatusUtils(context, userId);
final ActiveUnlockStatusUtils activeUnlockStatusUtils =
new ActiveUnlockStatusUtils(context);
if (activeUnlockStatusUtils.isAvailable()) {
if (!userManager.isProfile() && activeUnlockStatusUtils.isAvailable()) {
final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
combinedBiometricStatusUtils.getDisablingAdmin();
setBiometricSafetySourceData(context,
setBiometricSafetySourceData(
context,
activeUnlockStatusUtils.getTitleForActiveUnlock(),
combinedBiometricStatusUtils.getSummary(),
createPendingIntent(context,
biometricNavigationUtils.getBiometricSettingsIntent(context,
createPendingIntent(
context,
biometricNavigationUtils.getBiometricSettingsIntent(
context,
combinedBiometricStatusUtils.getSettingsClassName(),
disablingAdmin, Bundle.EMPTY),
disablingAdmin,
Bundle.EMPTY),
REQUEST_CODE_COMBINED_BIOMETRIC_SETTING),
disablingAdmin == null /* enabled */,
combinedBiometricStatusUtils.hasEnrolled(),
safetyEvent);
return;
}
if (combinedBiometricStatusUtils.isAvailable()) {
final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
combinedBiometricStatusUtils.getDisablingAdmin();
setBiometricSafetySourceData(context,
setBiometricSafetySourceData(
context,
combinedBiometricStatusUtils.getTitle(),
combinedBiometricStatusUtils.getSummary(),
createPendingIntent(context,
biometricNavigationUtils.getBiometricSettingsIntent(context,
combinedBiometricStatusUtils.getSettingsClassNameBasedOnUser(),
disablingAdmin, Bundle.EMPTY),
createPendingIntent(
profileParentContext,
biometricNavigationUtils
.getBiometricSettingsIntent(
context,
combinedBiometricStatusUtils
.getSettingsClassNameBasedOnUser(),
disablingAdmin,
Bundle.EMPTY)
.setIdentifier(Integer.toString(userId)),
REQUEST_CODE_COMBINED_BIOMETRIC_SETTING),
disablingAdmin == null /* enabled */,
combinedBiometricStatusUtils.hasEnrolled(),
@@ -100,13 +119,19 @@ public final class BiometricsSafetySource {
if (faceStatusUtils.isAvailable()) {
final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
faceStatusUtils.getDisablingAdmin();
setBiometricSafetySourceData(context,
setBiometricSafetySourceData(
context,
faceStatusUtils.getTitle(),
faceStatusUtils.getSummary(),
createPendingIntent(context,
biometricNavigationUtils.getBiometricSettingsIntent(context,
faceStatusUtils.getSettingsClassName(), disablingAdmin,
Bundle.EMPTY),
createPendingIntent(
profileParentContext,
biometricNavigationUtils
.getBiometricSettingsIntent(
context,
faceStatusUtils.getSettingsClassName(),
disablingAdmin,
Bundle.EMPTY)
.setIdentifier(Integer.toString(userId)),
REQUEST_CODE_FACE_SETTING),
disablingAdmin == null /* enabled */,
faceStatusUtils.hasEnrolled(),
@@ -116,19 +141,25 @@ public final class BiometricsSafetySource {
}
final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(context);
final FingerprintStatusUtils fingerprintStatusUtils = new FingerprintStatusUtils(context,
fingerprintManager, userId);
final FingerprintStatusUtils fingerprintStatusUtils =
new FingerprintStatusUtils(context, fingerprintManager, userId);
if (fingerprintStatusUtils.isAvailable()) {
final RestrictedLockUtils.EnforcedAdmin disablingAdmin =
fingerprintStatusUtils.getDisablingAdmin();
setBiometricSafetySourceData(context,
setBiometricSafetySourceData(
context,
fingerprintStatusUtils.getTitle(),
fingerprintStatusUtils.getSummary(),
createPendingIntent(context,
biometricNavigationUtils.getBiometricSettingsIntent(context,
fingerprintStatusUtils.getSettingsClassName(), disablingAdmin,
Bundle.EMPTY),
createPendingIntent(
profileParentContext,
biometricNavigationUtils
.getBiometricSettingsIntent(
context,
fingerprintStatusUtils.getSettingsClassName(),
disablingAdmin,
Bundle.EMPTY)
.setIdentifier(Integer.toString(userId)),
REQUEST_CODE_FINGERPRINT_SETTING),
disablingAdmin == null /* enabled */,
fingerprintStatusUtils.hasEnrolled(),
@@ -140,33 +171,38 @@ public final class BiometricsSafetySource {
public static void onBiometricsChanged(Context context) {
setSafetySourceData(
context,
new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()
);
new SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED)
.build());
}
private static void setBiometricSafetySourceData(Context context, String title, String summary,
PendingIntent pendingIntent, boolean enabled, boolean hasEnrolled,
private static void setBiometricSafetySourceData(
Context context,
String title,
String summary,
PendingIntent pendingIntent,
boolean enabled,
boolean hasEnrolled,
SafetyEvent safetyEvent) {
final int severityLevel =
enabled && hasEnrolled ? SafetySourceData.SEVERITY_LEVEL_INFORMATION
enabled && hasEnrolled
? SafetySourceData.SEVERITY_LEVEL_INFORMATION
: SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED;
final SafetySourceStatus status = new SafetySourceStatus.Builder(title, summary,
severityLevel).setPendingIntent(pendingIntent).setEnabled(enabled).build();
final SafetySourceStatus status =
new SafetySourceStatus.Builder(title, summary, severityLevel)
.setPendingIntent(pendingIntent)
.setEnabled(enabled)
.build();
final SafetySourceData safetySourceData =
new SafetySourceData.Builder().setStatus(status).build();
SafetyCenterManagerWrapper.get().setSafetySourceData(
context, SAFETY_SOURCE_ID, safetySourceData, safetyEvent);
SafetyCenterManagerWrapper.get()
.setSafetySourceData(context, SAFETY_SOURCE_ID, safetySourceData, safetyEvent);
}
private static PendingIntent createPendingIntent(Context context, Intent intent,
int requestCode) {
return PendingIntent
.getActivity(
context,
requestCode,
intent,
PendingIntent.FLAG_IMMUTABLE);
private static PendingIntent createPendingIntent(
Context context, Intent intent, int requestCode) {
return PendingIntent.getActivity(
context, requestCode, intent, PendingIntent.FLAG_IMMUTABLE);
}
}

View File

@@ -54,7 +54,7 @@ fun AppBatteryPreference(app: ApplicationInfo) {
if (!presenter.isAvailable()) return
Preference(object : PreferenceModel {
override val title = stringResource(R.string.app_battery_usage_title)
override val title = stringResource(R.string.battery_details_title)
override val summary = presenter.summary
override val enabled = presenter.enabled
override val onClick = presenter::startActivity

View File

@@ -41,6 +41,7 @@ import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.utils.CustomDialogHelper;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -74,6 +75,7 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
private static final int DIALOG_CONFIRM_RESET_GUEST = 4;
private static final int DIALOG_CONFIRM_RESET_GUEST_AND_SWITCH_USER = 5;
private static final int DIALOG_CONFIRM_REVOKE_ADMIN = 6;
private static final int DIALOG_CONFIRM_GRANT_ADMIN = 7;
/** Whether to enable the app_copying fragment. */
private static final boolean SHOW_APP_COPYING_PREF = false;
@@ -188,11 +190,12 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
mMetricsFeatureProvider.action(getActivity(),
SettingsEnums.ACTION_REVOKE_ADMIN_FROM_SETTINGS);
showDialog(DIALOG_CONFIRM_REVOKE_ADMIN);
return false;
} else {
mMetricsFeatureProvider.action(getActivity(),
SettingsEnums.ACTION_GRANT_ADMIN_FROM_SETTINGS);
showDialog(DIALOG_CONFIRM_GRANT_ADMIN);
}
mMetricsFeatureProvider.action(getActivity(),
SettingsEnums.ACTION_GRANT_ADMIN_FROM_SETTINGS);
updateUserAdminStatus(true);
return false;
}
return true;
}
@@ -208,6 +211,8 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
return SettingsEnums.DIALOG_USER_ENABLE_CALLING_AND_SMS;
case DIALOG_CONFIRM_REVOKE_ADMIN:
return SettingsEnums.DIALOG_REVOKE_USER_ADMIN;
case DIALOG_CONFIRM_GRANT_ADMIN:
return SettingsEnums.DIALOG_GRANT_USER_ADMIN;
case DIALOG_SETUP_USER:
return SettingsEnums.DIALOG_USER_SETUP;
default:
@@ -252,12 +257,54 @@ public class UserDetailsSettings extends SettingsPreferenceFragment
(dialog, which) -> switchUser());
}
case DIALOG_CONFIRM_REVOKE_ADMIN:
return UserDialogs.createConfirmRevokeAdmin(getActivity(),
(dialog, which) -> updateUserAdminStatus(false));
return createRevokeAdminDialog(getContext());
case DIALOG_CONFIRM_GRANT_ADMIN:
return createGrantAdminDialog(getContext());
}
throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
}
/**
* Creates dialog to confirm revoking admin rights.
* @return created confirmation dialog
*/
private Dialog createRevokeAdminDialog(Context context) {
CustomDialogHelper dialogHelper = new CustomDialogHelper(context);
dialogHelper.setIcon(
context.getDrawable(com.android.settingslib.R.drawable.ic_admin_panel_settings));
dialogHelper.setTitle(R.string.user_revoke_admin_confirm_title);
dialogHelper.setMessage(R.string.user_revoke_admin_confirm_message);
dialogHelper.setPositiveButton(R.string.remove, view -> {
updateUserAdminStatus(false);
dialogHelper.getDialog().dismiss();
});
dialogHelper.setBackButton(R.string.cancel, view -> {
dialogHelper.getDialog().dismiss();
});
return dialogHelper.getDialog();
}
/**
* Creates dialog to confirm granting admin rights.
* @return created confirmation dialog
*/
private Dialog createGrantAdminDialog(Context context) {
CustomDialogHelper dialogHelper = new CustomDialogHelper(context);
dialogHelper.setIcon(
context.getDrawable(com.android.settingslib.R.drawable.ic_admin_panel_settings));
dialogHelper.setTitle(com.android.settingslib.R.string.user_grant_admin_title);
dialogHelper.setMessage(com.android.settingslib.R.string.user_grant_admin_message);
dialogHelper.setPositiveButton(com.android.settingslib.R.string.user_grant_admin_button,
view -> {
updateUserAdminStatus(true);
dialogHelper.getDialog().dismiss();
});
dialogHelper.setBackButton(R.string.cancel, view -> {
dialogHelper.getDialog().dismiss();
});
return dialogHelper.getDialog();
}
/**
* Erase the current guest user and create a new one in the background. UserSettings will
* handle guest creation after receiving the {@link UserSettings.RESULT_GUEST_REMOVED} result.

View File

@@ -202,19 +202,4 @@ public final class UserDialogs {
.setNegativeButton(android.R.string.cancel, null)
.create();
}
/**
* Creates a dialog to confirm that the admin privileges of the user should be revoked.
*
* @param onConfirmListener Callback object for positive action
*/
public static Dialog createConfirmRevokeAdmin(Context context,
DialogInterface.OnClickListener onConfirmListener) {
return new AlertDialog.Builder(context)
.setTitle(R.string.user_revoke_admin_confirm_title)
.setMessage(R.string.user_revoke_admin_confirm_message)
.setPositiveButton(R.string.remove, onConfirmListener)
.setNegativeButton(android.R.string.cancel, null)
.create();
}
}

View File

@@ -85,7 +85,7 @@ public class BatteryDefenderTipTest {
@Test
public void getIcon_showIcon() {
assertThat(mBatteryDefenderTip.getIconId())
.isEqualTo(R.drawable.ic_battery_status_good_24dp);
.isEqualTo(R.drawable.ic_battery_status_good_theme);
}
@Test

View File

@@ -85,7 +85,7 @@ public final class IncompatibleChargerTipTest {
@Test
public void getIcon_showIcon() {
assertThat(mIncompatibleChargerTip.getIconId())
.isEqualTo(R.drawable.ic_battery_alert_24dp);
.isEqualTo(R.drawable.ic_battery_alert_theme);
}
@Test

View File

@@ -70,8 +70,7 @@ public class LowBatteryTipTest {
mContext.getString(R.string.battery_tip_low_battery_title));
assertThat(mLowBatteryTip.getSummary(mContext)).isEqualTo(
mContext.getString(R.string.battery_tip_low_battery_summary));
assertThat(mLowBatteryTip.getIconId()).isEqualTo(R.drawable.ic_battery_status_bad_24dp);
assertThat(mLowBatteryTip.getIconTintColorId()).isEqualTo(R.color.battery_bad_color_light);
assertThat(mLowBatteryTip.getIconId()).isEqualTo(R.drawable.ic_battery_saver_accent_24dp);
}
@Test

View File

@@ -101,7 +101,7 @@ class AppBatteryPreferenceTest {
setContent(notInstalledApp)
composeTestRule.onNode(hasTextExactly(context.getString(R.string.app_battery_usage_title)))
composeTestRule.onNode(hasTextExactly(context.getString(R.string.battery_details_title)))
.assertIsDisplayed()
.assertIsNotEnabled()
}
@@ -114,7 +114,7 @@ class AppBatteryPreferenceTest {
composeTestRule.onNode(
hasTextExactly(
context.getString(R.string.app_battery_usage_title),
context.getString(R.string.battery_details_title),
context.getString(R.string.no_battery_summary),
),
).assertIsDisplayed().assertIsEnabled()

View File

@@ -56,12 +56,15 @@ public class FingerprintEnrollmentActivityTest {
private static final String ACTIVITY_CLASS_NAME =
"com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity";
private static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow";
private static final String EXTRA_SKIP_INTRO = "skip_intro";
private static final String EXTRA_SKIP_FIND_SENSOR = "skip_find_sensor";
private static final String EXTRA_FROM_SETTINGS_SUMMARY = "from_settings_summary";
private static final String EXTRA_PAGE_TRANSITION_TYPE = "page_transition_type";
private static final String EXTRA_KEY_GK_PW_HANDLE = "gk_pw_handle";
private static final String TEST_PIN = "1234";
private static final String DO_IT_LATER = "Do it later";
private static final String UDFPS_ENROLLING_TITLE = "Touch & hold the fingerprint sensor";
private static final String SFPS_ENROLLING_TITLE =
"Lift, then touch. Move your finger slightly each time.";
@@ -120,6 +123,12 @@ public class FingerprintEnrollmentActivityTest {
mDevice.pressHome();
}
@After
public void tearDown() throws Exception {
LockScreenUtil.resetLockscreen(TEST_PIN);
mDevice.pressHome();
}
@Test
public void testIntroChooseLock() {
final Intent intent = newActivityIntent();
@@ -165,7 +174,7 @@ public class FingerprintEnrollmentActivityTest {
agreeBtn.click();
// FindUdfps page
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
assertThat(lottie).isNotNull();
@@ -193,7 +202,7 @@ public class FingerprintEnrollmentActivityTest {
agreeBtn.click();
// FindUdfps page
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
assertThat(lottie).isNotNull();
@@ -221,7 +230,7 @@ public class FingerprintEnrollmentActivityTest {
agreeBtn.click();
// FindSfps page
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
assertThat(lottie).isNotNull();
@@ -244,7 +253,7 @@ public class FingerprintEnrollmentActivityTest {
agreeBtn.click();
// FindRfps page
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
if (lottie == null) {
@@ -284,15 +293,15 @@ public class FingerprintEnrollmentActivityTest {
agreeBtn.click();
// FindSensor page
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
final UiObject2 doItLaterBtn = mDevice.findObject(By.text("Do it later"));
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
assertThat(doItLaterBtn).isNotNull();
assertThat(doItLaterBtn.isClickable()).isTrue();
doItLaterBtn.click();
// Back to home
mDevice.waitForWindowUpdate("com.android.settings", IDLE_TIMEOUT);
assertThat(mDevice.findObject(By.text("Do it later"))).isNull();
assertThat(mDevice.findObject(By.text(DO_IT_LATER))).isNull();
}
@Test
@@ -308,8 +317,8 @@ public class FingerprintEnrollmentActivityTest {
agreeBtn.click();
// FindSensor page
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
final UiObject2 doItLaterBtn = mDevice.findObject(By.text("Do it later"));
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
assertThat(doItLaterBtn).isNotNull();
assertThat(doItLaterBtn.isClickable()).isTrue();
doItLaterBtn.click();
@@ -325,7 +334,7 @@ public class FingerprintEnrollmentActivityTest {
// Back to home
mDevice.waitForWindowUpdate("com.android.settings", IDLE_TIMEOUT);
assertThat(mDevice.findObject(By.text("Skip anyway"))).isNull();
assertThat(mDevice.findObject(By.text("Do it later"))).isNull();
assertThat(mDevice.findObject(By.text(DO_IT_LATER))).isNull();
}
@Test
@@ -341,8 +350,8 @@ public class FingerprintEnrollmentActivityTest {
agreeBtn.click();
// FindSensor page
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
final UiObject2 doItLaterBtn = mDevice.findObject(By.text("Do it later"));
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
assertThat(doItLaterBtn).isNotNull();
assertThat(doItLaterBtn.isClickable()).isTrue();
doItLaterBtn.click();
@@ -356,7 +365,7 @@ public class FingerprintEnrollmentActivityTest {
goBackBtn.click();
// FindSensor page again
assertThat(mDevice.wait(Until.hasObject(By.text("Do it later")), IDLE_TIMEOUT)).isTrue();
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
}
@Test
@@ -447,10 +456,103 @@ public class FingerprintEnrollmentActivityTest {
assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
}
@After
public void tearDown() throws Exception {
LockScreenUtil.resetLockscreen(TEST_PIN);
mDevice.pressHome();
@Test
public void testFindUdfpsWithGkPwHandle_clickStart() {
assumeTrue(mCanAssumeUdfps);
LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
launchFindSensorWithGkPwHandle();
// FindUdfps page
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
assertThat(lottie).isNotNull();
assertThat(lottie.isClickable()).isTrue();
final UiObject2 startBtn = mDevice.findObject(By.text("Start"));
assertThat(startBtn.isClickable()).isTrue();
startBtn.click();
// Enrolling page
assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
}
@Test
public void testFindUdfpsWithGkPwHandle_clickLottie() {
assumeTrue(mCanAssumeUdfps);
LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
launchFindSensorWithGkPwHandle();
// FindUdfps page
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
assertThat(lottie).isNotNull();
assertThat(lottie.isClickable()).isTrue();
final UiObject2 startBtn = mDevice.findObject(By.text("Start"));
assertThat(startBtn.isClickable()).isTrue();
lottie.click();
// Enrolling page
assertThat(mDevice.wait(Until.hasObject(By.text(mEnrollingTitle)), IDLE_TIMEOUT)).isTrue();
}
@Test
public void testFindSfpsWithGkPwHandle() {
assumeTrue(mCanAssumeSfps);
LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
launchFindSensorWithGkPwHandle();
// FindSfps page
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
assertThat(lottie).isNotNull();
// We don't have view which can be clicked to run to next page, stop at here.
}
@Test
public void testFindRfpsWithGkPwHandle() {
assumeFalse(mCanAssumeUdfps || mCanAssumeSfps);
LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
launchFindSensorWithGkPwHandle();
// FindRfps page
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 lottie = mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"illustration_lottie"));
if (lottie == null) {
// FindSfps page shall have an animation view if no lottie view
assertThat(mDevice.findObject(By.res(SETTINGS_PACKAGE_NAME,
"fingerprint_sensor_location_animation"))).isNotNull();
}
}
@Test
public void testFindSensorWithGkPwHandle_clickSkipInFindSensor() {
LockScreenUtil.setLockscreen(LockScreenUtil.LockscreenType.PIN, TEST_PIN, true);
launchFindSensorWithGkPwHandle();
// FindSensor page
assertThat(mDevice.wait(Until.hasObject(By.text(DO_IT_LATER)), IDLE_TIMEOUT)).isTrue();
final UiObject2 doItLaterBtn = mDevice.findObject(By.text(DO_IT_LATER));
assertThat(doItLaterBtn).isNotNull();
assertThat(doItLaterBtn.isClickable()).isTrue();
doItLaterBtn.click();
// Back to home
mDevice.waitForWindowUpdate("com.android.settings", IDLE_TIMEOUT);
assertThat(mDevice.findObject(By.text(DO_IT_LATER))).isNull();
}
private void launchIntroWithGkPwHandle(boolean isSuw) {
@@ -469,6 +571,20 @@ public class FingerprintEnrollmentActivityTest {
userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback);
}
private void launchFindSensorWithGkPwHandle() {
LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
final LockscreenCredential lockscreenCredential = LockscreenCredential.createPin(TEST_PIN);
final int userId = UserHandle.myUserId();
final LockPatternChecker.OnVerifyCallback onVerifyCallback = (response, timeoutMs) -> {
final Intent intent = newActivityIntent();
intent.putExtra(EXTRA_SKIP_INTRO, true);
intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, response.getGatekeeperPasswordHandle());
mContext.startActivity(intent);
};
LockPatternChecker.verifyCredential(lockPatternUtils, lockscreenCredential,
userId, LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, onVerifyCallback);
}
private void launchEnrollingWithGkPwHandle() {
LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext);
final LockscreenCredential lockscreenCredential = LockscreenCredential.createPin(TEST_PIN);

View File

@@ -484,7 +484,7 @@ public class CredentialManagerPreferenceControllerTest {
CredentialManagerPreferenceController controller =
new CredentialManagerPreferenceController(
mContext, mCredentialsPreferenceCategory.getKey());
controller.setAvailableServices(() -> mock(Lifecycle.class), availableServices, addServiceOverride);
controller.setAvailableServices(availableServices, addServiceOverride);
controller.setDelegate(mDelegate);
return controller;
}