Snap for 10106040 from b8e02ef73f to udc-release
Change-Id: Ifef13bcf927e29821a12ee4b500e1f885d5026c8
This commit is contained in:
@@ -4868,22 +4868,6 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name=".notetask.shortcut.CreateNoteTaskShortcutActivity"
|
||||
android:enabled="false"
|
||||
android:exported="true"
|
||||
android:excludeFromRecents="true"
|
||||
android:resizeableActivity="false"
|
||||
android:theme="@android:style/Theme.NoDisplay"
|
||||
android:label="@string/note_task_shortcut_label"
|
||||
android:icon="@drawable/ic_note_task_shortcut_widget">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.CREATE_SHORTCUT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.android.settings.bluetooth.QrCodeScanModeActivity"
|
||||
android:permission="android.permission.BLUETOOTH_CONNECT"
|
||||
|
||||
@@ -15,7 +15,7 @@ message BatteryOptimizeHistoricalLogEntry {
|
||||
// The action to set optimize mode
|
||||
enum Action {
|
||||
UNKNOWN = 0;
|
||||
MANUAL = 1;
|
||||
LEAVE = 1;
|
||||
APPLY = 2;
|
||||
RESET = 3;
|
||||
RESTORE = 4;
|
||||
@@ -24,4 +24,5 @@ message BatteryOptimizeHistoricalLogEntry {
|
||||
optional string package_name = 1;
|
||||
optional Action action = 2;
|
||||
optional string action_description = 3;
|
||||
optional int64 timestamp = 4;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ 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="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
|
||||
<group>
|
||||
<path
|
||||
android:fillColor="#0B57D0"
|
||||
android:pathData="M48 24C48 10.7452 37.2548 0 24 0C10.7452 0 0 10.7452 0 24C0 37.2548 10.7452 48 24 48C37.2548 48 48 37.2548 48 24Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M37.692 16.8L36 15.108C35.556 14.652 34.944 14.4 34.308 14.4C33.672 14.4 33.06 14.652 32.616 15.108L23.268 24.456L20.508 27.216L19.248 32.28C19.212 32.352 19.2 32.448 19.2 32.532C19.2 33.12 19.68 33.6 20.268 33.6C20.352 33.6 20.448 33.588 20.532 33.564L25.596 32.304L28.356 29.544L37.704 20.196C38.148 19.74 38.4 19.128 38.4 18.492C38.4 17.856 38.148 17.244 37.692 16.8ZM26.652 27.852L25.452 29.052L23.76 27.36L24.96 26.16L34.308 16.8L36 18.492L26.652 27.852Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M17.825 33.6C12.257 33.6 10.2 31.9581 10.2 28.7351C10.2 25.8284 12.727 24.4472 16.656 23.8703C17.95 23.6802 18.6125 23.137 18.6125 22.5654C18.6125 20.9818 15.415 21.0788 14.4 21.0324V18.6C14.4 18.6 17.95 18.6 19.65 19.8923C20.5181 20.5521 21 21.4125 21 22.7149C21 24.5027 19.7375 25.9099 16.656 26.1633C14.6206 26.3307 12.6 26.9351 12.6 28.7351C12.6 30.3527 14.616 31.1676 18.6 31.1676L17.825 33.6Z" />
|
||||
</group>
|
||||
</vector>
|
||||
@@ -991,6 +991,8 @@
|
||||
<string name="setup_fingerprint_enroll_enrolling_skip_title">Skip fingerprint setup?</string>
|
||||
<!-- Content of the dialog shown when the user tries to skip fingerprint setup, asking them to confirm the action [CHAR LIMIT=NONE] -->
|
||||
<string name="setup_fingerprint_enroll_enrolling_skip_message">You\u2019ve chosen to use your fingerprint as one way to unlock your phone. If you skip now, you\u2019ll need to set this up later. Setup takes only a minute or so.</string>
|
||||
<!-- Title of dialog shown when the user tries to skip for setup screen lock, warning them of potential consequences of not doing so [CHAR LIMIT=48]-->
|
||||
<string name="lock_screen_skip_setup_title">Skip setup for <xliff:g id="options" example="PIN • Face • Fingerprint">%s</xliff:g>?</string>
|
||||
<!-- Title of dialog shown when the user tries to skip setting up a PIN, warning them of potential consequences of not doing so [CHAR LIMIT=48]-->
|
||||
<string name="lock_screen_pin_skip_title">Skip PIN setup?</string>
|
||||
<!-- Title of dialog shown when the user tries to skip setting up a PIN, warning them of potential consequences of not doing so [CHAR LIMIT=90]-->
|
||||
@@ -1088,7 +1090,7 @@
|
||||
<!-- Action label for the issue card in Safety Center when no screen lock is set [CHAR LIMIT=50] -->
|
||||
<string name="no_screen_lock_issue_action_label">Set screen lock</string>
|
||||
<!-- Title of the notification shown by Safety Center when no screen lock is set. This notification is shown in the notification shade, outside of the main Safety Center UI. [CHAR LIMIT=50] -->
|
||||
<string name="no_screen_lock_issue_notification_title">Device has no screen lock</string>
|
||||
<string name="no_screen_lock_issue_notification_title">Set a screen lock</string>
|
||||
<!-- Summary/body text of the notification shown by Safety Center when no screen lock is set. This notification is shown in the notification shade, outside of the main Safety Center UI. [CHAR LIMIT=NONE] -->
|
||||
<string name="no_screen_lock_issue_notification_text">For added security, set a PIN, pattern, or password for this device.</string>
|
||||
|
||||
@@ -2275,6 +2277,8 @@
|
||||
<string name="accessibility_category_work">Work profile accounts - <xliff:g id="managed_by" example="Managed by Corporate application">%s</xliff:g></string>
|
||||
<!-- Content description for personal profile accounts group [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_category_personal">Personal profile accounts</string>
|
||||
<!-- Content description for personal clone accounts group [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_category_clone">Clone profile accounts</string>
|
||||
<!-- Content description for work profile details page title [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_work_account_title">Work account - <xliff:g id="managed_by" example="Email provider">%s</xliff:g></string>
|
||||
<!-- Content description for personal profile details page title [CHAR LIMIT=NONE] -->
|
||||
@@ -12086,7 +12090,4 @@
|
||||
|
||||
<!-- Warning message when we try to dock an app not supporting multiple instances split into multiple sides [CHAR LIMIT=NONE] -->
|
||||
<string name="dock_multi_instances_not_supported_text">"This app can only be opened in 1 window"</string>
|
||||
|
||||
<!-- [CHAR LIMIT=30] Label used to open Note Task -->
|
||||
<string name="note_task_shortcut_label">Note shortcut</string>
|
||||
</resources>
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
package com.android.settings.accounts;
|
||||
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCESSIBILITY_CATEGORY_CLONE;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCESSIBILITY_CATEGORY_PERSONAL;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCESSIBILITY_CATEGORY_WORK;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.CLONE_CATEGORY_HEADER;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_BY;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_PROFILE_SETTINGS_TITLE;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_CATEGORY_HEADER;
|
||||
@@ -349,28 +351,34 @@ public class AccountPreferenceController extends AbstractPreferenceController
|
||||
preferenceGroup.setContentDescription(title);
|
||||
} else if (userInfo.isManagedProfile()) {
|
||||
if (mType == ProfileSelectFragment.ProfileType.ALL) {
|
||||
preferenceGroup.setTitle(
|
||||
mDpm.getResources().getString(WORK_CATEGORY_HEADER,
|
||||
() -> mContext.getString(R.string.category_work)));
|
||||
setCategoryTitleFromDevicePolicyResource(preferenceGroup, WORK_CATEGORY_HEADER,
|
||||
R.string.category_work);
|
||||
final String workGroupSummary = getWorkGroupSummary(context, userInfo);
|
||||
preferenceGroup.setSummary(workGroupSummary);
|
||||
preferenceGroup.setContentDescription(
|
||||
mDpm.getResources().getString(ACCESSIBILITY_CATEGORY_WORK, () ->
|
||||
mContext.getString(
|
||||
R.string.accessibility_category_work, workGroupSummary)));
|
||||
setContentDescriptionFromDevicePolicyResource(preferenceGroup,
|
||||
ACCESSIBILITY_CATEGORY_WORK, R.string.accessibility_category_work,
|
||||
workGroupSummary);
|
||||
}
|
||||
profileData.removeWorkProfilePreference = newRemoveWorkProfilePreference();
|
||||
mHelper.enforceRestrictionOnPreference(profileData.removeWorkProfilePreference,
|
||||
DISALLOW_REMOVE_MANAGED_PROFILE, UserHandle.myUserId());
|
||||
profileData.managedProfilePreference = newManagedProfileSettings();
|
||||
} else {
|
||||
} else if (userInfo.isCloneProfile()) {
|
||||
if (mType == ProfileSelectFragment.ProfileType.ALL) {
|
||||
preferenceGroup.setTitle(
|
||||
mDpm.getResources().getString(PERSONAL_CATEGORY_HEADER,
|
||||
() -> mContext.getString(R.string.category_personal)));
|
||||
preferenceGroup.setContentDescription(
|
||||
mDpm.getResources().getString(ACCESSIBILITY_CATEGORY_PERSONAL, () ->
|
||||
mContext.getString(R.string.accessibility_category_personal)));
|
||||
setCategoryTitleFromDevicePolicyResource(preferenceGroup, CLONE_CATEGORY_HEADER,
|
||||
R.string.category_clone);
|
||||
setContentDescriptionFromDevicePolicyResource(preferenceGroup,
|
||||
ACCESSIBILITY_CATEGORY_CLONE, R.string.accessibility_category_clone,
|
||||
null);
|
||||
}
|
||||
} else {
|
||||
// Primary Profile
|
||||
if (mType == ProfileSelectFragment.ProfileType.ALL) {
|
||||
setCategoryTitleFromDevicePolicyResource(preferenceGroup, PERSONAL_CATEGORY_HEADER,
|
||||
R.string.category_personal);
|
||||
setContentDescriptionFromDevicePolicyResource(preferenceGroup,
|
||||
ACCESSIBILITY_CATEGORY_PERSONAL, R.string.accessibility_category_personal,
|
||||
null);
|
||||
}
|
||||
}
|
||||
final PreferenceScreen screen = mFragment.getPreferenceScreen();
|
||||
@@ -381,13 +389,33 @@ public class AccountPreferenceController extends AbstractPreferenceController
|
||||
if (userInfo.isEnabled()) {
|
||||
profileData.authenticatorHelper = new AuthenticatorHelper(context,
|
||||
userInfo.getUserHandle(), this);
|
||||
profileData.addAccountPreference = newAddAccountPreference();
|
||||
mHelper.enforceRestrictionOnPreference(profileData.addAccountPreference,
|
||||
DISALLOW_MODIFY_ACCOUNTS, userInfo.id);
|
||||
if (!userInfo.isCloneProfile()) {
|
||||
profileData.addAccountPreference = newAddAccountPreference();
|
||||
mHelper.enforceRestrictionOnPreference(profileData.addAccountPreference,
|
||||
DISALLOW_MODIFY_ACCOUNTS, userInfo.id);
|
||||
}
|
||||
}
|
||||
mProfiles.put(userInfo.id, profileData);
|
||||
}
|
||||
|
||||
private void setCategoryTitleFromDevicePolicyResource(
|
||||
AccessiblePreferenceCategory preferenceGroup, String stringId, int resourceIdentifier) {
|
||||
preferenceGroup.setTitle(
|
||||
mDpm.getResources().getString(stringId,
|
||||
() -> mContext.getString(resourceIdentifier)));
|
||||
}
|
||||
|
||||
private void setContentDescriptionFromDevicePolicyResource(
|
||||
AccessiblePreferenceCategory preferenceGroup, String stringId, int resourceIdentifier,
|
||||
String formatArgs) {
|
||||
preferenceGroup.setContentDescription(mDpm.getResources().getString(stringId, () -> {
|
||||
if (formatArgs != null) {
|
||||
return mContext.getString(resourceIdentifier, formatArgs);
|
||||
}
|
||||
return mContext.getString(resourceIdentifier);
|
||||
}));
|
||||
}
|
||||
|
||||
private RestrictedPreference newAddAccountPreference() {
|
||||
RestrictedPreference preference =
|
||||
new RestrictedPreference(mFragment.getPreferenceManager().getContext());
|
||||
|
||||
@@ -620,6 +620,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
completeEnableProviderDialogBox(
|
||||
whichButton, packageName, setActivityResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {}
|
||||
};
|
||||
|
||||
return new NewProviderConfirmationDialogFragment(host, packageName, appName);
|
||||
@@ -666,6 +669,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
new DialogHost() {
|
||||
@Override
|
||||
public void onDialogClick(int whichButton) {}
|
||||
|
||||
@Override
|
||||
public void onCancel() {}
|
||||
};
|
||||
|
||||
return new ErrorDialogFragment(host);
|
||||
@@ -689,6 +695,12 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
pref.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
// If we dismiss the dialog then re-enable.
|
||||
pref.setChecked(true);
|
||||
}
|
||||
};
|
||||
|
||||
return new ConfirmationDialogFragment(host, packageName, appName);
|
||||
@@ -705,6 +717,8 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
/** Called when the dialog button is clicked. */
|
||||
private static interface DialogHost {
|
||||
void onDialogClick(int whichButton);
|
||||
|
||||
void onCancel();
|
||||
}
|
||||
|
||||
/** Called to send messages back to the parent fragment. */
|
||||
@@ -754,6 +768,11 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
public DialogHost getDialogHost() {
|
||||
return mDialogHost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(@NonNull DialogInterface dialog) {
|
||||
getDialogHost().onCancel();
|
||||
}
|
||||
}
|
||||
|
||||
/** Dialog showing error when too many providers are selected. */
|
||||
|
||||
@@ -156,7 +156,7 @@ public class DefaultCombinedPreferenceController extends DefaultAppPreferenceCon
|
||||
final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
|
||||
|
||||
// If there are multiple autofill services then pick the first one.
|
||||
if (mKey.startsWith(serviceInfo.packageName)) {
|
||||
if (mKey != null && mKey.startsWith(serviceInfo.packageName)) {
|
||||
final String settingsActivity;
|
||||
try {
|
||||
settingsActivity =
|
||||
|
||||
@@ -28,6 +28,8 @@ import android.hardware.face.FaceManager;
|
||||
import android.hardware.face.FaceSensorPropertiesInternal;
|
||||
import android.os.Bundle;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
@@ -38,6 +40,7 @@ import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
import com.android.settings.biometrics.face.FaceEnrollIntroduction;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
|
||||
@@ -45,6 +48,7 @@ import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction
|
||||
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
|
||||
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollIntroduction;
|
||||
import com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.password.ChooseLockGeneric;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.SetupChooseLockGeneric;
|
||||
@@ -60,6 +64,9 @@ import java.lang.annotation.RetentionPolicy;
|
||||
public class BiometricUtils {
|
||||
private static final String TAG = "BiometricUtils";
|
||||
|
||||
/** The character ' • ' to separate the setup choose options */
|
||||
public static final String SEPARATOR = " \u2022 ";
|
||||
|
||||
// Note: Theis IntDef must align SystemUI DevicePostureInt
|
||||
@IntDef(prefix = {"DEVICE_POSTURE_"}, value = {
|
||||
DEVICE_POSTURE_UNKNOWN,
|
||||
@@ -496,4 +503,45 @@ public class BiometricUtils {
|
||||
public static boolean isLandscape(@NonNull Context context) {
|
||||
return context.getDisplay().getRotation() == Surface.ROTATION_90;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the device supports Face enrollment in SUW flow
|
||||
*/
|
||||
public static boolean isFaceSupportedInSuw(Context context) {
|
||||
return FeatureFactory.getFactory(context).getFaceFeatureProvider().isSetupWizardSupported(
|
||||
context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the combined screen lock options by device biometrics config
|
||||
* @param context the application context
|
||||
* @param screenLock the type of screen lock(PIN, Pattern, Password) in string
|
||||
* @param hasFingerprint device support fingerprint or not
|
||||
* @param isFaceSupported device support face or not
|
||||
* @return the options combined with screen lock, face, and fingerprint in String format.
|
||||
*/
|
||||
public static String getCombinedScreenLockOptions(Context context,
|
||||
CharSequence screenLock, boolean hasFingerprint, boolean isFaceSupported) {
|
||||
final SpannableStringBuilder ssb = new SpannableStringBuilder();
|
||||
final BidiFormatter bidi = BidiFormatter.getInstance();
|
||||
// Assume the flow is "Screen Lock" + "Face" + "Fingerprint"
|
||||
ssb.append(bidi.unicodeWrap(screenLock));
|
||||
|
||||
if (isFaceSupported) {
|
||||
ssb.append(bidi.unicodeWrap(SEPARATOR));
|
||||
ssb.append(bidi.unicodeWrap(
|
||||
capitalize(context.getString(R.string.keywords_face_settings))));
|
||||
}
|
||||
|
||||
if (hasFingerprint) {
|
||||
ssb.append(bidi.unicodeWrap(SEPARATOR));
|
||||
ssb.append(bidi.unicodeWrap(
|
||||
capitalize(context.getString(R.string.security_settings_fingerprint))));
|
||||
}
|
||||
return ssb.toString();
|
||||
}
|
||||
|
||||
private static String capitalize(final String input) {
|
||||
return Character.toUpperCase(input.charAt(0)) + input.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,11 +165,7 @@ public class DataUsageList extends DataUsageBaseFragment
|
||||
}
|
||||
|
||||
processArgument();
|
||||
mMobileNetworkRepository = MobileNetworkRepository.getInstance(getContext());
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
mSubscriptionInfoEntity = mMobileNetworkRepository.getSubInfoById(
|
||||
String.valueOf(mSubId));
|
||||
});
|
||||
updateSubscriptionInfoEntity();
|
||||
mDataStateListener = new MobileDataEnabledListener(activity, this);
|
||||
}
|
||||
|
||||
@@ -294,6 +290,15 @@ public class DataUsageList extends DataUsageBaseFragment
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateSubscriptionInfoEntity() {
|
||||
mMobileNetworkRepository = MobileNetworkRepository.getInstance(getContext());
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
mSubscriptionInfoEntity = mMobileNetworkRepository.getSubInfoById(
|
||||
String.valueOf(mSubId));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@code MobileDataEnabledListener.Client}
|
||||
*/
|
||||
@@ -503,11 +508,13 @@ public class DataUsageList extends DataUsageBaseFragment
|
||||
Collections.sort(items);
|
||||
final List<String> packageNames = Arrays.asList(getContext().getResources().getStringArray(
|
||||
R.array.datausage_hiding_carrier_service_package_names));
|
||||
// When there is no specified SubscriptionInfo, Wi-Fi data usage will be displayed.
|
||||
// In this case, the carrier service package also needs to be hidden.
|
||||
boolean shouldHidePackageName = mSubscriptionInfoEntity != null
|
||||
? Arrays.stream(getContext().getResources().getIntArray(
|
||||
R.array.datausage_hiding_carrier_service_carrier_id))
|
||||
.anyMatch(carrierId -> (carrierId == mSubscriptionInfoEntity.carrierId))
|
||||
: false;
|
||||
: true;
|
||||
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
UidDetail detail = mUidDetailProvider.getUidDetail(items.get(i).key, true);
|
||||
|
||||
@@ -291,7 +291,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
|
||||
|
||||
BatteryHistoricalLogUtil.writeLog(
|
||||
getContext().getApplicationContext(),
|
||||
Action.MANUAL,
|
||||
Action.LEAVE,
|
||||
BatteryHistoricalLogUtil.getPackageNameWithUserId(
|
||||
mBatteryOptimizeUtils.getPackageName(), UserHandle.myUserId()),
|
||||
mLogStringBuilder.toString());
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.app.backup.BackupHelper;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.IDeviceIdleController;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
@@ -48,7 +47,6 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
/** An inditifier for {@link BackupHelper}. */
|
||||
public static final String TAG = "BatteryBackupHelper";
|
||||
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
|
||||
private static final boolean DEBUG = Build.TYPE.equals("userdebug");
|
||||
|
||||
static final String DELIMITER = ",";
|
||||
static final String DELIMITER_MODE = ":";
|
||||
@@ -119,7 +117,7 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
Log.e(TAG, "backupFullPowerList() failed", e);
|
||||
return null;
|
||||
}
|
||||
// Ignores unexpected emptty result case.
|
||||
// Ignores unexpected empty result case.
|
||||
if (allowlistedApps == null || allowlistedApps.length == 0) {
|
||||
Log.w(TAG, "no data found in the getFullPowerList()");
|
||||
return new ArrayList<>();
|
||||
@@ -145,8 +143,7 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
|
||||
// Converts application into the AppUsageState.
|
||||
for (ApplicationInfo info : applications) {
|
||||
final int mode = appOps.checkOpNoThrow(
|
||||
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, info.uid, info.packageName);
|
||||
final int mode = BatteryOptimizeUtils.getMode(appOps, info.uid, info.packageName);
|
||||
@BatteryOptimizeUtils.OptimizationMode
|
||||
final int optimizationMode = BatteryOptimizeUtils.getAppOptimizationMode(
|
||||
mode, allowlistedApps.contains(info.packageName));
|
||||
@@ -159,7 +156,7 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
final String packageOptimizeMode =
|
||||
info.packageName + DELIMITER_MODE + optimizationMode;
|
||||
builder.append(packageOptimizeMode + DELIMITER);
|
||||
debugLog(packageOptimizeMode);
|
||||
Log.d(TAG, "backupOptimizationMode: " + packageOptimizeMode);
|
||||
backupCount++;
|
||||
}
|
||||
|
||||
@@ -255,9 +252,8 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
}
|
||||
|
||||
private boolean isSystemOrDefaultApp(String packageName, int uid) {
|
||||
final PowerAllowlistBackend powerAllowlistBackend = getPowerAllowlistBackend();
|
||||
return powerAllowlistBackend.isSysAllowlisted(packageName)
|
||||
|| powerAllowlistBackend.isDefaultActiveApp(packageName, uid);
|
||||
return BatteryOptimizeUtils.isSystemOrDefaultApp(
|
||||
getPowerAllowlistBackend(), packageName, uid);
|
||||
}
|
||||
|
||||
private ArraySet<ApplicationInfo> getInstalledApplications() {
|
||||
@@ -267,10 +263,6 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
return BatteryOptimizeUtils.getInstalledApplications(mContext, getIPackageManager());
|
||||
}
|
||||
|
||||
private void debugLog(String debugContent) {
|
||||
if (DEBUG) Log.d(TAG, debugContent);
|
||||
}
|
||||
|
||||
private static void writeBackupData(
|
||||
BackupDataOutput data, String dataKey, String dataContent) {
|
||||
final byte[] dataContentBytes = dataContent.getBytes();
|
||||
@@ -283,6 +275,6 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
}
|
||||
|
||||
private static boolean isOwner() {
|
||||
return UserHandle.myUserId() == UserHandle.USER_OWNER;
|
||||
return UserHandle.myUserId() == UserHandle.USER_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.SharedPreferences;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
|
||||
import com.android.settings.fuelgauge.batteryusage.ConvertUtils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
@@ -49,6 +50,7 @@ public final class BatteryHistoricalLogUtil {
|
||||
.setPackageName(pkg)
|
||||
.setAction(action)
|
||||
.setActionDescription(actionDescription)
|
||||
.setTimestamp(System.currentTimeMillis())
|
||||
.build());
|
||||
}
|
||||
|
||||
@@ -89,6 +91,7 @@ public final class BatteryHistoricalLogUtil {
|
||||
if (logEntryList.isEmpty()) {
|
||||
writer.println("\tNo past logs.");
|
||||
} else {
|
||||
writer.println("0:RESTRICTED 1:UNRESTRICTED 2:OPTIMIZED 3:UNKNOWN");
|
||||
logEntryList.forEach(entry -> writer.println(toString(entry)));
|
||||
}
|
||||
}
|
||||
@@ -101,8 +104,9 @@ public final class BatteryHistoricalLogUtil {
|
||||
}
|
||||
|
||||
private static String toString(BatteryOptimizeHistoricalLogEntry entry) {
|
||||
return String.format("%s\tAction:%s\tEvent:%s",
|
||||
entry.getPackageName(), entry.getAction(), entry.getActionDescription());
|
||||
return String.format("%s\tAction:%s\tEvent:%s\tTimestamp:%s", entry.getPackageName(),
|
||||
entry.getAction(), entry.getActionDescription(),
|
||||
ConvertUtils.utcToLocalTimeForLogging(entry.getTimestamp()));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -83,8 +83,7 @@ public class BatteryOptimizeUtils {
|
||||
mAppOpsManager = context.getSystemService(AppOpsManager.class);
|
||||
mBatteryUtils = BatteryUtils.getInstance(context);
|
||||
mPowerAllowListBackend = PowerAllowlistBackend.getInstance(context);
|
||||
mMode = mAppOpsManager
|
||||
.checkOpNoThrow(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, mUid, mPackageName);
|
||||
mMode = getMode(mAppOpsManager, mUid, mPackageName);
|
||||
mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName, mUid);
|
||||
}
|
||||
|
||||
@@ -204,7 +203,12 @@ public class BatteryOptimizeUtils {
|
||||
return mPackageName == null ? UNKNOWN_PACKAGE : mPackageName;
|
||||
}
|
||||
|
||||
private static boolean isSystemOrDefaultApp(
|
||||
static int getMode(AppOpsManager appOpsManager, int uid, String packageName) {
|
||||
return appOpsManager.checkOpNoThrow(
|
||||
AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName);
|
||||
}
|
||||
|
||||
static boolean isSystemOrDefaultApp(
|
||||
PowerAllowlistBackend powerAllowlistBackend, String packageName, int uid) {
|
||||
return powerAllowlistBackend.isSysAllowlisted(packageName)
|
||||
|| powerAllowlistBackend.isDefaultActiveApp(packageName, uid);
|
||||
|
||||
@@ -67,9 +67,6 @@ public class BatteryTipLoader extends AsyncLoaderCompat<List<BatteryTip>> {
|
||||
|
||||
tips.add(new LowBatteryDetector(context, policy, batteryInfo, isPowerSaveMode).detect());
|
||||
tips.add(new HighUsageDetector(context, policy, mBatteryUsageStats, batteryInfo).detect());
|
||||
tips.add(new SmartBatteryDetector(
|
||||
context, policy, batteryInfo, context.getContentResolver(), isPowerSaveMode)
|
||||
.detect());
|
||||
tips.add(new BatteryDefenderDetector(batteryInfo, context).detect());
|
||||
tips.add(new DockDefenderDetector(batteryInfo, context).detect());
|
||||
tips.add(new IncompatibleChargerDetector(context).detect());
|
||||
|
||||
@@ -169,9 +169,11 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
|
||||
private void mapLanguageWithLayout(InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
CharSequence subtypeLabel = getSubtypeLabel(mContext, info, subtype);
|
||||
KeyboardLayout[] keyboardLayouts = getKeyboardLayouts(info, subtype);
|
||||
String layout = getKeyboardLayout(info, subtype);
|
||||
|
||||
KeyboardLayout[] keyboardLayouts =
|
||||
NewKeyboardSettingsUtils.getKeyboardLayouts(
|
||||
mIm, mUserId, mInputDeviceIdentifier, info, subtype);
|
||||
String layout = NewKeyboardSettingsUtils.getKeyboardLayout(
|
||||
mIm, mUserId, mInputDeviceIdentifier, info, subtype);
|
||||
if (layout != null) {
|
||||
for (int i = 0; i < keyboardLayouts.length; i++) {
|
||||
if (keyboardLayouts[i].getDescriptor().equals(layout)) {
|
||||
@@ -220,7 +222,6 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
preference -> {
|
||||
showKeyboardLayoutPicker(
|
||||
keyboardInfo.getSubtypeLabel(),
|
||||
keyboardInfo.getLayout(),
|
||||
mInputDeviceIdentifier,
|
||||
mUserId,
|
||||
keyboardInfo.getInputMethodInfo(),
|
||||
@@ -267,7 +268,6 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
|
||||
private void showKeyboardLayoutPicker(
|
||||
CharSequence subtypeLabel,
|
||||
String layout,
|
||||
InputDeviceIdentifier inputDeviceIdentifier,
|
||||
int userId,
|
||||
InputMethodInfo inputMethodInfo,
|
||||
@@ -281,7 +281,6 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
NewKeyboardSettingsUtils.EXTRA_INPUT_METHOD_SUBTYPE, inputMethodSubtype);
|
||||
arguments.putInt(NewKeyboardSettingsUtils.EXTRA_USER_ID, userId);
|
||||
arguments.putCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE, subtypeLabel);
|
||||
arguments.putString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT, layout);
|
||||
new SubSettingLauncher(mContext)
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.setDestination(NewKeyboardLayoutPickerFragment.class.getName())
|
||||
@@ -289,16 +288,6 @@ public class NewKeyboardLayoutEnabledLocalesFragment extends DashboardFragment
|
||||
.launch();
|
||||
}
|
||||
|
||||
private KeyboardLayout[] getKeyboardLayouts(InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
return mIm.getKeyboardLayoutListForInputDevice(
|
||||
mInputDeviceIdentifier, mUserId, info, subtype);
|
||||
}
|
||||
|
||||
private String getKeyboardLayout(InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
return mIm.getKeyboardLayoutForInputDevice(
|
||||
mInputDeviceIdentifier, mUserId, info, subtype);
|
||||
}
|
||||
|
||||
private CharSequence getSubtypeLabel(
|
||||
Context context, InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
return subtype.getDisplayName(
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputDeviceIdentifier;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.input.KeyboardLayout;
|
||||
import android.os.Bundle;
|
||||
import android.view.inputmethod.InputMethodInfo;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
@@ -31,28 +32,50 @@ public class NewKeyboardLayoutPickerContent extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "KeyboardLayoutPicker";
|
||||
|
||||
private InputManager mIm;
|
||||
private int mUserId;
|
||||
private InputDeviceIdentifier mIdentifier;
|
||||
private InputMethodInfo mInputMethodInfo;
|
||||
private InputMethodSubtype mInputMethodSubtype;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
InputManager inputManager = getContext().getSystemService(InputManager.class);
|
||||
mIm = getContext().getSystemService(InputManager.class);
|
||||
Bundle arguments = getArguments();
|
||||
final CharSequence title = arguments.getCharSequence(NewKeyboardSettingsUtils.EXTRA_TITLE);
|
||||
final String layout = arguments.getString(NewKeyboardSettingsUtils.EXTRA_KEYBOARD_LAYOUT);
|
||||
final int userId = arguments.getInt(NewKeyboardSettingsUtils.EXTRA_USER_ID);
|
||||
final InputDeviceIdentifier identifier =
|
||||
mUserId = arguments.getInt(NewKeyboardSettingsUtils.EXTRA_USER_ID);
|
||||
mIdentifier =
|
||||
arguments.getParcelable(NewKeyboardSettingsUtils.EXTRA_INPUT_DEVICE_IDENTIFIER);
|
||||
final InputMethodInfo inputMethodInfo =
|
||||
mInputMethodInfo =
|
||||
arguments.getParcelable(NewKeyboardSettingsUtils.EXTRA_INPUT_METHOD_INFO);
|
||||
final InputMethodSubtype inputMethodSubtype =
|
||||
mInputMethodSubtype =
|
||||
arguments.getParcelable(NewKeyboardSettingsUtils.EXTRA_INPUT_METHOD_SUBTYPE);
|
||||
if (identifier == null
|
||||
|| NewKeyboardSettingsUtils.getInputDevice(inputManager, identifier) == null) {
|
||||
if (mIdentifier == null
|
||||
|| NewKeyboardSettingsUtils.getInputDevice(mIm, mIdentifier) == null) {
|
||||
getActivity().finish();
|
||||
return;
|
||||
}
|
||||
getActivity().setTitle(title);
|
||||
use(NewKeyboardLayoutPickerController.class).initialize(this /*parent*/, userId,
|
||||
identifier, inputMethodInfo, inputMethodSubtype, layout);
|
||||
use(NewKeyboardLayoutPickerController.class).initialize(this /*parent*/, mUserId,
|
||||
mIdentifier, mInputMethodInfo, mInputMethodSubtype, getSelectedLayoutLabel());
|
||||
}
|
||||
|
||||
private String getSelectedLayoutLabel() {
|
||||
String label = getContext().getString(R.string.keyboard_default_layout);
|
||||
String layout = NewKeyboardSettingsUtils.getKeyboardLayout(
|
||||
mIm, mUserId, mIdentifier, mInputMethodInfo, mInputMethodSubtype);
|
||||
KeyboardLayout[] keyboardLayouts = NewKeyboardSettingsUtils.getKeyboardLayouts(
|
||||
mIm, mUserId, mIdentifier, mInputMethodInfo, mInputMethodSubtype);
|
||||
if (layout != null) {
|
||||
for (int i = 0; i < keyboardLayouts.length; i++) {
|
||||
if (keyboardLayouts[i].getDescriptor().equals(layout)) {
|
||||
label = keyboardLayouts[i].getLabel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.inputmethod;
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputDeviceIdentifier;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.input.KeyboardLayout;
|
||||
import android.view.InputDevice;
|
||||
import android.view.inputmethod.InputMethodInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@@ -39,7 +40,6 @@ public class NewKeyboardSettingsUtils {
|
||||
"com.android.settings.inputmethod.EXTRA_INTENT_FROM";
|
||||
|
||||
static final String EXTRA_TITLE = "keyboard_layout_picker_title";
|
||||
static final String EXTRA_KEYBOARD_LAYOUT = "keyboard_layout";
|
||||
static final String EXTRA_USER_ID = "user_id";
|
||||
static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier";
|
||||
static final String EXTRA_INPUT_METHOD_INFO = "input_method_info";
|
||||
@@ -117,4 +117,14 @@ public class NewKeyboardSettingsUtils {
|
||||
static InputDevice getInputDevice(InputManager im, InputDeviceIdentifier identifier) {
|
||||
return im.getInputDeviceByDescriptor(identifier.getDescriptor());
|
||||
}
|
||||
|
||||
static KeyboardLayout[] getKeyboardLayouts(InputManager inputManager, int userId,
|
||||
InputDeviceIdentifier identifier, InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
return inputManager.getKeyboardLayoutListForInputDevice(identifier, userId, info, subtype);
|
||||
}
|
||||
|
||||
static String getKeyboardLayout(InputManager inputManager, int userId,
|
||||
InputDeviceIdentifier identifier, InputMethodInfo info, InputMethodSubtype subtype) {
|
||||
return inputManager.getKeyboardLayoutForInputDevice(identifier, userId, info, subtype);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,12 +67,14 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
||||
private static final String SHOW_VIRTUAL_KEYBOARD_SWITCH = "show_virtual_keyboard_switch";
|
||||
private static final String KEYBOARD_SHORTCUTS_HELPER = "keyboard_shortcuts_helper";
|
||||
private static final String MODIFIER_KEYS_SETTINGS = "modifier_keys_settings";
|
||||
private static final String EXTRA_AUTO_SELECTION = "auto_selection";
|
||||
|
||||
@NonNull
|
||||
private final ArrayList<HardKeyboardDeviceInfo> mLastHardKeyboards = new ArrayList<>();
|
||||
|
||||
private InputManager mIm;
|
||||
private InputMethodManager mImm;
|
||||
private InputDeviceIdentifier mAutoInputDeviceIdentifier;
|
||||
@NonNull
|
||||
private PreferenceCategory mKeyboardAssistanceCategory;
|
||||
@NonNull
|
||||
@@ -84,6 +86,12 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
||||
static final String EXTRA_BT_ADDRESS = "extra_bt_address";
|
||||
private String mBluetoothAddress;
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putParcelable(EXTRA_AUTO_SELECTION, mAutoInputDeviceIdentifier);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle bundle, String s) {
|
||||
Activity activity = Preconditions.checkNotNull(getActivity());
|
||||
@@ -107,15 +115,19 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
||||
KeyboardLayoutPickerFragment.EXTRA_INPUT_DEVICE_IDENTIFIER);
|
||||
// TODO (b/271391879): The EXTRA_INTENT_FROM is used for the future metrics.
|
||||
if (inputDeviceIdentifier != null) {
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putParcelable(NewKeyboardSettingsUtils.EXTRA_INPUT_DEVICE_IDENTIFIER,
|
||||
inputDeviceIdentifier);
|
||||
new SubSettingLauncher(getContext())
|
||||
.setSourceMetricsCategory(getMetricsCategory())
|
||||
.setDestination(NewKeyboardLayoutEnabledLocalesFragment.class.getName())
|
||||
.setArguments(arguments)
|
||||
.launch();
|
||||
mAutoInputDeviceIdentifier = inputDeviceIdentifier;
|
||||
}
|
||||
// Don't repeat the autoselection.
|
||||
if (isAutoSelection(bundle, inputDeviceIdentifier)) {
|
||||
showEnabledLocalesKeyboardLayoutList(inputDeviceIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAutoSelection(Bundle bundle, InputDeviceIdentifier identifier) {
|
||||
if (bundle != null && bundle.getParcelable(EXTRA_AUTO_SELECTION) != null) {
|
||||
return false;
|
||||
}
|
||||
return identifier != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,7 +232,6 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
||||
pref.setOnPreferenceClickListener(
|
||||
preference -> {
|
||||
showEnabledLocalesKeyboardLayoutList(
|
||||
hardKeyboardDeviceInfo.mDeviceName,
|
||||
hardKeyboardDeviceInfo.mDeviceIdentifier);
|
||||
return true;
|
||||
});
|
||||
@@ -246,8 +257,7 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
|
||||
fragment.show(getActivity().getSupportFragmentManager(), "keyboardLayout");
|
||||
}
|
||||
|
||||
private void showEnabledLocalesKeyboardLayoutList(String keyboardName,
|
||||
InputDeviceIdentifier inputDeviceIdentifier) {
|
||||
private void showEnabledLocalesKeyboardLayoutList(InputDeviceIdentifier inputDeviceIdentifier) {
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putParcelable(NewKeyboardSettingsUtils.EXTRA_INPUT_DEVICE_IDENTIFIER,
|
||||
inputDeviceIdentifier);
|
||||
|
||||
@@ -17,24 +17,27 @@
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Fragment to show a confirm dialog. The caller should implement onConfirmListener. */
|
||||
public class ConfirmDialogFragment extends BaseDialogFragment
|
||||
@@ -136,28 +139,10 @@ public class ConfirmDialogFragment extends BaseDialogFragment
|
||||
dialogMessage.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
final ArrayAdapter<String> arrayAdapterItems = new ArrayAdapter<String>(
|
||||
getContext(),
|
||||
R.layout.sim_confirm_dialog_item_multiple_enabled_profiles_supported, list);
|
||||
final ListView lvItems = content.findViewById(R.id.carrier_list);
|
||||
if (lvItems != null) {
|
||||
lvItems.setVisibility(View.VISIBLE);
|
||||
lvItems.setAdapter(arrayAdapterItems);
|
||||
lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position,
|
||||
long id) {
|
||||
Log.i(TAG, "list onClick =" + position);
|
||||
Log.i(TAG, "list item =" + list.get(position));
|
||||
|
||||
if (position == list.size() - 1) {
|
||||
// user select the "cancel" item;
|
||||
informCaller(false, -1);
|
||||
} else {
|
||||
informCaller(true, position);
|
||||
}
|
||||
}
|
||||
});
|
||||
lvItems.setAdapter(new ButtonArrayAdapter(getContext(), list));
|
||||
}
|
||||
final LinearLayout infoOutline = content.findViewById(R.id.info_outline_layout);
|
||||
if (infoOutline != null) {
|
||||
@@ -197,4 +182,32 @@ public class ConfirmDialogFragment extends BaseDialogFragment
|
||||
}
|
||||
listener.onConfirm(getTagInCaller(), confirmed, itemPosition);
|
||||
}
|
||||
|
||||
private class ButtonArrayAdapter extends ArrayAdapter<String> {
|
||||
private final List<String> mList;
|
||||
|
||||
ButtonArrayAdapter(Context context, List<String> list) {
|
||||
super(context, R.layout.sim_confirm_dialog_item_multiple_enabled_profiles_supported,
|
||||
list);
|
||||
mList = list;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
View view = super.getView(position, convertView, parent);
|
||||
view.setOnClickListener(v -> {
|
||||
Log.i(TAG, "list onClick =" + position);
|
||||
Log.i(TAG, "list item =" + mList.get(position));
|
||||
|
||||
if (position == mList.size() - 1) {
|
||||
// user select the "cancel" item;
|
||||
informCaller(false, -1);
|
||||
} else {
|
||||
informCaller(true, position);
|
||||
}
|
||||
});
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* 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.notetask.shortcut
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.role.RoleManager
|
||||
import android.app.role.RoleManager.ROLE_NOTES
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Bundle
|
||||
import android.os.PersistableBundle
|
||||
import android.os.UserHandle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.core.content.getSystemService
|
||||
import com.android.settings.R
|
||||
|
||||
/**
|
||||
* Activity responsible for create a shortcut for notes action. If the shortcut is enabled, a new
|
||||
* shortcut will appear in the widget picker. If the shortcut is selected, the Activity here will be
|
||||
* launched, creating a new shortcut for [CreateNoteTaskShortcutActivity], and will finish.
|
||||
*
|
||||
* IMPORTANT! The shortcut package name and class should be synchronized with SystemUI controller:
|
||||
* [com.android.systemui.notetask.NoteTaskController#SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT].
|
||||
*
|
||||
* Changing the package name or class is a breaking change.
|
||||
*
|
||||
* @see <a
|
||||
* href="https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#custom-pinned">Creating
|
||||
* a custom shortcut activity</a>
|
||||
*/
|
||||
internal class CreateNoteTaskShortcutActivity : ComponentActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val roleManager = requireNotNull(getSystemService<RoleManager>())
|
||||
val shortcutManager = requireNotNull(getSystemService<ShortcutManager>())
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val shortcutInfo = roleManager.createNoteShortcutInfoAsUser(context = this, user)
|
||||
val shortcutIntent = shortcutManager.createShortcutResultIntent(shortcutInfo)
|
||||
setResult(Activity.RESULT_OK, shortcutIntent)
|
||||
|
||||
finish()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
private const val SHORTCUT_ID = "note_task_shortcut_id"
|
||||
private const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE =
|
||||
"extra_shortcut_badge_override_package"
|
||||
private const val ACTION_LAUNCH_NOTE_TASK = "com.android.systemui.action.LAUNCH_NOTE_TASK"
|
||||
|
||||
private fun RoleManager.createNoteShortcutInfoAsUser(
|
||||
context: Context,
|
||||
user: UserHandle,
|
||||
): ShortcutInfo? {
|
||||
val systemUiComponent = context.getSystemUiComponent() ?: return null
|
||||
|
||||
val extras = PersistableBundle()
|
||||
getDefaultRoleHolderAsUser(ROLE_NOTES, user)?.let { packageName ->
|
||||
// Set custom app badge using the icon from ROLES_NOTES default app.
|
||||
extras.putString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, packageName)
|
||||
}
|
||||
|
||||
val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
|
||||
|
||||
val intent = Intent(ACTION_LAUNCH_NOTE_TASK).apply {
|
||||
setPackage(systemUiComponent.packageName)
|
||||
}
|
||||
|
||||
// Creates a System UI context. That will let the ownership with SystemUI and allows it
|
||||
// to perform updates such as enabling or updating the badge override package.
|
||||
val systemUiContext = context.createPackageContext(
|
||||
systemUiComponent.packageName,
|
||||
/* flags */ 0,
|
||||
)
|
||||
|
||||
return ShortcutInfo.Builder(systemUiContext, SHORTCUT_ID)
|
||||
.setIntent(intent)
|
||||
.setShortLabel(context.getString(R.string.note_task_shortcut_label))
|
||||
.setLongLived(true)
|
||||
.setIcon(icon)
|
||||
.setExtras(extras)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun RoleManager.getDefaultRoleHolderAsUser(
|
||||
role: String,
|
||||
user: UserHandle,
|
||||
): String? = getRoleHoldersAsUser(role, user).firstOrNull()
|
||||
|
||||
private fun Context.getSystemUiComponent(): ComponentName? {
|
||||
val flattenName = getString(
|
||||
com.android.internal.R.string.config_systemUIServiceComponent)
|
||||
check(flattenName.isNotEmpty()) {
|
||||
"No 'com.android.internal.R.string.config_systemUIServiceComponent' resource"
|
||||
}
|
||||
return try {
|
||||
ComponentName.unflattenFromString(flattenName)
|
||||
} catch (e: RuntimeException) {
|
||||
val message = "Invalid component name defined by 'com.android.internal.R.string." +
|
||||
"config_systemUIServiceComponent' resource: $flattenName"
|
||||
throw IllegalStateException(message, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,8 +48,6 @@ import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.service.persistentdata.PersistentDataBlockManager;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
@@ -77,9 +75,9 @@ import com.android.settings.SetupWizardUtils;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.BiometricEnrollActivity;
|
||||
import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
import com.android.settings.biometrics.BiometricUtils;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.safetycenter.LockScreenSafetySource;
|
||||
import com.android.settings.search.SearchFeatureProvider;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
@@ -143,9 +141,6 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
*/
|
||||
public static final String EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS = "choose_lock_generic_extras";
|
||||
|
||||
/** The character ' • ' to separate the setup choose options */
|
||||
public static final String SEPARATOR = " \u2022 ";
|
||||
|
||||
@VisibleForTesting
|
||||
static final int CONFIRM_EXISTING_REQUEST = 100;
|
||||
@VisibleForTesting
|
||||
@@ -662,32 +657,20 @@ public class ChooseLockGeneric extends SettingsActivity {
|
||||
|
||||
@VisibleForTesting
|
||||
String getBiometricsPreferenceTitle(@NonNull ScreenLockType secureType) {
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder();
|
||||
BidiFormatter bidi = BidiFormatter.getInstance();
|
||||
final boolean hasFingerprint = Utils.hasFingerprintHardware(getContext());
|
||||
final boolean hasFace = Utils.hasFaceHardware(getContext());
|
||||
final boolean isSuw = WizardManagerHelper.isAnySetupWizard(getIntent());
|
||||
final boolean isFaceSupported =
|
||||
hasFace && (!isSuw || BiometricUtils.isFaceSupportedInSuw(getContext()));
|
||||
|
||||
// Assume the flow is "Screen Lock" + "Face" + "Fingerprint"
|
||||
if (mController != null) {
|
||||
ssb.append(bidi.unicodeWrap(mController.getTitle(secureType)));
|
||||
return BiometricUtils.getCombinedScreenLockOptions(getContext(),
|
||||
mController.getTitle(secureType), hasFingerprint, isFaceSupported);
|
||||
} else {
|
||||
Log.e(TAG, "ChooseLockGenericController is null!");
|
||||
return getResources().getString(R.string.error_title);
|
||||
}
|
||||
|
||||
if (mFaceManager != null && mFaceManager.isHardwareDetected() && isFaceSupported()) {
|
||||
ssb.append(bidi.unicodeWrap(SEPARATOR));
|
||||
ssb.append(bidi.unicodeWrap(
|
||||
getResources().getString(R.string.keywords_face_settings)));
|
||||
}
|
||||
if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
|
||||
ssb.append(bidi.unicodeWrap(SEPARATOR));
|
||||
ssb.append(bidi.unicodeWrap(
|
||||
getResources().getString(R.string.security_settings_fingerprint)));
|
||||
}
|
||||
return ssb.toString();
|
||||
}
|
||||
|
||||
private boolean isFaceSupported() {
|
||||
return FeatureFactory.getFactory(getContext().getApplicationContext())
|
||||
.getFaceFeatureProvider()
|
||||
.isSetupWizardSupported(getContext().getApplicationContext());
|
||||
}
|
||||
|
||||
private void setPreferenceTitle(ScreenLockType lock, @StringRes int title) {
|
||||
|
||||
@@ -64,6 +64,8 @@ public final class ChooseLockSettingsHelper {
|
||||
public static final String EXTRA_KEY_FOR_FACE = "for_face";
|
||||
// For the paths where multiple biometric sensors exist
|
||||
public static final String EXTRA_KEY_FOR_BIOMETRICS = "for_biometrics";
|
||||
// For the paths where setup biometrics in suw flow
|
||||
public static final String EXTRA_KEY_IS_SUW = "is_suw";
|
||||
public static final String EXTRA_KEY_FOREGROUND_ONLY = "foreground_only";
|
||||
public static final String EXTRA_KEY_REQUEST_GK_PW_HANDLE = "request_gk_pw_handle";
|
||||
// Gatekeeper password handle, which can subsequently be used to generate Gatekeeper
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.password;
|
||||
import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
|
||||
import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
|
||||
|
||||
import android.app.RemoteServiceException.MissingRequestPasswordComplexityPermissionException;
|
||||
@@ -43,6 +44,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.SetupWizardUtils;
|
||||
import com.android.settings.utils.SettingsDividerItemDecoration;
|
||||
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
import com.google.android.setupdesign.GlifPreferenceLayout;
|
||||
import com.google.android.setupdesign.util.ThemeHelper;
|
||||
|
||||
@@ -187,14 +189,14 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric {
|
||||
final String key = preference.getKey();
|
||||
if (KEY_UNLOCK_SET_DO_LATER.equals(key)) {
|
||||
// show warning.
|
||||
final Intent intent = getActivity().getIntent();
|
||||
SetupSkipDialog dialog = SetupSkipDialog.newInstance(
|
||||
getActivity().getIntent()
|
||||
.getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false),
|
||||
/* isPatternMode= */ false,
|
||||
/* isAlphaMode= */ false,
|
||||
CREDENTIAL_TYPE_NONE,
|
||||
intent.getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false),
|
||||
/* forFingerprint= */ false,
|
||||
/* forFace= */ false,
|
||||
/* forBiometrics= */ false
|
||||
/* forBiometrics= */ false,
|
||||
WizardManagerHelper.isAnySetupWizard(intent)
|
||||
);
|
||||
dialog.show(getFragmentManager());
|
||||
return true;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.settings.password;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -31,6 +34,8 @@ import com.android.settings.R;
|
||||
import com.android.settings.SetupRedactionInterstitial;
|
||||
import com.android.settings.password.ChooseLockTypeDialogFragment.OnLockTypeSelectedListener;
|
||||
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
|
||||
/**
|
||||
* Setup Wizard's version of ChooseLockPassword screen. It inherits the logic and basic structure
|
||||
* from ChooseLockPassword class, and should remain similar to that behaviorally. This class should
|
||||
@@ -113,12 +118,12 @@ public class SetupChooseLockPassword extends ChooseLockPassword {
|
||||
final boolean forBiometrics = intent
|
||||
.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false);
|
||||
final SetupSkipDialog dialog = SetupSkipDialog.newInstance(
|
||||
mIsAlphaMode ? CREDENTIAL_TYPE_PASSWORD : CREDENTIAL_TYPE_PIN,
|
||||
frpSupported,
|
||||
/* isPatternMode= */ false,
|
||||
mIsAlphaMode,
|
||||
forFingerprint,
|
||||
forFace,
|
||||
forBiometrics);
|
||||
forBiometrics,
|
||||
WizardManagerHelper.isAnySetupWizard(intent));
|
||||
|
||||
ConfirmDeviceCredentialUtils.hideImeImmediately(
|
||||
getActivity().getWindow().getDecorView());
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.settings.password;
|
||||
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -32,6 +34,8 @@ import androidx.fragment.app.Fragment;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SetupRedactionInterstitial;
|
||||
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
|
||||
/**
|
||||
* Setup Wizard's version of ChooseLockPattern screen. It inherits the logic and basic structure
|
||||
* from ChooseLockPattern class, and should remain similar to that behaviorally. This class should
|
||||
@@ -101,14 +105,13 @@ public class SetupChooseLockPattern extends ChooseLockPattern {
|
||||
.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false);
|
||||
final boolean forBiometrics = intent
|
||||
.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false);
|
||||
|
||||
final SetupSkipDialog dialog = SetupSkipDialog.newInstance(
|
||||
CREDENTIAL_TYPE_PATTERN,
|
||||
frpSupported,
|
||||
/* isPatternMode= */ true,
|
||||
/* isAlphaMode= */ false,
|
||||
forFingerprint,
|
||||
forFace,
|
||||
forBiometrics);
|
||||
forBiometrics,
|
||||
WizardManagerHelper.isAnySetupWizard(intent));
|
||||
dialog.show(getFragmentManager());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
package com.android.settings.password;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_SUW;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
@@ -29,7 +37,10 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.BiometricUtils;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
|
||||
public class SetupSkipDialog extends InstrumentedDialogFragment
|
||||
@@ -38,24 +49,23 @@ public class SetupSkipDialog extends InstrumentedDialogFragment
|
||||
public static final String EXTRA_FRP_SUPPORTED = ":settings:frp_supported";
|
||||
|
||||
private static final String ARG_FRP_SUPPORTED = "frp_supported";
|
||||
// The key indicates type of lock screen is pattern setup.
|
||||
private static final String ARG_LOCK_TYPE_PATTERN = "lock_type_pattern";
|
||||
// The key indicates type of screen lock credential types(PIN/Pattern/Password)
|
||||
private static final String ARG_LOCK_CREDENTIAL_TYPE = "lock_credential_type";
|
||||
// The key indicates type of lock screen setup is alphanumeric for password setup.
|
||||
private static final String ARG_LOCK_TYPE_ALPHANUMERIC = "lock_type_alphanumeric";
|
||||
private static final String TAG_SKIP_DIALOG = "skip_dialog";
|
||||
public static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10;
|
||||
|
||||
public static SetupSkipDialog newInstance(boolean isFrpSupported, boolean isPatternMode,
|
||||
boolean isAlphanumericMode, boolean forFingerprint, boolean forFace,
|
||||
boolean forBiometrics) {
|
||||
public static SetupSkipDialog newInstance(@LockPatternUtils.CredentialType int credentialType,
|
||||
boolean isFrpSupported, boolean forFingerprint, boolean forFace,
|
||||
boolean forBiometrics, boolean isSuw) {
|
||||
SetupSkipDialog dialog = new SetupSkipDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_LOCK_CREDENTIAL_TYPE, credentialType);
|
||||
args.putBoolean(ARG_FRP_SUPPORTED, isFrpSupported);
|
||||
args.putBoolean(ARG_LOCK_TYPE_PATTERN, isPatternMode);
|
||||
args.putBoolean(ARG_LOCK_TYPE_ALPHANUMERIC, isAlphanumericMode);
|
||||
args.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, forFingerprint);
|
||||
args.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, forFace);
|
||||
args.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, forBiometrics);
|
||||
args.putBoolean(EXTRA_KEY_FOR_FINGERPRINT, forFingerprint);
|
||||
args.putBoolean(EXTRA_KEY_FOR_FACE, forFace);
|
||||
args.putBoolean(EXTRA_KEY_FOR_BIOMETRICS, forBiometrics);
|
||||
args.putBoolean(EXTRA_KEY_IS_SUW, isSuw);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
@@ -70,59 +80,59 @@ public class SetupSkipDialog extends InstrumentedDialogFragment
|
||||
return onCreateDialogBuilder().create();
|
||||
}
|
||||
|
||||
private AlertDialog.Builder getBiometricsBuilder(
|
||||
@LockPatternUtils.CredentialType int credentialType, boolean isSuw, boolean hasFace,
|
||||
boolean hasFingerprint) {
|
||||
final boolean isFaceSupported = hasFace && (!isSuw || BiometricUtils.isFaceSupportedInSuw(
|
||||
getContext()));
|
||||
final int msgResId;
|
||||
final int screenLockResId;
|
||||
switch (credentialType) {
|
||||
case CREDENTIAL_TYPE_PATTERN:
|
||||
screenLockResId = R.string.unlock_set_unlock_pattern_title;
|
||||
msgResId = getPatternSkipMessageRes(hasFace && isFaceSupported, hasFingerprint);
|
||||
break;
|
||||
case CREDENTIAL_TYPE_PASSWORD:
|
||||
screenLockResId = R.string.unlock_set_unlock_password_title;
|
||||
msgResId = getPasswordSkipMessageRes(hasFace && isFaceSupported, hasFingerprint);
|
||||
break;
|
||||
case CREDENTIAL_TYPE_PIN:
|
||||
default:
|
||||
screenLockResId = R.string.unlock_set_unlock_pin_title;
|
||||
msgResId = getPinSkipMessageRes(hasFace && isFaceSupported, hasFingerprint);
|
||||
break;
|
||||
}
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setPositiveButton(R.string.skip_lock_screen_dialog_button_label, this)
|
||||
.setNegativeButton(R.string.cancel_lock_screen_dialog_button_label, this)
|
||||
.setTitle(getSkipSetupTitle(screenLockResId, hasFingerprint,
|
||||
hasFace && isFaceSupported))
|
||||
.setMessage(msgResId);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public AlertDialog.Builder onCreateDialogBuilder() {
|
||||
Bundle args = getArguments();
|
||||
final boolean forFace =
|
||||
args.getBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE);
|
||||
final boolean forFingerprint =
|
||||
args.getBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT);
|
||||
final boolean forBiometrics =
|
||||
args.getBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS);
|
||||
final boolean isSuw = args.getBoolean(EXTRA_KEY_IS_SUW);
|
||||
final boolean forBiometrics = args.getBoolean(EXTRA_KEY_FOR_BIOMETRICS);
|
||||
final boolean forFace = args.getBoolean(EXTRA_KEY_FOR_FACE);
|
||||
final boolean forFingerprint = args.getBoolean(EXTRA_KEY_FOR_FINGERPRINT);
|
||||
@LockPatternUtils.CredentialType
|
||||
final int credentialType = args.getInt(ARG_LOCK_CREDENTIAL_TYPE);
|
||||
|
||||
if (forFace || forFingerprint || forBiometrics) {
|
||||
final boolean hasFace = forFace || forBiometrics;
|
||||
final boolean hasFingerprint = forFingerprint || forBiometrics;
|
||||
|
||||
final int titleId;
|
||||
final int msgResId;
|
||||
if (args.getBoolean(ARG_LOCK_TYPE_PATTERN)) {
|
||||
titleId = getPatternSkipTitleRes(hasFace, hasFingerprint);
|
||||
msgResId = getPatternSkipMessageRes(hasFace, hasFingerprint);
|
||||
} else if (args.getBoolean(ARG_LOCK_TYPE_ALPHANUMERIC)) {
|
||||
titleId = getPasswordSkipTitleRes(hasFace, hasFingerprint);
|
||||
msgResId = getPasswordSkipMessageRes(hasFace, hasFingerprint);
|
||||
} else {
|
||||
titleId = getPinSkipTitleRes(hasFace, hasFingerprint);
|
||||
msgResId = getPinSkipMessageRes(hasFace, hasFingerprint);
|
||||
}
|
||||
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setPositiveButton(R.string.skip_lock_screen_dialog_button_label, this)
|
||||
.setNegativeButton(R.string.cancel_lock_screen_dialog_button_label, this)
|
||||
.setTitle(titleId)
|
||||
.setMessage(msgResId);
|
||||
} else {
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setPositiveButton(R.string.skip_anyway_button_label, this)
|
||||
.setNegativeButton(R.string.go_back_button_label, this)
|
||||
.setTitle(R.string.lock_screen_intro_skip_title)
|
||||
.setMessage(args.getBoolean(ARG_FRP_SUPPORTED) ?
|
||||
R.string.lock_screen_intro_skip_dialog_text_frp :
|
||||
R.string.lock_screen_intro_skip_dialog_text);
|
||||
final boolean hasFace = Utils.hasFaceHardware(getContext());
|
||||
final boolean hasFingerprint = Utils.hasFingerprintHardware(getContext());
|
||||
return getBiometricsBuilder(credentialType, isSuw, hasFace, hasFingerprint);
|
||||
}
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getPatternSkipTitleRes(boolean hasFace, boolean hasFingerprint) {
|
||||
if (hasFace && hasFingerprint) {
|
||||
return R.string.lock_screen_pattern_skip_biometrics_title;
|
||||
} else if (hasFace) {
|
||||
return R.string.lock_screen_pattern_skip_face_title;
|
||||
} else if (hasFingerprint) {
|
||||
return R.string.lock_screen_pattern_skip_fingerprint_title;
|
||||
} else {
|
||||
return R.string.lock_screen_pattern_skip_title;
|
||||
}
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setPositiveButton(R.string.skip_anyway_button_label, this)
|
||||
.setNegativeButton(R.string.go_back_button_label, this)
|
||||
.setTitle(R.string.lock_screen_intro_skip_title)
|
||||
.setMessage(args.getBoolean(ARG_FRP_SUPPORTED) ?
|
||||
R.string.lock_screen_intro_skip_dialog_text_frp :
|
||||
R.string.lock_screen_intro_skip_dialog_text);
|
||||
}
|
||||
|
||||
@StringRes
|
||||
@@ -138,19 +148,6 @@ public class SetupSkipDialog extends InstrumentedDialogFragment
|
||||
}
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getPasswordSkipTitleRes(boolean hasFace, boolean hasFingerprint) {
|
||||
if (hasFace && hasFingerprint) {
|
||||
return R.string.lock_screen_password_skip_biometrics_title;
|
||||
} else if (hasFace) {
|
||||
return R.string.lock_screen_password_skip_face_title;
|
||||
} else if (hasFingerprint) {
|
||||
return R.string.lock_screen_password_skip_fingerprint_title;
|
||||
} else {
|
||||
return R.string.lock_screen_password_skip_title;
|
||||
}
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getPasswordSkipMessageRes(boolean hasFace, boolean hasFingerprint) {
|
||||
if (hasFace && hasFingerprint) {
|
||||
@@ -164,19 +161,6 @@ public class SetupSkipDialog extends InstrumentedDialogFragment
|
||||
}
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getPinSkipTitleRes(boolean hasFace, boolean hasFingerprint) {
|
||||
if (hasFace && hasFingerprint) {
|
||||
return R.string.lock_screen_pin_skip_biometrics_title;
|
||||
} else if (hasFace) {
|
||||
return R.string.lock_screen_pin_skip_face_title;
|
||||
} else if (hasFingerprint) {
|
||||
return R.string.lock_screen_pin_skip_fingerprint_title;
|
||||
} else {
|
||||
return R.string.lock_screen_pin_skip_title;
|
||||
}
|
||||
}
|
||||
|
||||
@StringRes
|
||||
private int getPinSkipMessageRes(boolean hasFace, boolean hasFingerprint) {
|
||||
if (hasFace && hasFingerprint) {
|
||||
@@ -190,6 +174,13 @@ public class SetupSkipDialog extends InstrumentedDialogFragment
|
||||
}
|
||||
}
|
||||
|
||||
private String getSkipSetupTitle(int screenTypeResId, boolean hasFingerprint,
|
||||
boolean hasFace) {
|
||||
return getString(R.string.lock_screen_skip_setup_title,
|
||||
BiometricUtils.getCombinedScreenLockOptions(getContext(),
|
||||
getString(screenTypeResId), hasFingerprint, hasFace));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int button) {
|
||||
Activity activity = getActivity();
|
||||
|
||||
@@ -106,6 +106,7 @@ public class DataUsageListTest {
|
||||
ReflectionHelpers.setField(mDataUsageList, "services", mNetworkServices);
|
||||
doReturn(mLoaderManager).when(mDataUsageList).getLoaderManager();
|
||||
mDataUsageList.mLoadingViewController = mock(LoadingViewController.class);
|
||||
doNothing().when(mDataUsageList).updateSubscriptionInfoEntity();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -41,11 +41,10 @@ public class DevelopmentMemtagPageTest {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void getMetricsCategory_isSETTINGS_MEMTAG_CATEGORY() {
|
||||
public void getMetricsCategory_isSETTINGS_DEVELOPMENT_MEMTAG_CATEGORY() {
|
||||
assertThat(mMemtagPage.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.SETTINGS_MEMTAG_CATEGORY);
|
||||
.isEqualTo(SettingsEnums.SETTINGS_DEVELOPMENT_MEMTAG_CATEGORY);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -57,17 +57,18 @@ public final class BatteryHistoricalLogUtilTest {
|
||||
BatteryHistoricalLogUtil.writeLog(mContext, Action.APPLY, "pkg1", "logs");
|
||||
BatteryHistoricalLogUtil.printBatteryOptimizeHistoricalLog(mContext, mTestPrintWriter);
|
||||
|
||||
assertThat(mTestStringWriter.toString()).contains("pkg1\tAction:APPLY\tEvent:logs");
|
||||
assertThat(mTestStringWriter.toString()).contains(
|
||||
"pkg1\tAction:APPLY\tEvent:logs\tTimestamp:");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeLog_multipleLogs_withCorrectCounts() {
|
||||
for (int i = 0; i < BatteryHistoricalLogUtil.MAX_ENTRIES; i++) {
|
||||
BatteryHistoricalLogUtil.writeLog(mContext, Action.MANUAL, "pkg" + i, "logs");
|
||||
BatteryHistoricalLogUtil.writeLog(mContext, Action.LEAVE, "pkg" + i, "logs");
|
||||
}
|
||||
BatteryHistoricalLogUtil.printBatteryOptimizeHistoricalLog(mContext, mTestPrintWriter);
|
||||
|
||||
assertThat(mTestStringWriter.toString().split("MANUAL").length).isEqualTo(41);
|
||||
assertThat(mTestStringWriter.toString().split("LEAVE").length).isEqualTo(41);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -54,8 +54,7 @@ public class BatteryTipLoaderTest {
|
||||
BatteryTip.TipType.BATTERY_DEFENDER,
|
||||
BatteryTip.TipType.DOCK_DEFENDER,
|
||||
BatteryTip.TipType.INCOMPATIBLE_CHARGER,
|
||||
BatteryTip.TipType.HIGH_DEVICE_USAGE,
|
||||
BatteryTip.TipType.SMART_BATTERY_MANAGER};
|
||||
BatteryTip.TipType.HIGH_DEVICE_USAGE};
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private BatteryUsageStats mBatteryUsageStats;
|
||||
@Mock
|
||||
|
||||
@@ -79,6 +79,7 @@ import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.shadows.ShadowPersistentDataBlockManager;
|
||||
@@ -98,6 +99,8 @@ public class ChooseLockGenericTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
|
||||
private ActivityController<ChooseLockGeneric> mActivityController;
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
private ChooseLockGenericFragment mFragment;
|
||||
private ChooseLockGeneric mActivity;
|
||||
@@ -109,7 +112,8 @@ public class ChooseLockGenericTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mActivity = Robolectric.buildActivity(ChooseLockGeneric.class)
|
||||
mActivityController = Robolectric.buildActivity(ChooseLockGeneric.class);
|
||||
mActivity = mActivityController
|
||||
.create()
|
||||
.start()
|
||||
.postCreate(null)
|
||||
@@ -314,6 +318,20 @@ public class ChooseLockGenericTest {
|
||||
assertThat(mActivity.isFinishing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void securedScreenLock_notChangingConfig_notWaitForConfirmation_onStopFinishSelf() {
|
||||
Intent intent = new Intent().putExtra(
|
||||
LockPatternUtils.PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC);
|
||||
intent.putExtra("waiting_for_confirmation", true);
|
||||
initActivity(intent);
|
||||
|
||||
mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */);
|
||||
mActivityController.configurationChange();
|
||||
mActivityController.stop();
|
||||
|
||||
assertThat(mActivity.isFinishing()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceTreeClick_fingerprintPassesMinComplexityInfoOntoNextActivity() {
|
||||
Intent intent = new Intent(ACTION_SET_NEW_PASSWORD)
|
||||
@@ -534,10 +552,10 @@ public class ChooseLockGenericTest {
|
||||
assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
|
||||
PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_LOW);
|
||||
|
||||
final String supportFingerprint = mActivity.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = mActivity.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
final String supportFingerprint = capitalize(mActivity.getResources().getString(
|
||||
R.string.security_settings_fingerprint));
|
||||
final String supportFace = capitalize(mActivity.getResources().getString(
|
||||
R.string.keywords_face_settings));
|
||||
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
@@ -563,4 +581,8 @@ public class ChooseLockGenericTest {
|
||||
.create().start().postCreate(null).resume().get();
|
||||
mActivity.getSupportFragmentManager().beginTransaction().add(mFragment, null).commitNow();
|
||||
}
|
||||
|
||||
private static String capitalize(final String input) {
|
||||
return Character.toUpperCase(input.charAt(0)) + input.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
|
||||
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
|
||||
|
||||
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_SETUP_FLOW;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -43,6 +44,7 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowPasswordUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settings.utils.ActivityControllerWrapper;
|
||||
|
||||
import com.google.android.setupdesign.GlifPreferenceLayout;
|
||||
|
||||
@@ -100,6 +102,7 @@ public class SetupChooseLockGenericTest {
|
||||
@Test
|
||||
public void setupChooseLockGenericPasswordComplexityExtraWithoutPermission() {
|
||||
Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN");
|
||||
intent.putExtra(EXTRA_IS_SETUP_FLOW, true);
|
||||
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
|
||||
SetupChooseLockGeneric activity =
|
||||
Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).create().get();
|
||||
@@ -114,6 +117,7 @@ public class SetupChooseLockGenericTest {
|
||||
ShadowPasswordUtils.addGrantedPermission(REQUEST_PASSWORD_COMPLEXITY);
|
||||
|
||||
Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN");
|
||||
intent.putExtra(EXTRA_IS_SETUP_FLOW, true);
|
||||
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
|
||||
SetupChooseLockGeneric activity =
|
||||
Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).create().get();
|
||||
@@ -124,7 +128,8 @@ public class SetupChooseLockGenericTest {
|
||||
|
||||
@Test
|
||||
public void setupChooseLockGenericUsingDescriptionTextOfGlifLayout() {
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(false);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true, true,
|
||||
false);
|
||||
GlifPreferenceLayout view = getViewOfSetupChooseLockGenericFragment(fragment);
|
||||
assertThat(TextUtils.isEmpty(view.getDescriptionText())).isFalse();
|
||||
assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText());
|
||||
@@ -132,47 +137,24 @@ public class SetupChooseLockGenericTest {
|
||||
|
||||
@Test
|
||||
public void setupChooseLockGenericUsingDescriptionTextOfGlifLayoutForBiometric() {
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true, true,
|
||||
true);
|
||||
GlifPreferenceLayout view = getViewOfSetupChooseLockGenericFragment(fragment);
|
||||
assertThat(TextUtils.isEmpty(view.getDescriptionText())).isFalse();
|
||||
assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceTextShowScreenLockAndFingerprint() {
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
false);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);
|
||||
|
||||
final String supportFingerprint = fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = fragment.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).doesNotContain(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).doesNotContain(
|
||||
supportFace);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).doesNotContain(
|
||||
supportFace);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceTextShowScreenLockAndShowFaceAndShowFingerprint() {
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
true);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true, true,
|
||||
true);
|
||||
|
||||
final String supportFingerprint = fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = fragment.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
final String supportFingerprint = capitalize(fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint));
|
||||
final String supportFace = capitalize(fragment.getResources().getString(
|
||||
R.string.keywords_face_settings));
|
||||
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
@@ -192,12 +174,13 @@ public class SetupChooseLockGenericTest {
|
||||
public void updatePreferenceTextShowScreenLockAndShowFingerprint() {
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
false);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true);
|
||||
SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(false, false,
|
||||
true);
|
||||
|
||||
final String supportFingerprint = fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint);
|
||||
final String supportFace = fragment.getResources().getString(
|
||||
R.string.keywords_face_settings);
|
||||
final String supportFingerprint = capitalize(fragment.getResources().getString(
|
||||
R.string.security_settings_fingerprint));
|
||||
final String supportFace = capitalize(fragment.getResources().getString(
|
||||
R.string.keywords_face_settings));
|
||||
|
||||
assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
@@ -213,16 +196,18 @@ public class SetupChooseLockGenericTest {
|
||||
supportFace);
|
||||
}
|
||||
|
||||
private SetupChooseLockGenericFragment getFragmentOfSetupChooseLockGeneric(boolean biometric) {
|
||||
private SetupChooseLockGenericFragment getFragmentOfSetupChooseLockGeneric(
|
||||
boolean forFingerprint, boolean forFace, boolean forBiometric) {
|
||||
ShadowPasswordUtils.addGrantedPermission(REQUEST_PASSWORD_COMPLEXITY);
|
||||
Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN");
|
||||
intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, biometric);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, biometric);
|
||||
// TODO(b/275023433) This presents the activity from being made 'visible` is workaround
|
||||
SetupChooseLockGeneric activity =
|
||||
Robolectric.buildActivity(SetupChooseLockGeneric.class,
|
||||
intent).create().start().postCreate(null).resume().get();
|
||||
intent.putExtra(EXTRA_IS_SETUP_FLOW, true);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, forFingerprint);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, forFace);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, forBiometric);
|
||||
|
||||
SetupChooseLockGeneric activity = (SetupChooseLockGeneric) ActivityControllerWrapper.setup(
|
||||
Robolectric.buildActivity(SetupChooseLockGeneric.class, intent)).get();
|
||||
|
||||
List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
|
||||
assertThat(fragments).isNotNull();
|
||||
@@ -238,4 +223,8 @@ public class SetupChooseLockGenericTest {
|
||||
|
||||
return (GlifPreferenceLayout) fragment.getView();
|
||||
}
|
||||
|
||||
private static String capitalize(final String input) {
|
||||
return Character.toUpperCase(input.charAt(0)) + input.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import android.widget.Button;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.utils.ActivityControllerWrapper;
|
||||
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
|
||||
import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment.Stage;
|
||||
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
|
||||
@@ -40,6 +39,7 @@ import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
|
||||
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.utils.ActivityControllerWrapper;
|
||||
import com.android.settings.widget.ScrollToParentEditText;
|
||||
|
||||
import com.google.android.setupcompat.PartnerCustomizationLayout;
|
||||
@@ -93,7 +93,6 @@ public class SetupChooseLockPasswordTest {
|
||||
application,
|
||||
new IntentBuilder(application).build());
|
||||
|
||||
//ActivityController.of(new SetupChooseLockPassword(), intent).setup().get();
|
||||
ActivityControllerWrapper.setup(
|
||||
Robolectric.buildActivity(SetupChooseLockPassword.class, intent)).get();
|
||||
}
|
||||
@@ -204,7 +203,6 @@ public class SetupChooseLockPasswordTest {
|
||||
intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true);
|
||||
return (SetupChooseLockPassword) ActivityControllerWrapper.setup(
|
||||
Robolectric.buildActivity(SetupChooseLockPassword.class, intent)).get();
|
||||
//return ActivityController.of(new SetupChooseLockPassword(), intent).setup().get();
|
||||
}
|
||||
|
||||
@Implements(ChooseLockGenericController.class)
|
||||
|
||||
@@ -38,10 +38,10 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockPatternView;
|
||||
import com.android.internal.widget.LockPatternView.Cell;
|
||||
import com.android.internal.widget.LockPatternView.DisplayMode;
|
||||
import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment;
|
||||
import com.android.settings.password.ChooseLockPattern.IntentBuilder;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SetupRedactionInterstitial;
|
||||
import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment;
|
||||
import com.android.settings.password.ChooseLockPattern.IntentBuilder;
|
||||
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
|
||||
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
@@ -84,7 +84,7 @@ public class SetupChooseLockPatternTest {
|
||||
new IntentBuilder(application)
|
||||
.setUserId(UserHandle.myUserId())
|
||||
.build());
|
||||
//mActivity = ActivityController.of(new SetupChooseLockPattern(), intent).setup().get();
|
||||
|
||||
mActivity = (SetupChooseLockPattern) ActivityControllerWrapper.setup(
|
||||
Robolectric.buildActivity(SetupChooseLockPattern.class, intent)).get();
|
||||
}
|
||||
|
||||
@@ -16,18 +16,34 @@
|
||||
|
||||
package com.android.settings.password;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
|
||||
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.biometrics.BiometricUtils;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settings.utils.ActivityControllerWrapper;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
@@ -39,12 +55,25 @@ import org.robolectric.shadows.ShadowApplication;
|
||||
@Config(shadows = {ShadowUtils.class, ShadowAlertDialog.class})
|
||||
public class SetupSkipDialogTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
@Mock
|
||||
private FaceManager mFaceManager;
|
||||
private FragmentActivity mActivity;
|
||||
private FakeFeatureFactory mFakeFeatureFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ShadowUtils.setFingerprintManager(mFingerprintManager);
|
||||
ShadowUtils.setFaceManager(mFaceManager);
|
||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mActivity = (FragmentActivity) ActivityControllerWrapper.setup(
|
||||
Robolectric.buildActivity(FragmentActivity.class)).get();
|
||||
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
true);
|
||||
}
|
||||
|
||||
private ShadowAlertDialog getShadowAlertDialog() {
|
||||
@@ -55,10 +84,33 @@ public class SetupSkipDialogTest {
|
||||
return shadowAlertDialog;
|
||||
}
|
||||
|
||||
private String getSkipSetupTitle(int credentialType, boolean hasFingerprint,
|
||||
boolean hasFace) {
|
||||
final int screenLockResId;
|
||||
switch (credentialType) {
|
||||
case CREDENTIAL_TYPE_PATTERN:
|
||||
screenLockResId = R.string.unlock_set_unlock_pattern_title;
|
||||
break;
|
||||
case CREDENTIAL_TYPE_PASSWORD:
|
||||
screenLockResId = R.string.unlock_set_unlock_password_title;
|
||||
break;
|
||||
case CREDENTIAL_TYPE_PIN:
|
||||
default:
|
||||
screenLockResId = R.string.unlock_set_unlock_pin_title;
|
||||
break;
|
||||
}
|
||||
return mActivity.getString(R.string.lock_screen_skip_setup_title,
|
||||
BiometricUtils.getCombinedScreenLockOptions(mActivity,
|
||||
mActivity.getString(screenLockResId), hasFingerprint, hasFace));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void frpMessages_areShownCorrectly_whenNotSupported() {
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(false);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(false, false, false, false, false, false);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, false, false, false, false, true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
@@ -70,8 +122,11 @@ public class SetupSkipDialogTest {
|
||||
|
||||
@Test
|
||||
public void frpMessages_areShownCorrectly_whenSupported() {
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(false);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, false, false, false, false, false);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, true, false, false, false, true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
@@ -83,117 +138,175 @@ public class SetupSkipDialogTest {
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPinSetupForFace_shouldShownCorrectly() {
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, false, false, false, true, false);
|
||||
final boolean hasFace = true;
|
||||
final boolean hasFingerprint = false;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog = SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, false,
|
||||
false, true, false, true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pin_skip_face_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PIN, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pin_skip_face_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPasswordSetupForFace_shouldShownCorrectly() {
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, false, true, false, true, false);
|
||||
final boolean hasFace = true;
|
||||
final boolean hasFingerprint = false;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog = SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PASSWORD,
|
||||
false, hasFingerprint, hasFace, false, true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_password_skip_face_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PASSWORD, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_password_skip_face_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPatternSetupForFace_shouldShownCorrectly() {
|
||||
final boolean hasFace = true;
|
||||
final boolean hasFingerprint = false;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, true, false, false, true, false);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PATTERN, true, false, true, false,
|
||||
true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pattern_skip_face_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PATTERN, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pattern_skip_face_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPinSetupForFingerprint_shouldShownCorrectly() {
|
||||
final boolean hasFace = false;
|
||||
final boolean hasFingerprint = true;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, false, false, true, false, false);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, true, true, false, false, true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pin_skip_fingerprint_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PIN, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pin_skip_fingerprint_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPasswordSetupForFingerprint_shouldShownCorrectly() {
|
||||
final boolean hasFace = false;
|
||||
final boolean hasFingerprint = true;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, false, true, true, false, false);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PASSWORD, true, true, false, false,
|
||||
true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_password_skip_fingerprint_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PASSWORD, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_password_skip_fingerprint_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPatternSetupForFingerprint_shouldShownCorrectly() {
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, true, false, true, false, false);
|
||||
final boolean hasFace = false;
|
||||
final boolean hasFingerprint = true;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog = SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PATTERN, true,
|
||||
true, false, false, true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pattern_skip_fingerprint_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PATTERN, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pattern_skip_fingerprint_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPinSetupForBiometrics_shouldShownCorrectly() {
|
||||
final boolean hasFace = true;
|
||||
final boolean hasFingerprint = true;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, false, false, false, false, true);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, true, false, false, true, true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pin_skip_biometrics_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PIN, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pin_skip_biometrics_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPasswordSetupForBiometrics_shouldShownCorrectly() {
|
||||
final boolean hasFace = true;
|
||||
final boolean hasFingerprint = true;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, false, true, false, false, true);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PASSWORD, true, false, false, true,
|
||||
true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_password_skip_biometrics_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PASSWORD, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_password_skip_biometrics_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dialogMessage_whenSkipPatternSetupForBiometrics_shouldShownCorrectly() {
|
||||
final boolean hasFace = true;
|
||||
final boolean hasFingerprint = true;
|
||||
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(hasFace);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint);
|
||||
|
||||
SetupSkipDialog setupSkipDialog =
|
||||
SetupSkipDialog.newInstance(true, true, false, false, false, true);
|
||||
SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PATTERN, true, false, false, true,
|
||||
true);
|
||||
setupSkipDialog.show(mActivity.getSupportFragmentManager());
|
||||
|
||||
ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog();
|
||||
assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pattern_skip_biometrics_title));
|
||||
getSkipSetupTitle(CREDENTIAL_TYPE_PATTERN, hasFingerprint, hasFace));
|
||||
assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo(
|
||||
mActivity.getString(R.string.lock_screen_pattern_skip_biometrics_message));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user