diff options
111 files changed, 710 insertions, 614 deletions
diff --git a/config/preloaded-classes b/config/preloaded-classes index 1812c2bb61d6..fd4e3dfcaf95 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -6634,12 +6634,6 @@ android.security.Scrypt android.security.attestationverification.AttestationVerificationManager android.security.keymaster.ExportResult$1 android.security.keymaster.ExportResult -android.security.keymaster.IKeyAttestationApplicationIdProvider$Stub -android.security.keymaster.IKeyAttestationApplicationIdProvider -android.security.keymaster.KeyAttestationApplicationId$1 -android.security.keymaster.KeyAttestationApplicationId -android.security.keymaster.KeyAttestationPackageInfo$1 -android.security.keymaster.KeyAttestationPackageInfo android.security.keymaster.KeyCharacteristics$1 android.security.keymaster.KeyCharacteristics android.security.keymaster.KeymasterArgument$1 @@ -6664,7 +6658,13 @@ android.security.keystore.AttestationUtils android.security.keystore.BackendBusyException android.security.keystore.DelegatingX509Certificate android.security.keystore.DeviceIdAttestationException +android.security.keystore.IKeyAttestationApplicationIdProvider$Stub +android.security.keystore.IKeyAttestationApplicationIdProvider +android.security.keystore.KeyAttestationApplicationId$Stub +android.security.keystore.KeyAttestationApplicationId android.security.keystore.KeyAttestationException +android.security.keystore.KeyAttestationPackageInfo$Stub +android.security.keystore.KeyAttestationPackageInfo android.security.keystore.KeyExpiredException android.security.keystore.KeyGenParameterSpec$Builder android.security.keystore.KeyGenParameterSpec @@ -6687,6 +6687,8 @@ android.security.keystore.KeystoreResponse$1 android.security.keystore.KeystoreResponse android.security.keystore.ParcelableKeyGenParameterSpec$1 android.security.keystore.ParcelableKeyGenParameterSpec +android.security.keystore.Signature$Stub +android.security.keystore.Signature android.security.keystore.SecureKeyImportUnavailableException android.security.keystore.StrongBoxUnavailableException android.security.keystore.UserAuthArgs diff --git a/core/java/Android.bp b/core/java/Android.bp index 5091b52f7fd0..70864d532986 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -23,11 +23,6 @@ filegroup { visibility: ["//frameworks/base"], } -filegroup { - name: "IKeyAttestationApplicationIdProvider.aidl", - srcs: ["android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl"], -} - aidl_library { name: "IDropBoxManagerService_aidl", srcs: [ diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index 7ed3a1d63e4f..6a51171b8f90 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -60,6 +60,7 @@ import com.android.internal.widget.IWeakEscrowTokenRemovedListener; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockscreenCredential; +import com.android.internal.widget.PasswordValidationError; import com.android.internal.widget.VerifyCredentialResponse; import java.nio.charset.Charset; @@ -916,17 +917,14 @@ public class KeyguardManager { if (!checkInitialLockMethodUsage()) { return false; } + Objects.requireNonNull(password, "Password cannot be null."); complexity = PasswordMetrics.sanitizeComplexityLevel(complexity); - // TODO: b/131755827 add devicePolicyManager support for Auto - DevicePolicyManager devicePolicyManager = - (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); PasswordMetrics adminMetrics = - devicePolicyManager.getPasswordMinimumMetrics(mContext.getUserId()); - // Check if the password fits the mold of a pin or pattern. - boolean isPinOrPattern = lockType != PASSWORD; - - return PasswordMetrics.validatePassword( - adminMetrics, complexity, isPinOrPattern, password).size() == 0; + mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId()); + try (LockscreenCredential credential = createLockscreenCredential(lockType, password)) { + return PasswordMetrics.validateCredential(adminMetrics, complexity, + credential).size() == 0; + } } /** @@ -945,11 +943,8 @@ public class KeyguardManager { return -1; } complexity = PasswordMetrics.sanitizeComplexityLevel(complexity); - // TODO: b/131755827 add devicePolicyManager support for Auto - DevicePolicyManager devicePolicyManager = - (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); PasswordMetrics adminMetrics = - devicePolicyManager.getPasswordMinimumMetrics(mContext.getUserId()); + mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId()); PasswordMetrics minMetrics = PasswordMetrics.applyComplexity(adminMetrics, isPin, complexity); return minMetrics.length; @@ -1171,6 +1166,14 @@ public class KeyguardManager { currentLockType, currentPassword); LockscreenCredential newCredential = createLockscreenCredential( newLockType, newPassword); + PasswordMetrics adminMetrics = + mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId()); + List<PasswordValidationError> errors = PasswordMetrics.validateCredential(adminMetrics, + DevicePolicyManager.PASSWORD_COMPLEXITY_NONE, newCredential); + if (!errors.isEmpty()) { + Log.e(TAG, "New credential is not valid: " + errors.get(0)); + return false; + } return mLockPatternUtils.setLockCredential(newCredential, currentCredential, userId); } diff --git a/core/java/android/app/admin/PasswordMetrics.java b/core/java/android/app/admin/PasswordMetrics.java index ab48791d43ef..dd311755bf3f 100644 --- a/core/java/android/app/admin/PasswordMetrics.java +++ b/core/java/android/app/admin/PasswordMetrics.java @@ -30,6 +30,7 @@ import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSW import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; import static com.android.internal.widget.LockPatternUtils.MIN_LOCK_PASSWORD_SIZE; +import static com.android.internal.widget.LockPatternUtils.MIN_LOCK_PATTERN_SIZE; import static com.android.internal.widget.PasswordValidationError.CONTAINS_INVALID_CHARACTERS; import static com.android.internal.widget.PasswordValidationError.CONTAINS_SEQUENCE; import static com.android.internal.widget.PasswordValidationError.NOT_ENOUGH_DIGITS; @@ -134,17 +135,6 @@ public final class PasswordMetrics implements Parcelable { } } - private static boolean hasInvalidCharacters(byte[] password) { - // Allow non-control Latin-1 characters only. - for (byte b : password) { - char c = (char) b; - if (c < 32 || c > 127) { - return true; - } - } - return false; - } - @Override public int describeContents() { return 0; @@ -189,19 +179,15 @@ public final class PasswordMetrics implements Parcelable { }; /** - * Returns the {@code PasswordMetrics} for a given credential. - * - * If the credential is a pin or a password, equivalent to - * {@link #computeForPasswordOrPin(byte[], boolean)}. {@code credential} cannot be null - * when {@code type} is - * {@link com.android.internal.widget.LockPatternUtils#CREDENTIAL_TYPE_PASSWORD}. + * Returns the {@code PasswordMetrics} for the given credential. */ public static PasswordMetrics computeForCredential(LockscreenCredential credential) { if (credential.isPassword() || credential.isPin()) { - return PasswordMetrics.computeForPasswordOrPin(credential.getCredential(), - credential.isPin()); + return computeForPasswordOrPin(credential.getCredential(), credential.isPin()); } else if (credential.isPattern()) { - return new PasswordMetrics(CREDENTIAL_TYPE_PATTERN); + PasswordMetrics metrics = new PasswordMetrics(CREDENTIAL_TYPE_PATTERN); + metrics.length = credential.size(); + return metrics; } else if (credential.isNone()) { return new PasswordMetrics(CREDENTIAL_TYPE_NONE); } else { @@ -210,10 +196,10 @@ public final class PasswordMetrics implements Parcelable { } /** - * Returns the {@code PasswordMetrics} for a given password or pin + * Returns the {@code PasswordMetrics} for the given password or pin. */ - public static PasswordMetrics computeForPasswordOrPin(byte[] password, boolean isPin) { - // Analyse the characters used + private static PasswordMetrics computeForPasswordOrPin(byte[] credential, boolean isPin) { + // Analyze the characters used. int letters = 0; int upperCase = 0; int lowerCase = 0; @@ -221,8 +207,8 @@ public final class PasswordMetrics implements Parcelable { int symbols = 0; int nonLetter = 0; int nonNumeric = 0; - final int length = password.length; - for (byte b : password) { + final int length = credential.length; + for (byte b : credential) { switch (categoryChar((char) b)) { case CHAR_LOWER_CASE: letters++; @@ -247,7 +233,7 @@ public final class PasswordMetrics implements Parcelable { } final int credType = isPin ? CREDENTIAL_TYPE_PIN : CREDENTIAL_TYPE_PASSWORD; - final int seqLength = maxLengthSequence(password); + final int seqLength = maxLengthSequence(credential); return new PasswordMetrics(credType, length, letters, upperCase, lowerCase, numeric, symbols, nonLetter, nonNumeric, seqLength); } @@ -513,26 +499,24 @@ public final class PasswordMetrics implements Parcelable { } /** - * Validates password against minimum metrics and complexity. + * Validates a proposed lockscreen credential against minimum metrics and complexity. * - * @param adminMetrics - minimum metrics to satisfy admin requirements. - * @param minComplexity - minimum complexity imposed by the requester. - * @param isPin - whether it is PIN that should be only digits - * @param password - password to validate. - * @return a list of password validation errors. An empty list means the password is OK. + * @param adminMetrics minimum metrics to satisfy admin requirements + * @param minComplexity minimum complexity imposed by the requester + * @param credential the proposed lockscreen credential + * + * @return a list of validation errors. An empty list means the credential is OK. * * TODO: move to PasswordPolicy */ - public static List<PasswordValidationError> validatePassword( - PasswordMetrics adminMetrics, int minComplexity, boolean isPin, byte[] password) { - - if (hasInvalidCharacters(password)) { + public static List<PasswordValidationError> validateCredential( + PasswordMetrics adminMetrics, int minComplexity, LockscreenCredential credential) { + if (credential.hasInvalidChars()) { return Collections.singletonList( new PasswordValidationError(CONTAINS_INVALID_CHARACTERS, 0)); } - - final PasswordMetrics enteredMetrics = computeForPasswordOrPin(password, isPin); - return validatePasswordMetrics(adminMetrics, minComplexity, enteredMetrics); + PasswordMetrics actualMetrics = computeForCredential(credential); + return validatePasswordMetrics(adminMetrics, minComplexity, actualMetrics); } /** @@ -555,9 +539,18 @@ public final class PasswordMetrics implements Parcelable { || !bucket.allowsCredType(actualMetrics.credType)) { return Collections.singletonList(new PasswordValidationError(WEAK_CREDENTIAL_TYPE, 0)); } - if (actualMetrics.credType != CREDENTIAL_TYPE_PASSWORD - && actualMetrics.credType != CREDENTIAL_TYPE_PIN) { - return Collections.emptyList(); // Nothing to check for pattern or none. + if (actualMetrics.credType == CREDENTIAL_TYPE_PATTERN) { + // For pattern, only need to check the length against the hardcoded minimum. If the + // pattern length is unavailable (e.g., PasswordMetrics that was stored on-disk before + // the pattern length started being included in it), assume it is okay. + if (actualMetrics.length != 0 && actualMetrics.length < MIN_LOCK_PATTERN_SIZE) { + return Collections.singletonList(new PasswordValidationError(TOO_SHORT, + MIN_LOCK_PATTERN_SIZE)); + } + return Collections.emptyList(); + } + if (actualMetrics.credType == CREDENTIAL_TYPE_NONE) { + return Collections.emptyList(); // Nothing to check for none. } if (actualMetrics.credType == CREDENTIAL_TYPE_PIN && actualMetrics.nonNumeric > 0) { diff --git a/core/java/android/content/pm/Signature.aidl b/core/java/android/content/pm/Signature.aidl deleted file mode 100644 index 36c127ad0384..000000000000 --- a/core/java/android/content/pm/Signature.aidl +++ /dev/null @@ -1,32 +0,0 @@ -/* //device/java/android/android/view/WindowManager.aidl -** -** Copyright 2007, 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 android.content.pm; - -/* For the key attestation application id provider service we needed a native implementation - * of the Signature parcelable because the service is used by the native keystore. - * The native implementation is now located at - * system/security/keystore/Signature.cpp - * and - * system/security/keystore/include/keystore/Signature.h. - * and can be used by linking against libkeystore_binder. - * - * This is not the best arrangement. If you, dear reader, happen to implement native implementations - * for the package manager's parcelables, consider moving Signature.cpp/.h to your library and - * adjust keystore's dependencies accordingly. Thank you. - */ -parcelable Signature cpp_header "keystore/Signature.h"; diff --git a/core/java/android/security/keymaster/KeyAttestationApplicationId.java b/core/java/android/security/keymaster/KeyAttestationApplicationId.java deleted file mode 100644 index 670f30e1b04b..000000000000 --- a/core/java/android/security/keymaster/KeyAttestationApplicationId.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2016 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 android.security.keymaster; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * @hide - * The information aggregated by this class is used by keystore to identify a caller of the - * keystore API toward a remote party. It aggregates multiple PackageInfos because keystore - * can only determine a caller by uid granularity, and a uid can be shared by multiple packages. - * The remote party must decide if it trusts all of the packages enough to consider the - * confidentiality of the key material in question intact. - */ -public class KeyAttestationApplicationId implements Parcelable { - private final KeyAttestationPackageInfo[] mAttestationPackageInfos; - - /** - * @param mAttestationPackageInfos - */ - public KeyAttestationApplicationId(KeyAttestationPackageInfo[] mAttestationPackageInfos) { - super(); - this.mAttestationPackageInfos = mAttestationPackageInfos; - } - - /** - * @return the mAttestationPackageInfos - */ - public KeyAttestationPackageInfo[] getAttestationPackageInfos() { - return mAttestationPackageInfos; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeTypedArray(mAttestationPackageInfos, flags); - } - - public static final @android.annotation.NonNull Parcelable.Creator<KeyAttestationApplicationId> CREATOR - = new Parcelable.Creator<KeyAttestationApplicationId>() { - @Override - public KeyAttestationApplicationId createFromParcel(Parcel source) { - return new KeyAttestationApplicationId(source); - } - - @Override - public KeyAttestationApplicationId[] newArray(int size) { - return new KeyAttestationApplicationId[size]; - } - }; - - KeyAttestationApplicationId(Parcel source) { - mAttestationPackageInfos = source.createTypedArray(KeyAttestationPackageInfo.CREATOR); - } -} diff --git a/core/java/android/security/keymaster/KeyAttestationPackageInfo.java b/core/java/android/security/keymaster/KeyAttestationPackageInfo.java deleted file mode 100644 index c0b8d8dfd4d9..000000000000 --- a/core/java/android/security/keymaster/KeyAttestationPackageInfo.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2016 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 android.security.keymaster; - -import android.content.pm.Signature; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * @hide - * This class constitutes and excerpt from the PackageManager's PackageInfo for the purpose of - * key attestation. It is part of the KeyAttestationApplicationId, which is used by - * keystore to identify the caller of the keystore API towards a remote party. - */ -public class KeyAttestationPackageInfo implements Parcelable { - private final String mPackageName; - private final long mPackageVersionCode; - private final Signature[] mPackageSignatures; - - /** - * @param mPackageName - * @param mPackageVersionCode - * @param mPackageSignatures - */ - public KeyAttestationPackageInfo( - String mPackageName, long mPackageVersionCode, Signature[] mPackageSignatures) { - super(); - this.mPackageName = mPackageName; - this.mPackageVersionCode = mPackageVersionCode; - this.mPackageSignatures = mPackageSignatures; - } - /** - * @return the mPackageName - */ - public String getPackageName() { - return mPackageName; - } - /** - * @return the mPackageVersionCode - */ - public long getPackageVersionCode() { - return mPackageVersionCode; - } - /** - * @return the mPackageSignatures - */ - public Signature[] getPackageSignatures() { - return mPackageSignatures; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mPackageName); - dest.writeLong(mPackageVersionCode); - dest.writeTypedArray(mPackageSignatures, flags); - } - - public static final @android.annotation.NonNull Parcelable.Creator<KeyAttestationPackageInfo> CREATOR - = new Parcelable.Creator<KeyAttestationPackageInfo>() { - @Override - public KeyAttestationPackageInfo createFromParcel(Parcel source) { - return new KeyAttestationPackageInfo(source); - } - - @Override - public KeyAttestationPackageInfo[] newArray(int size) { - return new KeyAttestationPackageInfo[size]; - } - }; - - private KeyAttestationPackageInfo(Parcel source) { - mPackageName = source.readString(); - mPackageVersionCode = source.readLong(); - mPackageSignatures = source.createTypedArray(Signature.CREATOR); - } -} diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 0d0bfe3b8ab9..d70296353ff6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2536,7 +2536,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final int childrenCount = mChildrenCount; if (childrenCount != 0) { final float x = event.getXDispatchLocation(0); - final float y = event.getXDispatchLocation(0); + final float y = event.getYDispatchLocation(0); final ArrayList<View> preorderedList = buildOrderedChildList(); final boolean customOrder = preorderedList == null diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 490ec35d1482..dc28fa45794c 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -96,7 +96,7 @@ public class LockPatternUtils { public static final int MIN_LOCK_PATTERN_SIZE = 4; /** - * The minimum size of a valid password. + * The minimum size of a valid password or PIN. */ public static final int MIN_LOCK_PASSWORD_SIZE = 4; @@ -771,7 +771,6 @@ public class LockPatternUtils { * and return false if the given credential is wrong. * @throws RuntimeException if password change encountered an unrecoverable error. * @throws UnsupportedOperationException secure lockscreen is not supported on this device. - * @throws IllegalArgumentException if new credential is too short. */ public boolean setLockCredential(@NonNull LockscreenCredential newCredential, @NonNull LockscreenCredential savedCredential, int userHandle) { @@ -779,7 +778,6 @@ public class LockPatternUtils { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); } - newCredential.checkLength(); try { if (!getLockSettings().setLockCredential(newCredential, savedCredential, userHandle)) { @@ -1543,7 +1541,6 @@ public class LockPatternUtils { throw new UnsupportedOperationException( "This operation requires the lock screen feature."); } - credential.checkLength(); LockSettingsInternal localService = getLockSettingsInternal(); return localService.setLockCredentialWithToken(credential, tokenHandle, token, userHandle); diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java index 03e7fd1c7403..c88763ce6c97 100644 --- a/core/java/com/android/internal/widget/LockscreenCredential.java +++ b/core/java/com/android/internal/widget/LockscreenCredential.java @@ -60,10 +60,24 @@ import java.util.Objects; public class LockscreenCredential implements Parcelable, AutoCloseable { private final int mType; - // Stores raw credential bytes, or null if credential has been zeroized. An empty password + // Stores raw credential bytes, or null if credential has been zeroized. A none credential // is represented as a byte array of length 0. private byte[] mCredential; + // This indicates that the credential used characters outside ASCII 32–127. + // + // Such credentials were never intended to be allowed. However, Android 10–14 had a bug where + // conversion from the chars the user entered to the credential bytes used a simple truncation. + // Thus, any 'char' whose remainder mod 256 was in the range 32–127 was accepted and was + // equivalent to some ASCII character. For example, ™, which is U+2122, was truncated to ASCII + // 0x22 which is the double-quote character ". + // + // We have to continue to allow a LockscreenCredential to be constructed with this bug, so that + // existing devices can be unlocked if their password used this bug. However, we prevent new + // passwords that use this bug from being set. The boolean below keeps track of the information + // needed to do that check, since the conversion to mCredential may have been lossy. + private final boolean mHasInvalidChars; + /** * Private constructor, use static builder methods instead. * @@ -71,7 +85,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { * LockscreenCredential will only store the reference internally without copying. This is to * minimize the number of extra copies introduced. */ - private LockscreenCredential(int type, byte[] credential) { + private LockscreenCredential(int type, byte[] credential, boolean hasInvalidChars) { Objects.requireNonNull(credential); if (type == CREDENTIAL_TYPE_NONE) { Preconditions.checkArgument(credential.length == 0); @@ -80,17 +94,28 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { Preconditions.checkArgument(type == CREDENTIAL_TYPE_PIN || type == CREDENTIAL_TYPE_PASSWORD || type == CREDENTIAL_TYPE_PATTERN); - Preconditions.checkArgument(credential.length > 0); + // Do not validate credential.length yet. All non-none credentials have a minimum + // length requirement; however, one of the uses of LockscreenCredential is to represent + // a proposed credential that might be too short. For example, a LockscreenCredential + // with type CREDENTIAL_TYPE_PIN and length 0 represents an attempt to set an empty PIN. + // This differs from an actual attempt to set a none credential. We have to allow the + // LockscreenCredential object to be constructed so that the validation logic can run, + // even though the validation logic will ultimately reject the credential as too short. } mType = type; mCredential = credential; + mHasInvalidChars = hasInvalidChars; + } + + private LockscreenCredential(int type, CharSequence credential) { + this(type, charsToBytesTruncating(credential), hasInvalidChars(credential)); } /** - * Creates a LockscreenCredential object representing empty password. + * Creates a LockscreenCredential object representing a none credential. */ public static LockscreenCredential createNone() { - return new LockscreenCredential(CREDENTIAL_TYPE_NONE, new byte[0]); + return new LockscreenCredential(CREDENTIAL_TYPE_NONE, new byte[0], false); } /** @@ -98,15 +123,14 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { */ public static LockscreenCredential createPattern(@NonNull List<LockPatternView.Cell> pattern) { return new LockscreenCredential(CREDENTIAL_TYPE_PATTERN, - LockPatternUtils.patternToByteArray(pattern)); + LockPatternUtils.patternToByteArray(pattern), /* hasInvalidChars= */ false); } /** * Creates a LockscreenCredential object representing the given alphabetic password. */ public static LockscreenCredential createPassword(@NonNull CharSequence password) { - return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD, - charSequenceToByteArray(password)); + return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD, password); } /** @@ -117,20 +141,19 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { */ public static LockscreenCredential createManagedPassword(@NonNull byte[] password) { return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD, - Arrays.copyOf(password, password.length)); + Arrays.copyOf(password, password.length), /* hasInvalidChars= */ false); } /** * Creates a LockscreenCredential object representing the given numeric PIN. */ public static LockscreenCredential createPin(@NonNull CharSequence pin) { - return new LockscreenCredential(CREDENTIAL_TYPE_PIN, - charSequenceToByteArray(pin)); + return new LockscreenCredential(CREDENTIAL_TYPE_PIN, pin); } /** * Creates a LockscreenCredential object representing the given alphabetic password. - * If the supplied password is empty, create an empty credential object. + * If the supplied password is empty, create a none credential object. */ public static LockscreenCredential createPasswordOrNone(@Nullable CharSequence password) { if (TextUtils.isEmpty(password)) { @@ -142,7 +165,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { /** * Creates a LockscreenCredential object representing the given numeric PIN. - * If the supplied password is empty, create an empty credential object. + * If the supplied password is empty, create a none credential object. */ public static LockscreenCredential createPinOrNone(@Nullable CharSequence pin) { if (TextUtils.isEmpty(pin)) { @@ -175,7 +198,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { return mCredential; } - /** Returns whether this is an empty credential */ + /** Returns whether this is a none credential */ public boolean isNone() { ensureNotZeroized(); return mType == CREDENTIAL_TYPE_NONE; @@ -205,10 +228,17 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { return mCredential.length; } + /** Returns true if this credential was constructed with any chars outside the allowed range */ + public boolean hasInvalidChars() { + ensureNotZeroized(); + return mHasInvalidChars; + } + /** Create a copy of the credential */ public LockscreenCredential duplicate() { return new LockscreenCredential(mType, - mCredential != null ? Arrays.copyOf(mCredential, mCredential.length) : null); + mCredential != null ? Arrays.copyOf(mCredential, mCredential.length) : null, + mHasInvalidChars); } /** @@ -222,27 +252,37 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { } /** - * Check if the credential meets minimal length requirement. + * Checks whether the credential meets basic requirements for setting it as a new credential. * - * @throws IllegalArgumentException if the credential is too short. + * This is redundant if {@link android.app.admin.PasswordMetrics#validateCredential()}, which + * does more comprehensive checks, is correctly called first (which it should be). + * + * @throws IllegalArgumentException if the credential contains invalid characters or is too + * short */ - public void checkLength() { - if (isNone()) { - return; + public void validateBasicRequirements() { + if (mHasInvalidChars) { + throw new IllegalArgumentException("credential contains invalid characters"); } - if (isPattern()) { - if (size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) { - throw new IllegalArgumentException("pattern must not be null and at least " - + LockPatternUtils.MIN_LOCK_PATTERN_SIZE + " dots long."); - } - return; - } - if (isPassword() || isPin()) { - if (size() < LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) { - throw new IllegalArgumentException("password must not be null and at least " - + "of length " + LockPatternUtils.MIN_LOCK_PASSWORD_SIZE); - } - return; + switch (getType()) { + case CREDENTIAL_TYPE_PATTERN: + if (size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) { + throw new IllegalArgumentException("pattern must be at least " + + LockPatternUtils.MIN_LOCK_PATTERN_SIZE + " dots long."); + } + break; + case CREDENTIAL_TYPE_PIN: + if (size() < LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) { + throw new IllegalArgumentException("PIN must be at least " + + LockPatternUtils.MIN_LOCK_PASSWORD_SIZE + " digits long."); + } + break; + case CREDENTIAL_TYPE_PASSWORD: + if (size() < LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) { + throw new IllegalArgumentException("password must be at least " + + LockPatternUtils.MIN_LOCK_PASSWORD_SIZE + " characters long."); + } + break; } } @@ -317,6 +357,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); dest.writeByteArray(mCredential); + dest.writeBoolean(mHasInvalidChars); } public static final Parcelable.Creator<LockscreenCredential> CREATOR = @@ -324,7 +365,8 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { @Override public LockscreenCredential createFromParcel(Parcel source) { - return new LockscreenCredential(source.readInt(), source.createByteArray()); + return new LockscreenCredential(source.readInt(), source.createByteArray(), + source.readBoolean()); } @Override @@ -346,7 +388,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { @Override public int hashCode() { // Effective Java — Always override hashCode when you override equals - return Objects.hash(mType, Arrays.hashCode(mCredential)); + return Objects.hash(mType, Arrays.hashCode(mCredential), mHasInvalidChars); } @Override @@ -354,20 +396,45 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { if (o == this) return true; if (!(o instanceof LockscreenCredential)) return false; final LockscreenCredential other = (LockscreenCredential) o; - return mType == other.mType && Arrays.equals(mCredential, other.mCredential); + return mType == other.mType && Arrays.equals(mCredential, other.mCredential) + && mHasInvalidChars == other.mHasInvalidChars; + } + + private static boolean hasInvalidChars(CharSequence chars) { + // + // Consider the password to have invalid characters if it contains any non-ASCII characters + // or control characters. There are multiple reasons for this restriction: + // + // - Non-ASCII characters might only be possible to enter on a third-party keyboard app + // (IME) that is available when setting the password but not when verifying it after a + // reboot. This can happen if the keyboard is not direct boot aware or gets uninstalled. + // + // - Unicode strings that look identical to the user can map to different byte[]. Yet, only + // one byte[] can be accepted. Unicode normalization can solve this problem to some + // extent, but still many Unicode characters look similar and could cause confusion. + // + // - For backwards compatibility reasons, the upper 8 bits of the 16-bit 'chars' are + // discarded by charsToBytesTruncating(). Thus, as-is passwords with characters above + // U+00FF (255) are not as secure as they should be. IMPORTANT: Do not change the below + // code to allow characters above U+00FF (255) without fixing this issue! + // + for (int i = 0; i < chars.length(); i++) { + char c = chars.charAt(i); + if (c < 32 || c > 127) { + return true; + } + } + return false; } /** - * Converts a CharSequence to a byte array without requiring a toString(), which creates an - * additional copy. + * Converts a CharSequence to a byte array, intentionally truncating chars greater than 255 for + * backwards compatibility reasons. See {@link #mHasInvalidChars}. * * @param chars The CharSequence to convert * @return A byte array representing the input */ - private static byte[] charSequenceToByteArray(CharSequence chars) { - if (chars == null) { - return new byte[0]; - } + private static byte[] charsToBytesTruncating(CharSequence chars) { byte[] bytes = new byte[chars.length()]; for (int i = 0; i < chars.length(); i++) { bytes[i] = (byte) chars.charAt(i); diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 55382cc1d380..bfd80a9e4f74 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -157,12 +157,8 @@ static struct thread_dispatch_offsets_t // **************************************************************************** // **************************************************************************** -static constexpr int32_t PROXY_WARN_INTERVAL = 5000; static constexpr uint32_t GC_INTERVAL = 1000; -static std::atomic<uint32_t> gNumProxies(0); -static std::atomic<uint32_t> gProxiesWarned(0); - // Number of GlobalRefs held by JavaBBinders. static std::atomic<uint32_t> gNumLocalRefsCreated(0); static std::atomic<uint32_t> gNumLocalRefsDeleted(0); @@ -842,19 +838,7 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) return NULL; } BinderProxyNativeData* actualNativeData = getBPNativeData(env, object); - if (actualNativeData == nativeData) { - // Created a new Proxy - uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed); - uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed); - if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) { - // Multiple threads can get here, make sure only one of them gets to - // update the warn counter. - if (gProxiesWarned.compare_exchange_strong(numLastWarned, - numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) { - ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies); - } - } - } else { + if (actualNativeData != nativeData) { delete nativeData; } @@ -1209,7 +1193,7 @@ jint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz) jint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz) { - return gNumProxies.load(); + return BpBinder::getBinderProxyCount(); } jint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz) @@ -1494,7 +1478,6 @@ static void BinderProxy_destroy(void* rawNativeData) nativeData->mObject.get(), nativeData->mOrgue.get()); delete nativeData; IPCThreadState::self()->flushCommands(); - --gNumProxies; } JNIEXPORT jlong JNICALL android_os_BinderProxy_getNativeFinalizer(JNIEnv*, jclass) { diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 58f97b08f2e3..93048ea4fc85 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1022,7 +1022,7 @@ requires swapping ROTATION_90 and ROTATION_270. TODO(b/265991392): This should eventually be configured and parsed in display_settings.xml --> - <bool name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay">true</bool> + <bool name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay">false</bool> <!-- Indicate available ColorDisplayManager.COLOR_MODE_xxx. --> <integer-array name="config_availableColorModes"> diff --git a/core/tests/BroadcastRadioTests/Android.bp b/core/tests/BroadcastRadioTests/Android.bp index 436f058f3cbc..136bd79e0037 100644 --- a/core/tests/BroadcastRadioTests/Android.bp +++ b/core/tests/BroadcastRadioTests/Android.bp @@ -38,7 +38,7 @@ android_test { static_libs: [ "services.core", "androidx.test.rules", - "truth-prebuilt", + "truth", "testng", "mockito-target-extended", ], diff --git a/core/tests/GameManagerTests/Android.bp b/core/tests/GameManagerTests/Android.bp index 8c5d6d5a76a1..0e3bc6562edb 100644 --- a/core/tests/GameManagerTests/Android.bp +++ b/core/tests/GameManagerTests/Android.bp @@ -30,7 +30,7 @@ android_test { "frameworks-base-testutils", "junit", "platform-test-annotations", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], platform_apis: true, diff --git a/core/tests/PackageInstallerSessions/Android.bp b/core/tests/PackageInstallerSessions/Android.bp index 6f2366e32574..b631df1fcf57 100644 --- a/core/tests/PackageInstallerSessions/Android.bp +++ b/core/tests/PackageInstallerSessions/Android.bp @@ -35,7 +35,7 @@ android_test { "frameworks-base-testutils", "platform-test-annotations", "testng", - "truth-prebuilt", + "truth", ], libs: [ diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp index 52608351775c..1fb5f2c0789b 100644 --- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp +++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp @@ -18,7 +18,7 @@ android_test { "platform-test-annotations", "platformprotosnano", "statsdprotolite", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp index 2b34ee2646f3..7c1ac487bfdb 100644 --- a/core/tests/bugreports/Android.bp +++ b/core/tests/bugreports/Android.bp @@ -32,7 +32,7 @@ android_test { static_libs: [ "androidx.test.rules", "androidx.test.uiautomator_uiautomator", - "truth-prebuilt", + "truth", ], test_suites: ["general-tests"], sdk_version: "test_current", diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 286697cbd940..65af1c61052a 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -56,7 +56,7 @@ android_test { "ub-uiautomator", "platform-test-annotations", "platform-compat-test-rules", - "truth-prebuilt", + "truth", "print-test-util-lib", "testng", "servicestests-utils", @@ -148,7 +148,7 @@ android_library { "androidx.test.runner", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], libs: [ diff --git a/core/tests/coretests/src/android/app/KeyguardManagerTest.java b/core/tests/coretests/src/android/app/KeyguardManagerTest.java index 958906c36d05..ed8b2887ac79 100644 --- a/core/tests/coretests/src/android/app/KeyguardManagerTest.java +++ b/core/tests/coretests/src/android/app/KeyguardManagerTest.java @@ -174,6 +174,22 @@ public class KeyguardManagerTest { } @Test + public void setLock_validatesCredential() { + // setLock() should validate the credential before setting it. Test one example, which is + // that PINs must contain only ASCII digits 0-9, i.e. bytes 48-57. Using bytes 0-9 is + // incorrect and should *not* be accepted. + byte[] invalidPin = new byte[] { 1, 2, 3, 4 }; + byte[] validPin = "1234".getBytes(); + + assertFalse(mKeyguardManager.setLock(KeyguardManager.PIN, invalidPin, -1, null)); + assertFalse(mKeyguardManager.isDeviceSecure()); + + assertTrue(mKeyguardManager.setLock(KeyguardManager.PIN, validPin, -1, null)); + assertTrue(mKeyguardManager.isDeviceSecure()); + assertTrue(mKeyguardManager.setLock(-1, null, KeyguardManager.PIN, validPin)); + } + + @Test public void checkLock_correctCredentials() { // Set to `true` to behave as if SET_INITIAL_LOCK permission had been granted. doReturn(true).when(mKeyguardManager).checkInitialLockMethodUsage(); diff --git a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java index c9e02f8a998d..33e81c163b4e 100644 --- a/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java +++ b/core/tests/coretests/src/android/app/admin/PasswordMetricsTest.java @@ -25,6 +25,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; import static android.app.admin.PasswordMetrics.complexityLevelToMinQuality; import static android.app.admin.PasswordMetrics.sanitizeComplexityLevel; +import static android.app.admin.PasswordMetrics.validateCredential; import static android.app.admin.PasswordMetrics.validatePasswordMetrics; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; @@ -41,6 +42,8 @@ import android.platform.test.annotations.Presubmit; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; +import com.android.internal.widget.LockPatternUtils; +import com.android.internal.widget.LockscreenCredential; import com.android.internal.widget.PasswordValidationError; import org.junit.Test; @@ -94,8 +97,7 @@ public class PasswordMetricsTest { @Test public void testComputeForPassword_metrics() { - final PasswordMetrics metrics = PasswordMetrics.computeForPasswordOrPin( - "6B~0z1Z3*8A".getBytes(), /* isPin */ false); + final PasswordMetrics metrics = metricsForPassword("6B~0z1Z3*8A"); assertEquals(11, metrics.length); assertEquals(4, metrics.letters); assertEquals(3, metrics.upperCase); @@ -133,72 +135,54 @@ public class PasswordMetricsTest { @Test public void testDetermineComplexity_lowNumeric() { - assertEquals(PASSWORD_COMPLEXITY_LOW, - PasswordMetrics.computeForPasswordOrPin("1234".getBytes(), - /* isPin */true).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPin("1234").determineComplexity()); } @Test public void testDetermineComplexity_lowNumericComplex() { - assertEquals(PASSWORD_COMPLEXITY_LOW, - PasswordMetrics.computeForPasswordOrPin("124".getBytes(), - /* isPin */ true).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPin("124").determineComplexity()); } @Test public void testDetermineComplexity_lowAlphabetic() { - assertEquals(PASSWORD_COMPLEXITY_LOW, - PasswordMetrics.computeForPasswordOrPin("a!".getBytes(), - /* isPin */ false).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPassword("a!").determineComplexity()); } @Test public void testDetermineComplexity_lowAlphanumeric() { - assertEquals(PASSWORD_COMPLEXITY_LOW, - PasswordMetrics.computeForPasswordOrPin("a!1".getBytes(), - /* isPin */ false).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_LOW, metricsForPassword("a!1").determineComplexity()); } @Test public void testDetermineComplexity_mediumNumericComplex() { - assertEquals(PASSWORD_COMPLEXITY_MEDIUM, - PasswordMetrics.computeForPasswordOrPin("1238".getBytes(), - /* isPin */ true).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_MEDIUM, metricsForPin("1238").determineComplexity()); } @Test public void testDetermineComplexity_mediumAlphabetic() { - assertEquals(PASSWORD_COMPLEXITY_MEDIUM, - PasswordMetrics.computeForPasswordOrPin("ab!c".getBytes(), - /* isPin */ false).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_MEDIUM, metricsForPassword("ab!c").determineComplexity()); } @Test public void testDetermineComplexity_mediumAlphanumeric() { - assertEquals(PASSWORD_COMPLEXITY_MEDIUM, - PasswordMetrics.computeForPasswordOrPin("ab!1".getBytes(), - /* isPin */ false).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_MEDIUM, metricsForPassword("ab!1").determineComplexity()); } @Test public void testDetermineComplexity_highNumericComplex() { - assertEquals(PASSWORD_COMPLEXITY_HIGH, - PasswordMetrics.computeForPasswordOrPin("12389647!".getBytes(), - /* isPin */ true).determineComplexity()); + assertEquals(PASSWORD_COMPLEXITY_HIGH, metricsForPin("12389647!").determineComplexity()); } @Test public void testDetermineComplexity_highAlphabetic() { assertEquals(PASSWORD_COMPLEXITY_HIGH, - PasswordMetrics.computeForPasswordOrPin("alphabetic!".getBytes(), - /* isPin */ false).determineComplexity()); + metricsForPassword("alphabetic!").determineComplexity()); } @Test public void testDetermineComplexity_highAlphanumeric() { assertEquals(PASSWORD_COMPLEXITY_HIGH, - PasswordMetrics.computeForPasswordOrPin("alphanumeric123!".getBytes(), - /* isPin */ false).determineComplexity()); + metricsForPassword("alphanumeric123!").determineComplexity()); } @Test @@ -374,8 +358,74 @@ public class PasswordMetricsTest { PasswordValidationError.NOT_ENOUGH_NON_DIGITS, 1); } + @Test + public void testValidateCredential_none() { + PasswordMetrics adminMetrics; + LockscreenCredential none = LockscreenCredential.createNone(); + + adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE); + assertValidationErrors( + validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, none)); + + adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_PIN); + assertValidationErrors( + validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, none), + PasswordValidationError.WEAK_CREDENTIAL_TYPE, 0); + } + + @Test + public void testValidateCredential_password() { + PasswordMetrics adminMetrics; + LockscreenCredential password; + + adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE); + password = LockscreenCredential.createPassword("password"); + assertValidationErrors( + validateCredential(adminMetrics, PASSWORD_COMPLEXITY_LOW, password)); + + // Test that validateCredential() checks LockscreenCredential#hasInvalidChars(). + adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE); + password = LockscreenCredential.createPassword("™™™™"); + assertTrue(password.hasInvalidChars()); + assertValidationErrors( + validateCredential(adminMetrics, PASSWORD_COMPLEXITY_LOW, password), + PasswordValidationError.CONTAINS_INVALID_CHARACTERS, 0); + + // Test one more case where validateCredential() should reject the password. Beyond this, + // the unit tests for the lower-level method validatePasswordMetrics() should be sufficient. + adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE); + adminMetrics.length = 6; + password = LockscreenCredential.createPassword("pass"); + assertValidationErrors( + validateCredential(adminMetrics, PASSWORD_COMPLEXITY_LOW, password), + PasswordValidationError.TOO_SHORT, 6); + } + + private LockscreenCredential createPattern(String patternString) { + return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern( + patternString.getBytes())); + } + + private static PasswordMetrics metricsForPassword(String password) { + return PasswordMetrics.computeForCredential(LockscreenCredential.createPassword(password)); + } + + private static PasswordMetrics metricsForPin(String pin) { + return PasswordMetrics.computeForCredential(LockscreenCredential.createPin(pin)); + } + + @Test + public void testValidateCredential_pattern() { + PasswordMetrics adminMetrics = new PasswordMetrics(CREDENTIAL_TYPE_NONE); + assertValidationErrors( + validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, createPattern("123")), + PasswordValidationError.TOO_SHORT, 4); + assertValidationErrors( + validateCredential(adminMetrics, PASSWORD_COMPLEXITY_NONE, createPattern("1234"))); + } + /** - * @param expected sequense of validation error codes followed by requirement values, must have + * @param expected sequence of validation error codes followed by requirement values, must have * even number of elements. Empty means no errors. */ private void assertValidationErrors( diff --git a/core/tests/coretests/src/android/view/ViewGroupTest.java b/core/tests/coretests/src/android/view/ViewGroupTest.java index b37c8fd8c34e..bce3f3e8f2e1 100644 --- a/core/tests/coretests/src/android/view/ViewGroupTest.java +++ b/core/tests/coretests/src/android/view/ViewGroupTest.java @@ -49,11 +49,11 @@ public class ViewGroupTest { public void testDispatchMouseEventsUnderCursor() { final Context context = getInstrumentation().getContext(); final TestView viewGroup = new TestView(context, 0 /* left */, 0 /* top */, - 200 /* right */, 200 /* bottom */); + 200 /* right */, 100 /* bottom */); final TestView viewA = spy(new TestView(context, 0 /* left */, 0 /* top */, - 100 /* right */, 200 /* bottom */)); + 100 /* right */, 100 /* bottom */)); final TestView viewB = spy(new TestView(context, 100 /* left */, 0 /* top */, - 200 /* right */, 200 /* bottom */)); + 200 /* right */, 100 /* bottom */)); viewGroup.addView(viewA); viewGroup.addView(viewB); @@ -73,10 +73,10 @@ public class ViewGroupTest { MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[2]; coords[0] = new MotionEvent.PointerCoords(); coords[0].x = 80; - coords[0].y = 100; + coords[0].y = 50; coords[1] = new MotionEvent.PointerCoords(); coords[1].x = 240; - coords[1].y = 100; + coords[1].y = 50; MotionEvent event; // Make sure the down event is active with a pointer which coordinate is different from the @@ -91,6 +91,10 @@ public class ViewGroupTest { viewGroup.onResolvePointerIcon(event, 0 /* pointerIndex */); verify(viewB).onResolvePointerIcon(event, 0); + event.setAction(MotionEvent.ACTION_SCROLL); + viewGroup.dispatchGenericMotionEvent(event); + verify(viewB).dispatchGenericMotionEvent(event); + event = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */, MotionEvent.ACTION_POINTER_DOWN | (1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT), 2 /* pointerCount */, properties, coords, 0 /* metaState */, 0 /* buttonState */, @@ -102,8 +106,13 @@ public class ViewGroupTest { viewGroup.onResolvePointerIcon(event, 1 /* pointerIndex */); verify(viewB).onResolvePointerIcon(event, 1); + event.setAction(MotionEvent.ACTION_SCROLL); + viewGroup.dispatchGenericMotionEvent(event); + verify(viewB).dispatchGenericMotionEvent(event); + verify(viewA, never()).dispatchTouchEvent(any()); verify(viewA, never()).onResolvePointerIcon(any(), anyInt()); + verify(viewA, never()).dispatchGenericMotionEvent(any()); } /** diff --git a/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java b/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java index a47868d0a524..5692742f7248 100644 --- a/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java +++ b/core/tests/coretests/src/com/android/internal/widget/LockscreenCredentialTest.java @@ -16,52 +16,71 @@ package com.android.internal.widget; - import static com.google.common.truth.Truth.assertThat; -import android.test.AndroidTestCase; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; -import java.util.Arrays; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; -public class LockscreenCredentialTest extends AndroidTestCase { +import java.util.Arrays; - public void testEmptyCredential() { - LockscreenCredential empty = LockscreenCredential.createNone(); +@RunWith(AndroidJUnit4.class) +public class LockscreenCredentialTest { - assertTrue(empty.isNone()); - assertEquals(0, empty.size()); - assertNotNull(empty.getCredential()); + @Test + public void testNoneCredential() { + LockscreenCredential none = LockscreenCredential.createNone(); - assertFalse(empty.isPin()); - assertFalse(empty.isPassword()); - assertFalse(empty.isPattern()); + assertTrue(none.isNone()); + assertEquals(0, none.size()); + assertArrayEquals(new byte[0], none.getCredential()); + + assertFalse(none.isPin()); + assertFalse(none.isPassword()); + assertFalse(none.isPattern()); + assertFalse(none.hasInvalidChars()); + none.validateBasicRequirements(); } + @Test public void testPinCredential() { LockscreenCredential pin = LockscreenCredential.createPin("3456"); assertTrue(pin.isPin()); assertEquals(4, pin.size()); - assertTrue(Arrays.equals("3456".getBytes(), pin.getCredential())); + assertArrayEquals("3456".getBytes(), pin.getCredential()); assertFalse(pin.isNone()); assertFalse(pin.isPassword()); assertFalse(pin.isPattern()); + assertFalse(pin.hasInvalidChars()); + pin.validateBasicRequirements(); } + @Test public void testPasswordCredential() { LockscreenCredential password = LockscreenCredential.createPassword("password"); assertTrue(password.isPassword()); assertEquals(8, password.size()); - assertTrue(Arrays.equals("password".getBytes(), password.getCredential())); + assertArrayEquals("password".getBytes(), password.getCredential()); assertFalse(password.isNone()); assertFalse(password.isPin()); assertFalse(password.isPattern()); + assertFalse(password.hasInvalidChars()); + password.validateBasicRequirements(); } + @Test public void testPatternCredential() { LockscreenCredential pattern = LockscreenCredential.createPattern(Arrays.asList( LockPatternView.Cell.of(0, 0), @@ -73,13 +92,34 @@ public class LockscreenCredentialTest extends AndroidTestCase { assertTrue(pattern.isPattern()); assertEquals(5, pattern.size()); - assertTrue(Arrays.equals("12369".getBytes(), pattern.getCredential())); + assertArrayEquals("12369".getBytes(), pattern.getCredential()); assertFalse(pattern.isNone()); assertFalse(pattern.isPin()); assertFalse(pattern.isPassword()); + assertFalse(pattern.hasInvalidChars()); + pattern.validateBasicRequirements(); } + // Constructing a LockscreenCredential with a too-short length, even 0, should not throw an + // exception. This is because LockscreenCredential needs to be able to represent a request to + // set a credential that is too short. + @Test + public void testZeroLengthCredential() { + LockscreenCredential credential = LockscreenCredential.createPin(""); + assertTrue(credential.isPin()); + assertEquals(0, credential.size()); + + credential = createPattern(""); + assertTrue(credential.isPattern()); + assertEquals(0, credential.size()); + + credential = LockscreenCredential.createPassword(""); + assertTrue(credential.isPassword()); + assertEquals(0, credential.size()); + } + + @Test public void testPasswordOrNoneCredential() { assertEquals(LockscreenCredential.createNone(), LockscreenCredential.createPasswordOrNone(null)); @@ -89,6 +129,7 @@ public class LockscreenCredentialTest extends AndroidTestCase { LockscreenCredential.createPasswordOrNone("abcd")); } + @Test public void testPinOrNoneCredential() { assertEquals(LockscreenCredential.createNone(), LockscreenCredential.createPinOrNone(null)); @@ -98,6 +139,35 @@ public class LockscreenCredentialTest extends AndroidTestCase { LockscreenCredential.createPinOrNone("1357")); } + // Test that passwords containing invalid characters that were incorrectly allowed in + // Android 10–14 are still interpreted in the same way, but are not allowed for new passwords. + @Test + public void testPasswordWithInvalidChars() { + // ™ is U+2122, which was truncated to ASCII 0x22 which is double quote. + String[] passwords = new String[] { "foo™", "™™™™", "™foo" }; + String[] equivalentAsciiPasswords = new String[] { "foo\"", "\"\"\"\"", "\"foo" }; + for (int i = 0; i < passwords.length; i++) { + LockscreenCredential credential = LockscreenCredential.createPassword(passwords[i]); + assertTrue(credential.hasInvalidChars()); + assertArrayEquals(equivalentAsciiPasswords[i].getBytes(), credential.getCredential()); + try { + credential.validateBasicRequirements(); + fail("should not be able to set password with invalid chars"); + } catch (IllegalArgumentException expected) { } + } + } + + @Test + public void testPinWithInvalidChars() { + LockscreenCredential pin = LockscreenCredential.createPin("\n\n\n\n"); + assertTrue(pin.hasInvalidChars()); + try { + pin.validateBasicRequirements(); + fail("should not be able to set PIN with invalid chars"); + } catch (IllegalArgumentException expected) { } + } + + @Test public void testSanitize() { LockscreenCredential password = LockscreenCredential.createPassword("password"); password.zeroize(); @@ -123,11 +193,16 @@ public class LockscreenCredentialTest extends AndroidTestCase { fail("Sanitized credential still accessible"); } catch (IllegalStateException expected) { } try { + password.hasInvalidChars(); + fail("Sanitized credential still accessible"); + } catch (IllegalStateException expected) { } + try { password.getCredential(); fail("Sanitized credential still accessible"); } catch (IllegalStateException expected) { } } + @Test public void testEquals() { assertEquals(LockscreenCredential.createNone(), LockscreenCredential.createNone()); assertEquals(LockscreenCredential.createPassword("1234"), @@ -136,34 +211,40 @@ public class LockscreenCredentialTest extends AndroidTestCase { LockscreenCredential.createPin("4321")); assertEquals(createPattern("1234"), createPattern("1234")); - assertNotSame(LockscreenCredential.createPassword("1234"), + assertNotEquals(LockscreenCredential.createPassword("1234"), LockscreenCredential.createNone()); - assertNotSame(LockscreenCredential.createPassword("1234"), + assertNotEquals(LockscreenCredential.createPassword("1234"), LockscreenCredential.createPassword("4321")); - assertNotSame(LockscreenCredential.createPassword("1234"), + assertNotEquals(LockscreenCredential.createPassword("1234"), createPattern("1234")); - assertNotSame(LockscreenCredential.createPassword("1234"), + assertNotEquals(LockscreenCredential.createPassword("1234"), LockscreenCredential.createPin("1234")); - assertNotSame(LockscreenCredential.createPin("1111"), + assertNotEquals(LockscreenCredential.createPin("1111"), LockscreenCredential.createNone()); - assertNotSame(LockscreenCredential.createPin("1111"), + assertNotEquals(LockscreenCredential.createPin("1111"), LockscreenCredential.createPin("2222")); - assertNotSame(LockscreenCredential.createPin("1111"), + assertNotEquals(LockscreenCredential.createPin("1111"), createPattern("1111")); - assertNotSame(LockscreenCredential.createPin("1111"), + assertNotEquals(LockscreenCredential.createPin("1111"), LockscreenCredential.createPassword("1111")); - assertNotSame(createPattern("5678"), + assertNotEquals(createPattern("5678"), LockscreenCredential.createNone()); - assertNotSame(createPattern("5678"), + assertNotEquals(createPattern("5678"), createPattern("1234")); - assertNotSame(createPattern("5678"), + assertNotEquals(createPattern("5678"), LockscreenCredential.createPassword("5678")); - assertNotSame(createPattern("5678"), + assertNotEquals(createPattern("5678"), LockscreenCredential.createPin("5678")); + + // Test that mHasInvalidChars is compared. To do this, compare two passwords that map to + // the same byte[] (due to the truncation bug) but different values of mHasInvalidChars. + assertNotEquals(LockscreenCredential.createPassword("™™™™"), + LockscreenCredential.createPassword("\"\"\"\"")); } + @Test public void testDuplicate() { LockscreenCredential credential; @@ -175,8 +256,13 @@ public class LockscreenCredentialTest extends AndroidTestCase { assertEquals(credential, credential.duplicate()); credential = createPattern("5678"); assertEquals(credential, credential.duplicate()); + + // Test that mHasInvalidChars is duplicated. + credential = LockscreenCredential.createPassword("™™™™"); + assertEquals(credential, credential.duplicate()); } + @Test public void testPasswordToHistoryHash() { String password = "1234"; LockscreenCredential credential = LockscreenCredential.createPassword(password); @@ -193,6 +279,7 @@ public class LockscreenCredentialTest extends AndroidTestCase { .isEqualTo(expectedHash); } + @Test public void testPasswordToHistoryHashInvalidInput() { String password = "1234"; LockscreenCredential credential = LockscreenCredential.createPassword(password); @@ -221,6 +308,7 @@ public class LockscreenCredentialTest extends AndroidTestCase { .isNull(); } + @Test public void testLegacyPasswordToHash() { String password = "1234"; String salt = "6d5331dd120077a0"; @@ -233,6 +321,7 @@ public class LockscreenCredentialTest extends AndroidTestCase { .isEqualTo(expectedHash); } + @Test public void testLegacyPasswordToHashInvalidInput() { String password = "1234"; String salt = "6d5331dd120077a0"; diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp index 3d04937c9195..5f6eaf96a846 100644 --- a/core/tests/hdmitests/Android.bp +++ b/core/tests/hdmitests/Android.bp @@ -30,7 +30,7 @@ android_test { "frameworks-base-testutils", "guava-android-testlib", "platform-test-annotations", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], platform_apis: true, diff --git a/core/tests/mockingcoretests/Android.bp b/core/tests/mockingcoretests/Android.bp index 96811be37f5a..a2dd914a84ae 100644 --- a/core/tests/mockingcoretests/Android.bp +++ b/core/tests/mockingcoretests/Android.bp @@ -38,7 +38,7 @@ android_test { "androidx.test.ext.junit", "mockito-target-extended-minus-junit4", "platform-test-annotations", - "truth-prebuilt", + "truth", "testables", "ub-uiautomator", ], diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp index c74600bbab22..f81be494ad18 100644 --- a/core/tests/nfctests/Android.bp +++ b/core/tests/nfctests/Android.bp @@ -27,7 +27,7 @@ android_test { "androidx.test.ext.junit", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], libs: [ "android.test.runner", diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp index 063c5694ab5b..931eac515e31 100644 --- a/core/tests/overlaytests/device_self_targeting/Android.bp +++ b/core/tests/overlaytests/device_self_targeting/Android.bp @@ -30,7 +30,7 @@ android_test { "androidx.test.runner", "androidx.test.ext.junit", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], optimize: { diff --git a/core/tests/privacytests/Android.bp b/core/tests/privacytests/Android.bp index bc3dd810be8c..4e24cd5d91cb 100644 --- a/core/tests/privacytests/Android.bp +++ b/core/tests/privacytests/Android.bp @@ -14,7 +14,7 @@ android_test { "junit", "rappor-tests", "androidx.test.rules", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], platform_apis: true, diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp index 3798da592cd5..580e73c331a1 100644 --- a/core/tests/utiltests/Android.bp +++ b/core/tests/utiltests/Android.bp @@ -33,7 +33,7 @@ android_test { "frameworks-base-testutils", "mockito-target-minus-junit4", "androidx.test.ext.junit", - "truth-prebuilt", + "truth", "servicestests-utils", ], diff --git a/errorprone/Android.bp b/errorprone/Android.bp index 8f32f0eab37f..3328708ed17d 100644 --- a/errorprone/Android.bp +++ b/errorprone/Android.bp @@ -39,7 +39,7 @@ java_test_host { java_resource_dirs: ["tests/res"], java_resources: [":error_prone_android_framework_testdata"], static_libs: [ - "truth-prebuilt", + "truth", "kxml2-2.3.0", "compile-testing-prebuilt", "error_prone_android_framework_lib", diff --git a/keystore/aaid/aidl/Android.bp b/keystore/aaid/aidl/Android.bp new file mode 100644 index 000000000000..97acfb4ea4c3 --- /dev/null +++ b/keystore/aaid/aidl/Android.bp @@ -0,0 +1,31 @@ +// Copyright 2020, 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 { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +aidl_interface { + name: "android.security.aaid_aidl", + srcs: ["android/security/keystore/*.aidl"], + unstable: true, + backend: { + rust: { + enabled: true, + }, + cpp: { + enabled: true, + }, + }, +} diff --git a/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl b/keystore/aaid/aidl/android/security/keystore/IKeyAttestationApplicationIdProvider.aidl index dbffd5f57ce2..c360cb8f281a 100644 --- a/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl +++ b/keystore/aaid/aidl/android/security/keystore/IKeyAttestationApplicationIdProvider.aidl @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016, The Android Open Source Project + * Copyright (c) 2023, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,19 +14,15 @@ * limitations under the License. */ -package android.security.keymaster; +package android.security.keystore; -import android.security.keymaster.KeyAttestationApplicationId; -import android.security.keymaster.KeyAttestationPackageInfo; -import android.content.pm.Signature; +import android.security.keystore.KeyAttestationApplicationId; -/** - * This must be kept manually in sync with system/security/keystore until AIDL - * can generate both Java and C++ bindings. - * - * @hide - */ +/** @hide */ interface IKeyAttestationApplicationIdProvider { - /* keep in sync with /system/security/keystore/keystore_attestation_id.cpp */ + /** + * Provides information describing the possible applications identified by a UID. + * @hide + */ KeyAttestationApplicationId getKeyAttestationApplicationId(int uid); } diff --git a/keystore/aaid/aidl/android/security/keystore/KeyAttestationApplicationId.aidl b/keystore/aaid/aidl/android/security/keystore/KeyAttestationApplicationId.aidl new file mode 100644 index 000000000000..c33e8309b2f2 --- /dev/null +++ b/keystore/aaid/aidl/android/security/keystore/KeyAttestationApplicationId.aidl @@ -0,0 +1,31 @@ +/* + * 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 android.security.keystore; + +import android.security.keystore.KeyAttestationPackageInfo; + +/** + * @hide + * The information aggregated by this parcelable is used by keystore to identify a caller of the + * keystore API toward a remote party. It aggregates multiple PackageInfos because keystore + * can only determine a caller by uid granularity, and a uid can be shared by multiple packages. + * The remote party must decide if it trusts all of the packages enough to consider the + * confidentiality of the key material in question intact. + */ +parcelable KeyAttestationApplicationId { + KeyAttestationPackageInfo[] packageInfos; +} diff --git a/core/java/android/security/keymaster/KeyAttestationPackageInfo.aidl b/keystore/aaid/aidl/android/security/keystore/KeyAttestationPackageInfo.aidl index f8b843bc032f..5f647d0b1abe 100644 --- a/core/java/android/security/keymaster/KeyAttestationPackageInfo.aidl +++ b/keystore/aaid/aidl/android/security/keystore/KeyAttestationPackageInfo.aidl @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, The Android Open Source Project + * Copyright (c) 2023, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,20 @@ * limitations under the License. */ -package android.security.keymaster; +package android.security.keystore; -/* The cpp_header is relative to system/security/keystore/include - * Link against libkeystore_binder to make use of the native implementation of this Parcelable. +import android.security.keystore.Signature; + +/** + * @hide + * This parcelable constitutes and excerpt from the PackageManager's PackageInfo for the purpose of + * key attestation. It is part of the KeyAttestationApplicationId, which is used by + * keystore to identify the caller of the keystore API towards a remote party. */ -parcelable KeyAttestationPackageInfo cpp_header "keystore/KeyAttestationPackageInfo.h"; +parcelable KeyAttestationPackageInfo { + String packageName; + + long versionCode; + + Signature[] signatures; +} diff --git a/core/java/android/security/keymaster/KeyAttestationApplicationId.aidl b/keystore/aaid/aidl/android/security/keystore/Signature.aidl index 9f6ff58ed5ce..800499a13355 100644 --- a/core/java/android/security/keymaster/KeyAttestationApplicationId.aidl +++ b/keystore/aaid/aidl/android/security/keystore/Signature.aidl @@ -14,9 +14,18 @@ * limitations under the License. */ -package android.security.keymaster; +package android.security.keystore; -/* The cpp_header is relative to system/security/keystore/include - * Link against libkeystore_binder to make use of the native implementation of this Parcelable. +/** + * @hide + * Represents a signature data read from the package file. Extracted from from the PackageManager's + * PackageInfo for the purpose of key attestation. It is part of the KeyAttestationPackageInfo, + * which is used by keystore to identify the caller of the keystore API towards a remote party. */ -parcelable KeyAttestationApplicationId cpp_header "keystore/KeyAttestationApplicationId.h"; +parcelable Signature { + /** + * Represents signing certificate data associated with application package, signatures are + * expected to be a hex-encoded ASCII string representing valid X509 certificate. + */ + byte[] data; +} diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java index 0f3488bbe8d1..31c2eb2efaed 100644 --- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java +++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java @@ -28,8 +28,8 @@ import android.system.keystore2.ResponseCode; import android.util.Log; /** - * @hide This is the client side for IKeystoreUserManager AIDL. - * It shall only be used by the LockSettingsService. + * @hide This is the client side for IKeystoreMaintenance AIDL. + * It is used mainly by LockSettingsService. */ public class AndroidKeyStoreMaintenance { private static final String TAG = "AndroidKeyStoreMaintenance"; @@ -66,7 +66,7 @@ public class AndroidKeyStoreMaintenance { } /** - * Informs Keystore 2.0 about removing a usergit mer + * Informs Keystore 2.0 about removing a user * * @param userId - Android user id of the user being removed * @return 0 if successful or a {@code ResponseCode} @@ -91,7 +91,7 @@ public class AndroidKeyStoreMaintenance { * * @param userId - Android user id of the user * @param password - a secret derived from the synthetic password provided by the - * LockSettingService + * LockSettingsService * @return 0 if successful or a {@code ResponseCode} * @hide */ @@ -110,7 +110,7 @@ public class AndroidKeyStoreMaintenance { } /** - * Informs Keystore 2.0 that an app was uninstalled and the corresponding namspace is to + * Informs Keystore 2.0 that an app was uninstalled and the corresponding namespace is to * be cleared. */ public static int clearNamespace(@Domain int domain, long namespace) { @@ -172,10 +172,10 @@ public class AndroidKeyStoreMaintenance { * namespace. * * @return * 0 on success - * * KEY_NOT_FOUND if the source did not exists. + * * KEY_NOT_FOUND if the source did not exist. * * PERMISSION_DENIED if any of the required permissions was missing. * * INVALID_ARGUMENT if the destination was occupied or any domain value other than - * the allowed once were specified. + * the allowed ones was specified. * * SYSTEM_ERROR if an unexpected error occurred. */ public static int migrateKeyNamespace(KeyDescriptor source, KeyDescriptor destination) { diff --git a/libs/WindowManager/Jetpack/tests/unittest/Android.bp b/libs/WindowManager/Jetpack/tests/unittest/Android.bp index b6e743a2b7e1..ed2ff2de245b 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/Android.bp +++ b/libs/WindowManager/Jetpack/tests/unittest/Android.bp @@ -37,7 +37,7 @@ android_test { "androidx.test.rules", "androidx.test.ext.junit", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", "testables", "platform-test-annotations", ], diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp index b6696c70dbb1..82bcec4b63da 100644 --- a/libs/WindowManager/Shell/tests/flicker/Android.bp +++ b/libs/WindowManager/Shell/tests/flicker/Android.bp @@ -43,7 +43,7 @@ android_test { "flickerlib", "flickerlib-apphelpers", "flickerlib-helpers", - "truth-prebuilt", + "truth", "app-helpers-core", "launcher-helper-lib", "launcher-aosp-tapl", diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp index 38e9f390835c..34ca1d0ecd9d 100644 --- a/libs/WindowManager/Shell/tests/unittest/Android.bp +++ b/libs/WindowManager/Shell/tests/unittest/Android.bp @@ -44,7 +44,7 @@ android_test { "kotlinx-coroutines-android", "kotlinx-coroutines-core", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", "testables", "platform-test-annotations", "servicestests-utils", diff --git a/libs/dream/lowlight/tests/Android.bp b/libs/dream/lowlight/tests/Android.bp index 2d79090cd7d4..c256e2f364fb 100644 --- a/libs/dream/lowlight/tests/Android.bp +++ b/libs/dream/lowlight/tests/Android.bp @@ -33,7 +33,7 @@ android_test { "mockito-target-extended-minus-junit4", "platform-test-annotations", "testables", - "truth-prebuilt", + "truth", ], libs: [ "android.test.mock", diff --git a/libs/securebox/tests/Android.bp b/libs/securebox/tests/Android.bp index 7df546ae0ff6..80b501da1aa5 100644 --- a/libs/securebox/tests/Android.bp +++ b/libs/securebox/tests/Android.bp @@ -32,7 +32,7 @@ android_test { "platform-test-annotations", "testables", "testng", - "truth-prebuilt", + "truth", ], libs: [ "android.test.mock", diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp index 4cccf8972798..61b18c88e734 100644 --- a/media/tests/MediaRouter/Android.bp +++ b/media/tests/MediaRouter/Android.bp @@ -24,7 +24,7 @@ android_test { "compatibility-device-util-axt", "mockito-target-minus-junit4", "testng", - "truth-prebuilt", + "truth", ], test_suites: ["general-tests"], platform_apis: true, diff --git a/media/tests/projection/Android.bp b/media/tests/projection/Android.bp index e313c46d1973..48cd8b69ade8 100644 --- a/media/tests/projection/Android.bp +++ b/media/tests/projection/Android.bp @@ -30,7 +30,7 @@ android_test { "platform-test-annotations", "testng", "testables", - "truth-prebuilt", + "truth", "platform-compat-test-rules", ], diff --git a/packages/ExternalStorageProvider/tests/Android.bp b/packages/ExternalStorageProvider/tests/Android.bp index 633f18610921..86c62ef299e4 100644 --- a/packages/ExternalStorageProvider/tests/Android.bp +++ b/packages/ExternalStorageProvider/tests/Android.bp @@ -25,7 +25,7 @@ android_test { static_libs: [ "androidx.test.rules", "mockito-target", - "truth-prebuilt", + "truth", ], certificate: "platform", diff --git a/packages/FusedLocation/Android.bp b/packages/FusedLocation/Android.bp index 64b4c54e74ad..61a82701d155 100644 --- a/packages/FusedLocation/Android.bp +++ b/packages/FusedLocation/Android.bp @@ -47,7 +47,7 @@ android_test { test_config: "test/AndroidTest.xml", srcs: [ "test/src/**/*.java", - "src/**/*.java", // include real sources because we're forced to test this directly + "src/**/*.java", // include real sources because we're forced to test this directly ], libs: [ "android.test.base", @@ -60,9 +60,9 @@ android_test { "androidx.test.ext.junit", "androidx.test.ext.truth", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], platform_apis: true, certificate: "platform", - test_suites: ["device-tests"] + test_suites: ["device-tests"], } diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp index 2c1e1c2abc2c..5622d9d9bf76 100644 --- a/packages/SettingsLib/Spa/testutils/Android.bp +++ b/packages/SettingsLib/Spa/testutils/Android.bp @@ -30,7 +30,7 @@ android_library { "androidx.compose.ui_ui-test-junit4", "androidx.compose.ui_ui-test-manifest", "mockito", - "truth-prebuilt", + "truth", ], kotlincflags: [ "-Xjvm-default=all", diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp index ff3eeec4171f..bb57e25f30b3 100644 --- a/packages/SettingsLib/tests/integ/Android.bp +++ b/packages/SettingsLib/tests/integ/Android.bp @@ -49,7 +49,7 @@ android_test { "androidx.test.rules", "androidx.test.espresso.core", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", "SettingsLibDeviceStateRotationLock", "SettingsLibSettingsSpinner", "SettingsLibUsageProgressBarPreference", diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp index 5c55a435b463..ba2e57ac7cd1 100644 --- a/packages/SettingsLib/tests/robotests/Android.bp +++ b/packages/SettingsLib/tests/robotests/Android.bp @@ -64,6 +64,6 @@ java_library { libs: [ "Robolectric_all-target", "mockito-robolectric-prebuilt", - "truth-prebuilt", + "truth", ], } diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp index a4558f1bd40b..0c96f20428c6 100644 --- a/packages/SettingsLib/tests/unit/Android.bp +++ b/packages/SettingsLib/tests/unit/Android.bp @@ -30,6 +30,6 @@ android_test { "SettingsLib", "androidx.test.ext.junit", "androidx.test.runner", - "truth-prebuilt", + "truth", ], } diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp index 346462df004b..c7e804c668d1 100644 --- a/packages/SettingsProvider/Android.bp +++ b/packages/SettingsProvider/Android.bp @@ -60,7 +60,7 @@ android_test { "SettingsLibDeviceStateRotationLock", "SettingsLibDisplayUtils", "platform-test-annotations", - "truth-prebuilt", + "truth", ], libs: [ "android.test.base", diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index a50b182f5270..8ca925b99749 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -354,7 +354,7 @@ android_library { "hamcrest-library", "androidx.test.rules", "testables", - "truth-prebuilt", + "truth", "monet", "dagger2", "jsr330", @@ -461,7 +461,7 @@ android_robolectric_test { "android.test.runner", "android.test.base", "android.test.mock", - "truth-prebuilt", + "truth", ], upstream: true, diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp index 1757dda84eef..17db1ace63ed 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp +++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp @@ -31,7 +31,7 @@ android_test { "androidx.test.ext.junit", "compatibility-device-util-axt", "platform-test-annotations", - "truth-prebuilt", + "truth", ], srcs: [ "src/**/*.java", diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp index 155dc1a68295..18f783146c72 100644 --- a/packages/WallpaperBackup/Android.bp +++ b/packages/WallpaperBackup/Android.bp @@ -49,7 +49,7 @@ android_test { "androidx.test.core", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], resource_dirs: ["test/res"], certificate: "platform", diff --git a/packages/overlays/tests/Android.bp b/packages/overlays/tests/Android.bp index b781602399a3..0244c0fe0533 100644 --- a/packages/overlays/tests/Android.bp +++ b/packages/overlays/tests/Android.bp @@ -34,7 +34,7 @@ android_test { "androidx.test.rules", "androidx.test.espresso.core", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], dxflags: ["--multi-dex"], } diff --git a/services/core/Android.bp b/services/core/Android.bp index 4e412bbe67df..9ac30f334d0b 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -180,6 +180,7 @@ java_library_static { "android.hidl.manager-V1.2-java", "cbor-java", "icu4j_calendar_astronomer", + "android.security.aaid_aidl-java", "netd-client", "overlayable_policy_aidl-java", "SurfaceFlingerProperties", diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java index 46f486d875b6..f572845dc214 100644 --- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java +++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java @@ -311,7 +311,7 @@ public class BiometricDeferredQueue { @Nullable private static synchronized IGateKeeperService getGatekeeperService() { - final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE); + final IBinder service = ServiceManager.waitForService(Context.GATEKEEPER_SERVICE); if (service == null) { Slog.e(TAG, "Unable to acquire GateKeeperService"); return null; diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 0a02c49192b9..ff959decac33 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -115,7 +115,6 @@ import android.system.keystore2.Domain; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.EventLog; import android.util.Log; import android.util.LongSparseArray; import android.util.Slog; @@ -861,15 +860,11 @@ public class LockSettingsService extends ILockSettings.Stub { @Override // binder interface public void systemReady() { - if (mContext.checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) { - EventLog.writeEvent(0x534e4554, "28251513", getCallingUid(), ""); // SafetyNet - } checkWritePermission(); mHasSecureLockScreen = mContext.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN); migrateOldData(); - getGateKeeperService(); getAuthSecretHal(); mDeviceProvisionedObserver.onSystemReady(); @@ -1109,9 +1104,6 @@ public class LockSettingsService extends ILockSettings.Stub { } private final void checkPasswordHavePermission() { - if (mContext.checkCallingOrSelfPermission(PERMISSION) != PERMISSION_GRANTED) { - EventLog.writeEvent(0x534e4554, "28251513", getCallingUid(), ""); // SafetyNet - } mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsHave"); } @@ -1676,6 +1668,7 @@ public class LockSettingsService extends ILockSettings.Stub { + PERMISSION); } } + credential.validateBasicRequirements(); final long identity = Binder.clearCallingIdentity(); try { @@ -2239,17 +2232,6 @@ public class LockSettingsService extends ILockSettings.Stub { // credential has matched mBiometricDeferredQueue.addPendingLockoutResetForUser(userId, authResult.syntheticPassword.deriveGkPassword()); - - // perform verifyChallenge with synthetic password which generates the real GK auth - // token and response for the current user - response = mSpManager.verifyChallenge(getGateKeeperService(), - authResult.syntheticPassword, 0L /* challenge */, userId); - if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { - // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't - // match the recorded GK password handle. - Slog.wtf(TAG, "verifyChallenge with SP failed."); - return VerifyCredentialResponse.ERROR; - } } } if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { @@ -2645,7 +2627,7 @@ public class LockSettingsService extends ILockSettings.Stub { return mGateKeeperService; } - final IBinder service = ServiceManager.getService(Context.GATEKEEPER_SERVICE); + final IBinder service = ServiceManager.waitForService(Context.GATEKEEPER_SERVICE); if (service != null) { try { service.linkToDeath(new GateKeeperDiedRecipient(), 0); @@ -2883,7 +2865,7 @@ public class LockSettingsService extends ILockSettings.Stub { * * Also maintains the invariants described in {@link SyntheticPasswordManager} by * setting/clearing the protection (by the SP) on the user's auth-bound Keystore keys when the - * LSKF is added/removed, respectively. If the new LSKF is nonempty, then the Gatekeeper auth + * LSKF is added/removed, respectively. If an LSKF is being added, then the Gatekeeper auth * token is also refreshed. */ @GuardedBy("mSpManager") @@ -2900,9 +2882,7 @@ public class LockSettingsService extends ILockSettings.Stub { // not needed by synchronizeUnifiedWorkChallengeForProfiles() profilePasswords = null; - if (mSpManager.hasSidForUser(userId)) { - mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId); - } else { + if (!mSpManager.hasSidForUser(userId)) { mSpManager.newSidForUser(getGateKeeperService(), sp, userId); mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId); setKeystorePassword(sp.deriveKeyStorePassword(), userId); @@ -3118,6 +3098,7 @@ public class LockSettingsService extends ILockSettings.Stub { private boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle, byte[] token, int userId) { boolean result; + credential.validateBasicRequirements(); synchronized (mSpManager) { if (!mSpManager.hasEscrowData(userId)) { throw new SecurityException("Escrow token is disabled on the current user"); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java index f107d0bf9932..df95c69e7271 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java @@ -16,8 +16,6 @@ package com.android.server.locksettings; -import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; -import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; import android.app.ActivityManager; @@ -313,16 +311,8 @@ class LockSettingsShellCommand extends ShellCommand { mLockPatternUtils.getRequestedPasswordMetrics(mCurrentUserId); final int requiredComplexity = mLockPatternUtils.getRequestedPasswordComplexity(mCurrentUserId); - final List<PasswordValidationError> errors; - if (credential.isPassword() || credential.isPin()) { - errors = PasswordMetrics.validatePassword(requiredMetrics, requiredComplexity, - credential.isPin(), credential.getCredential()); - } else { - PasswordMetrics metrics = new PasswordMetrics( - credential.isPattern() ? CREDENTIAL_TYPE_PATTERN : CREDENTIAL_TYPE_NONE); - errors = PasswordMetrics.validatePasswordMetrics( - requiredMetrics, requiredComplexity, metrics); - } + final List<PasswordValidationError> errors = + PasswordMetrics.validateCredential(requiredMetrics, requiredComplexity, credential); if (!errors.isEmpty()) { getOutPrintWriter().println( "New credential doesn't satisfy admin policies: " + errors.get(0)); diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java index e8fd6f88359c..7fec377b3e9e 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java @@ -1602,7 +1602,7 @@ class SyntheticPasswordManager { /** Destroy all weak token-based SP protectors for the given user. */ public void destroyAllWeakTokenBasedProtectors(int userId) { List<Long> protectorIds = - mStorage.listSyntheticPasswordProtectorsForUser(SECDISCARDABLE_NAME, userId); + mStorage.listSyntheticPasswordProtectorsForUser(SP_BLOB_NAME, userId); for (long protectorId : protectorIds) { SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME, protectorId, userId)); diff --git a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java index c908acdd1d6c..d5bc91278aa8 100644 --- a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java +++ b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java @@ -24,9 +24,10 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; -import android.security.keymaster.IKeyAttestationApplicationIdProvider; -import android.security.keymaster.KeyAttestationApplicationId; -import android.security.keymaster.KeyAttestationPackageInfo; +import android.security.keystore.IKeyAttestationApplicationIdProvider; +import android.security.keystore.KeyAttestationApplicationId; +import android.security.keystore.KeyAttestationPackageInfo; +import android.security.keystore.Signature; /** * @hide @@ -64,14 +65,25 @@ public class KeyAttestationApplicationIdProviderService for (int i = 0; i < packageNames.length; ++i) { PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageNames[i], PackageManager.GET_SIGNATURES, userId); - keyAttestationPackageInfos[i] = new KeyAttestationPackageInfo(packageNames[i], - packageInfo.getLongVersionCode(), packageInfo.signatures); + KeyAttestationPackageInfo pInfo = new KeyAttestationPackageInfo(); + pInfo.packageName = new String(packageNames[i]); + pInfo.versionCode = packageInfo.getLongVersionCode(); + pInfo.signatures = new Signature[packageInfo.signatures.length]; + for (int index = 0; index < packageInfo.signatures.length; index++) { + Signature sign = new Signature(); + sign.data = packageInfo.signatures[index].toByteArray(); + pInfo.signatures[index] = sign; + } + + keyAttestationPackageInfos[i] = pInfo; } } catch (NameNotFoundException nnfe) { throw new RemoteException(nnfe.getMessage()); } finally { Binder.restoreCallingIdentity(token); } - return new KeyAttestationApplicationId(keyAttestationPackageInfos); + KeyAttestationApplicationId attestAppId = new KeyAttestationApplicationId(); + attestAppId.packageInfos = keyAttestationPackageInfos; + return attestAppId; } } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index e4146637f72f..635e11be3a16 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -1255,7 +1255,7 @@ public class TrustManagerService extends SystemService { for (int i = 0; i < mActiveAgents.size(); i++) { AgentInfo info = mActiveAgents.valueAt(i); if (info.userId == userId) { - if (info.agent.isTrustableOrWaitingForDowngrade()) { + if (info.agent.isManagingTrust()) { return true; } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 34170fa4c8b5..ab218a671823 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -5127,8 +5127,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean deviceWideOnly) { final CallerIdentity caller = getCallerIdentity(); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userHandle) - && (isSystemUid(caller) || hasCallingOrSelfPermission( - permission.SET_INITIAL_LOCK))); + && (isSystemUid(caller) + // Accept any permission that ILockSettings#setLockCredential() accepts. + || hasCallingOrSelfPermission(permission.SET_INITIAL_LOCK) + || hasCallingOrSelfPermission(permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS) + || hasCallingOrSelfPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE))); return getPasswordMinimumMetricsUnchecked(userHandle, deviceWideOnly); } @@ -5725,20 +5728,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int callingUid = caller.getUid(); final int userHandle = UserHandle.getUserId(callingUid); final boolean isPin = PasswordMetrics.isNumericOnly(password); + final LockscreenCredential newCredential; + if (isPin) { + newCredential = LockscreenCredential.createPin(password); + } else { + newCredential = LockscreenCredential.createPasswordOrNone(password); + } synchronized (getLockObject()) { final PasswordMetrics minMetrics = getPasswordMinimumMetricsUnchecked(userHandle); - final List<PasswordValidationError> validationErrors; final int complexity = getAggregatedPasswordComplexityLocked(userHandle); - // TODO: Consider changing validation API to take LockscreenCredential. - if (password.isEmpty()) { - validationErrors = PasswordMetrics.validatePasswordMetrics( - minMetrics, complexity, new PasswordMetrics(CREDENTIAL_TYPE_NONE)); - } else { - // TODO(b/120484642): remove getBytes() below - validationErrors = PasswordMetrics.validatePassword( - minMetrics, complexity, isPin, password.getBytes()); - } - + final List<PasswordValidationError> validationErrors = + PasswordMetrics.validateCredential(minMetrics, complexity, newCredential); if (!validationErrors.isEmpty()) { Slogf.w(LOG_TAG, "Failed to reset password due to constraint violation: %s", validationErrors.get(0)); @@ -5762,12 +5762,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Don't do this with the lock held, because it is going to call // back in to the service. final long ident = mInjector.binderClearCallingIdentity(); - final LockscreenCredential newCredential; - if (isPin) { - newCredential = LockscreenCredential.createPin(password); - } else { - newCredential = LockscreenCredential.createPasswordOrNone(password); - } try { if (tokenHandle == 0 || token == null) { if (!mLockPatternUtils.setLockCredential(newCredential, diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp index 506e1561e8d7..66ee696250c9 100644 --- a/services/robotests/backup/Android.bp +++ b/services/robotests/backup/Android.bp @@ -58,7 +58,7 @@ android_robolectric_test { "mockito-robolectric-prebuilt", "platform-test-annotations", "testng", - "truth-prebuilt", + "truth", ], instrumentation_for: "BackupFrameworksServicesLib", diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp index 07ddda39649a..528fda294050 100644 --- a/services/tests/InputMethodSystemServerTests/Android.bp +++ b/services/tests/InputMethodSystemServerTests/Android.bp @@ -43,7 +43,7 @@ android_test { "services.core", "servicestests-core-utils", "servicestests-utils-mockito-extended", - "truth-prebuilt", + "truth", ], libs: [ @@ -90,7 +90,7 @@ android_test { "services.core", "servicestests-core-utils", "servicestests-utils-mockito-extended", - "truth-prebuilt", + "truth", "SimpleImeTestingLib", "SimpleImeImsLib", ], diff --git a/services/tests/PackageManager/packageinstaller/Android.bp b/services/tests/PackageManager/packageinstaller/Android.bp index 35d754b4adc5..e8fce8e72601 100644 --- a/services/tests/PackageManager/packageinstaller/Android.bp +++ b/services/tests/PackageManager/packageinstaller/Android.bp @@ -32,7 +32,7 @@ android_test { "androidx.test.runner", "junit", "kotlin-test", - "truth-prebuilt", + "truth", ], platform_apis: true, test_suites: ["device-tests"], diff --git a/services/tests/PackageManagerComponentOverrideTests/Android.bp b/services/tests/PackageManagerComponentOverrideTests/Android.bp index 19fdf6056453..81fd90d9e6a9 100644 --- a/services/tests/PackageManagerComponentOverrideTests/Android.bp +++ b/services/tests/PackageManagerComponentOverrideTests/Android.bp @@ -29,7 +29,7 @@ package { android_test { name: "PackageManagerComponentOverrideTests", srcs: [ - "src/**/*.kt" + "src/**/*.kt", ], static_libs: [ "androidx.test.runner", @@ -37,7 +37,7 @@ android_test { "services.core", "servicestests-utils-mockito-extended", "testng", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows - "truth-prebuilt", + "truth", ], jni_libs: [ diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp index 9c4e6fd66ceb..ad7af44d4089 100644 --- a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp +++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp @@ -29,7 +29,7 @@ android_test { static_libs: [ "compatibility-device-util-axt", "androidx.test.runner", - "truth-prebuilt", + "truth", "Harrier", ], platform_apis: true, diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp index c7a71eeb969c..42a8f9b73a77 100644 --- a/services/tests/PackageManagerServiceTests/host/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/Android.bp @@ -30,7 +30,7 @@ java_test_host { libs: [ "tradefed", "junit", - "truth-prebuilt", + "truth", ], static_libs: [ "ApexInstallHelper", diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp index 462c5801e952..cea9c599317d 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp @@ -38,6 +38,6 @@ android_test_helper_app { "junit-params", "androidx.test.ext.junit", "androidx.test.rules", - "truth-prebuilt", + "truth", ], } diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp index 57184748d074..ed5f2b51b9ed 100644 --- a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp +++ b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp @@ -28,6 +28,6 @@ android_test_helper_app { "androidx.test.runner", "junit", "kotlin-test", - "truth-prebuilt", + "truth", ], } diff --git a/services/tests/PackageManagerServiceTests/server/Android.bp b/services/tests/PackageManagerServiceTests/server/Android.bp index 3176f0673b65..47d242235c47 100644 --- a/services/tests/PackageManagerServiceTests/server/Android.bp +++ b/services/tests/PackageManagerServiceTests/server/Android.bp @@ -41,7 +41,7 @@ android_test { "mockito-target-minus-junit4", "platform-test-annotations", "ShortcutManagerTestUtils", - "truth-prebuilt", + "truth", "testables", "ub-uiautomator", "platformprotosnano", @@ -52,7 +52,7 @@ android_test { "servicestests-utils", "service-permission.impl", "testng", - "truth-prebuilt", + "truth", "junit", "junit-params", "platform-compat-test-rules", diff --git a/services/tests/PackageManagerServiceTests/unit/Android.bp b/services/tests/PackageManagerServiceTests/unit/Android.bp index 9b3b8c35736c..8505983894a8 100644 --- a/services/tests/PackageManagerServiceTests/unit/Android.bp +++ b/services/tests/PackageManagerServiceTests/unit/Android.bp @@ -37,7 +37,7 @@ android_test { "services.core", "servicestests-utils", "servicestests-core-utils", - "truth-prebuilt", + "truth", ], jni_libs: [ "libdexmakerjvmtiagent", diff --git a/services/tests/RemoteProvisioningServiceTests/Android.bp b/services/tests/RemoteProvisioningServiceTests/Android.bp index fc2c0857146b..19c913620760 100644 --- a/services/tests/RemoteProvisioningServiceTests/Android.bp +++ b/services/tests/RemoteProvisioningServiceTests/Android.bp @@ -30,8 +30,8 @@ android_test { "mockito-target", "service-rkp.impl", "services.core", - "truth-prebuilt", - "truth-java8-extension-jar", + "truth", + "truth-java8-extension", ], test_suites: [ "device-tests", diff --git a/services/tests/apexsystemservices/Android.bp b/services/tests/apexsystemservices/Android.bp index e724e804f4e7..9dacfeabf1ef 100644 --- a/services/tests/apexsystemservices/Android.bp +++ b/services/tests/apexsystemservices/Android.bp @@ -34,7 +34,7 @@ java_test_host { "compatibility-host-util", "cts-install-lib-host", "frameworks-base-hostutils", - "truth-prebuilt", + "truth", "modules-utils-build-testing", ], test_suites: [ diff --git a/services/tests/inprocesstests/Android.bp b/services/tests/inprocesstests/Android.bp index 7c237ac6befb..086e84b86aca 100644 --- a/services/tests/inprocesstests/Android.bp +++ b/services/tests/inprocesstests/Android.bp @@ -14,7 +14,7 @@ android_test { "androidx.test.core", "androidx.test.rules", "services.core", - "truth-prebuilt", + "truth", "platform-test-annotations", ], test_suites: ["general-tests"], diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp index 101498aef183..f56f290643c6 100644 --- a/services/tests/mockingservicestests/Android.bp +++ b/services/tests/mockingservicestests/Android.bp @@ -67,7 +67,7 @@ android_test { "servicestests-core-utils", "servicestests-utils-mockito-extended", "testables", - "truth-prebuilt", + "truth", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows "testng", "compatibility-device-util-axt", diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index 16e1b457ad96..f770f8c4571e 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -48,7 +48,7 @@ android_test { "mockito-target-minus-junit4", "platform-test-annotations", "ShortcutManagerTestUtils", - "truth-prebuilt", + "truth", "testables", "ub-uiautomator", "platformprotosnano", @@ -59,7 +59,7 @@ android_test { // TODO: remove once Android migrates to JUnit 4.12, // which provides assertThrows "testng", - "truth-prebuilt", + "truth", "junit", "junit-params", "ActivityContext", diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 99a3b808e082..cc07ccefa119 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -46,7 +46,6 @@ import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_OPEN; import static android.app.admin.DevicePolicyManager.WIFI_SECURITY_PERSONAL; import static android.app.admin.DevicePolicyManager.WIPE_EUICC; -import static android.app.admin.PasswordMetrics.computeForPasswordOrPin; import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; import static android.location.LocationManager.FUSED_PROVIDER; import static android.location.LocationManager.GPS_PROVIDER; @@ -5479,8 +5478,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { reset(mContext.spiedContext); - PasswordMetrics passwordMetricsNoSymbols = computeForPasswordOrPin( - "abcdXYZ5".getBytes(), /* isPin */ false); + PasswordMetrics passwordMetricsNoSymbols = metricsForPassword("abcdXYZ5"); setActivePasswordState(passwordMetricsNoSymbols); assertThat(dpm.isActivePasswordSufficient()).isTrue(); @@ -5507,8 +5505,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { reset(mContext.spiedContext); assertThat(dpm.isActivePasswordSufficient()).isFalse(); - PasswordMetrics passwordMetricsWithSymbols = computeForPasswordOrPin( - "abcd.XY5".getBytes(), /* isPin */ false); + PasswordMetrics passwordMetricsWithSymbols = metricsForPassword("abcd.XY5"); setActivePasswordState(passwordMetricsWithSymbols); assertThat(dpm.isActivePasswordSufficient()).isTrue(); @@ -5564,7 +5561,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) - .thenReturn(computeForPasswordOrPin("184342".getBytes(), /* isPin */ true)); + .thenReturn(metricsForPin("184342")); // Numeric password is compliant with current requirement (QUALITY_NUMERIC set explicitly // on the parent admin) @@ -5685,7 +5682,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a work challenge and verify profile.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) - .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); + .thenReturn(metricsForPassword("abcdXYZ5")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -5710,7 +5707,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a work challenge and verify profile.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) - .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); + .thenReturn(metricsForPin("5156")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -5735,7 +5732,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) - .thenReturn(computeForPasswordOrPin("acbdXYZ5".getBytes(), /* isPin */ false)); + .thenReturn(metricsForPassword("acbdXYZ5")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -5758,7 +5755,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) - .thenReturn(computeForPasswordOrPin("1234".getBytes(), /* isPin */ true)); + .thenReturn(metricsForPin("1234")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -5783,7 +5780,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) - .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); + .thenReturn(metricsForPassword("abcdXYZ5")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -5806,7 +5803,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) - .thenReturn(computeForPasswordOrPin("51567548".getBytes(), /* isPin */ true)); + .thenReturn(metricsForPin("51567548")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -5831,7 +5828,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) - .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); + .thenReturn(metricsForPassword("abcdXYZ5")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -5854,7 +5851,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) - .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); + .thenReturn(metricsForPin("5156")); assertThat(dpm.isActivePasswordSufficient()).isTrue(); assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); } @@ -6909,7 +6906,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { .thenReturn(CALLER_USER_HANDLE); when(getServices().lockSettingsInternal .getUserPasswordMetrics(CALLER_USER_HANDLE)) - .thenReturn(computeForPasswordOrPin("asdf".getBytes(), /* isPin */ false)); + .thenReturn(metricsForPassword("asdf")); assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_MEDIUM); } @@ -6929,10 +6926,10 @@ public class DevicePolicyManagerTest extends DpmTestBase { when(getServices().lockSettingsInternal .getUserPasswordMetrics(CALLER_USER_HANDLE)) - .thenReturn(computeForPasswordOrPin("asdf".getBytes(), /* isPin */ false)); + .thenReturn(metricsForPassword("asdf")); when(getServices().lockSettingsInternal .getUserPasswordMetrics(parentUser.id)) - .thenReturn(computeForPasswordOrPin("parentUser".getBytes(), /* isPin */ false)); + .thenReturn(metricsForPassword("parentUser")); assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH); } @@ -7654,15 +7651,13 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE); reset(mContext.spiedContext); - PasswordMetrics passwordMetricsNoSymbols = computeForPasswordOrPin( - "1234".getBytes(), /* isPin */ true); + PasswordMetrics passwordMetricsNoSymbols = metricsForPin("1234"); setActivePasswordState(passwordMetricsNoSymbols); assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_LOW); assertThat(dpm.isActivePasswordSufficient()).isFalse(); reset(mContext.spiedContext); - passwordMetricsNoSymbols = computeForPasswordOrPin( - "84125312943a".getBytes(), /* isPin */ false); + passwordMetricsNoSymbols = metricsForPassword("84125312943a"); setActivePasswordState(passwordMetricsNoSymbols); assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH); // using isActivePasswordSufficient @@ -8838,4 +8833,12 @@ public class DevicePolicyManagerTest extends DpmTestBase { assumeTrue("device doesn't support deprecated password APIs", isDeprecatedPasswordApisSupported()); } + + private static PasswordMetrics metricsForPassword(String password) { + return PasswordMetrics.computeForCredential(LockscreenCredential.createPassword(password)); + } + + private static PasswordMetrics metricsForPin(String pin) { + return PasswordMetrics.computeForCredential(LockscreenCredential.createPin(pin)); + } } diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index d8e4fdae5a34..7189383d180e 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -285,6 +285,7 @@ public final class DeviceStateManagerServiceTest { assertEquals(info.currentState, DEFAULT_DEVICE_STATE.getIdentifier()); } + @FlakyTest(bugId = 297949293) @Test public void getDeviceStateInfo_baseStateAndCommittedStateNotSet() throws RemoteException { // Create a provider and a service without an initial base state. diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 60a033fde427..5a62d92e8e12 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -77,6 +77,26 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { testSetCredentialFailsWithoutLockScreen(PRIMARY_USER_ID, newPassword("password")); } + @Test(expected = IllegalArgumentException.class) + public void testSetTooShortPatternFails() throws RemoteException { + mService.setLockCredential(newPattern("123"), nonePassword(), PRIMARY_USER_ID); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetTooShortPinFails() throws RemoteException { + mService.setLockCredential(newPin("123"), nonePassword(), PRIMARY_USER_ID); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetTooShortPassword() throws RemoteException { + mService.setLockCredential(newPassword("123"), nonePassword(), PRIMARY_USER_ID); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetPasswordWithInvalidChars() throws RemoteException { + mService.setLockCredential(newPassword("§µ¿¶¥£"), nonePassword(), PRIMARY_USER_ID); + } + @Test public void testSetPatternPrimaryUser() throws RemoteException { setAndVerifyCredential(PRIMARY_USER_ID, newPattern("123456789")); @@ -94,7 +114,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { @Test public void testChangePatternPrimaryUser() throws RemoteException { - testChangeCredential(PRIMARY_USER_ID, newPassword("!£$%^&*(())"), newPattern("1596321")); + testChangeCredential(PRIMARY_USER_ID, newPassword("password"), newPattern("1596321")); } @Test @@ -185,7 +205,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID)); assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID)); - setCredential(PRIMARY_USER_ID, newPassword("pwd"), primaryPassword); + setCredential(PRIMARY_USER_ID, newPassword("password"), primaryPassword); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential( profilePassword, MANAGED_PROFILE_USER_ID, 0 /* flags */) .getResponseCode()); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java index ce0347dbe4ac..dee77806e4f3 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java @@ -215,12 +215,12 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { @Test public void testChangeCredentialKeepsAuthSecret() throws RemoteException { LockscreenCredential password = newPassword("password"); - LockscreenCredential badPassword = newPassword("new"); + LockscreenCredential newPassword = newPassword("newPassword"); initSpAndSetCredential(PRIMARY_USER_ID, password); - mService.setLockCredential(badPassword, password, PRIMARY_USER_ID); + mService.setLockCredential(newPassword, password, PRIMARY_USER_ID); assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential( - badPassword, PRIMARY_USER_ID, 0 /* flags */).getResponseCode()); + newPassword, PRIMARY_USER_ID, 0 /* flags */).getResponseCode()); // Check the same secret was passed each time ArgumentCaptor<byte[]> secret = ArgumentCaptor.forClass(byte[].class); diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp index 94f2d2e752f3..b1eeba56653b 100644 --- a/services/tests/uiservicestests/Android.bp +++ b/services/tests/uiservicestests/Android.bp @@ -36,7 +36,7 @@ android_test { "hamcrest-library", "servicestests-utils", "testables", - "truth-prebuilt", + "truth", // TODO: remove once Android migrates to JUnit 4.12, // which provides assertThrows "testng", diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp index e704ebf32270..744cb63f72b3 100644 --- a/services/tests/voiceinteractiontests/Android.bp +++ b/services/tests/voiceinteractiontests/Android.bp @@ -43,7 +43,7 @@ android_test { "services.soundtrigger", "servicestests-core-utils", "servicestests-utils-mockito-extended", - "truth-prebuilt", + "truth", ], libs: [ diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java index 6a1674b7df8e..63b8e1710b50 100644 --- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java +++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareLoggingLatencyTest.java @@ -38,13 +38,16 @@ import android.os.BatteryStatsInternal; import android.os.Process; import android.os.RemoteException; +import androidx.test.filters.FlakyTest; import androidx.test.platform.app.InstrumentationRegistry; import com.android.internal.util.FakeLatencyTracker; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.Timeout; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import org.mockito.ArgumentCaptor; @@ -52,8 +55,12 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; @RunWith(JUnit4.class) +@FlakyTest(bugId = 275746222) public class SoundTriggerMiddlewareLoggingLatencyTest { + @Rule + public Timeout mGlobalTimeout = Timeout.seconds(30); + private FakeLatencyTracker mLatencyTracker; @Mock private BatteryStatsInternal mBatteryStatsInternal; diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp index e537197584cb..0997d15acfa7 100644 --- a/services/tests/wmtests/Android.bp +++ b/services/tests/wmtests/Android.bp @@ -55,7 +55,7 @@ android_test { "platform-test-annotations", "servicestests-utils", "testng", - "truth-prebuilt", + "truth", "testables", "ub-uiautomator", "hamcrest-library", diff --git a/tests/BatteryStatsPerfTest/Android.bp b/tests/BatteryStatsPerfTest/Android.bp index 5233a5b8654e..c2a70151fa13 100644 --- a/tests/BatteryStatsPerfTest/Android.bp +++ b/tests/BatteryStatsPerfTest/Android.bp @@ -27,7 +27,7 @@ android_test { static_libs: [ "androidx.test.rules", "apct-perftests-utils", - "truth-prebuilt", + "truth", ], platform_apis: true, certificate: "platform", diff --git a/tests/BinaryTransparencyHostTest/Android.bp b/tests/BinaryTransparencyHostTest/Android.bp index dc6bdff6716c..0dbc022589fc 100644 --- a/tests/BinaryTransparencyHostTest/Android.bp +++ b/tests/BinaryTransparencyHostTest/Android.bp @@ -30,7 +30,7 @@ java_test_host { "compatibility-host-util", ], static_libs: [ - "truth-prebuilt", + "truth", ], data: [ ":BinaryTransparencyTestApp", diff --git a/tests/BlobStoreTestUtils/Android.bp b/tests/BlobStoreTestUtils/Android.bp index c4faf7f4fb11..1fb73e2c0967 100644 --- a/tests/BlobStoreTestUtils/Android.bp +++ b/tests/BlobStoreTestUtils/Android.bp @@ -22,12 +22,12 @@ package { } java_library { - name: "BlobStoreTestUtils", - srcs: ["src/**/*.java"], - static_libs: [ - "truth-prebuilt", - "androidx.test.uiautomator_uiautomator", - "androidx.test.ext.junit", - ], - sdk_version: "test_current", + name: "BlobStoreTestUtils", + srcs: ["src/**/*.java"], + static_libs: [ + "truth", + "androidx.test.uiautomator_uiautomator", + "androidx.test.ext.junit", + ], + sdk_version: "test_current", } diff --git a/tests/ChoreographerTests/Android.bp b/tests/ChoreographerTests/Android.bp index ca3026705c63..5d49120ee702 100644 --- a/tests/ChoreographerTests/Android.bp +++ b/tests/ChoreographerTests/Android.bp @@ -34,7 +34,7 @@ android_test { "androidx.test.rules", "compatibility-device-util-axt", "com.google.android.material_material", - "truth-prebuilt", + "truth", ], jni_libs: [ "libchoreographertests_jni", diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.bp b/tests/DynamicCodeLoggerIntegrationTests/Android.bp index 448d46fe5e4e..3f2c80831565 100644 --- a/tests/DynamicCodeLoggerIntegrationTests/Android.bp +++ b/tests/DynamicCodeLoggerIntegrationTests/Android.bp @@ -47,7 +47,7 @@ android_test { static_libs: [ "androidx.test.rules", - "truth-prebuilt", + "truth", ], compile_multilib: "both", diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp index 4ba538ed9d45..ba5b7952caee 100644 --- a/tests/FlickerTests/Android.bp +++ b/tests/FlickerTests/Android.bp @@ -44,7 +44,7 @@ android_test { "flickerlib", "flickerlib-apphelpers", "flickerlib-helpers", - "truth-prebuilt", + "truth", "launcher-helper-lib", "launcher-aosp-tapl", "platform-test-annotations", @@ -71,7 +71,7 @@ java_library { static_libs: [ "flickerlib", "flickerlib-helpers", - "truth-prebuilt", + "truth", "app-helpers-core", ], } @@ -90,7 +90,7 @@ java_library { "flickerlib", "flickerlib-apphelpers", "flickerlib-helpers", - "truth-prebuilt", + "truth", "app-helpers-core", "wm-flicker-window-extensions", ], diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp index 4fa6fbe1d4e1..292fbcb0031e 100644 --- a/tests/Input/Android.bp +++ b/tests/Input/Android.bp @@ -24,7 +24,7 @@ android_test { "mockito-target-minus-junit4", "services.core.unboosted", "testables", - "truth-prebuilt", + "truth", "androidx.test.uiautomator_uiautomator", ], test_suites: ["device-tests"], diff --git a/tests/InputMethodStressTest/Android.bp b/tests/InputMethodStressTest/Android.bp index 84845c69fb27..58ceb3f3edf4 100644 --- a/tests/InputMethodStressTest/Android.bp +++ b/tests/InputMethodStressTest/Android.bp @@ -26,7 +26,7 @@ android_test { "compatibility-device-util-axt", "platform-test-annotations", "platform-test-rules", - "truth-prebuilt", + "truth", ], test_suites: [ "general-tests", diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp index ef45864dd93b..ddec8fa1d70a 100644 --- a/tests/Internal/Android.bp +++ b/tests/Internal/Android.bp @@ -19,7 +19,7 @@ android_test { "junit", "androidx.test.rules", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", "platform-test-annotations", ], java_resource_dirs: ["res"], diff --git a/tests/LocalizationTest/Android.bp b/tests/LocalizationTest/Android.bp index 4e0b0a89d972..909ca5972552 100644 --- a/tests/LocalizationTest/Android.bp +++ b/tests/LocalizationTest/Android.bp @@ -34,7 +34,7 @@ android_test { "androidx.test.ext.junit", "androidx.test.rules", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", ], jni_libs: [ // For mockito extended diff --git a/tests/MidiTests/Android.bp b/tests/MidiTests/Android.bp index 254770d21818..fcacab3fb13c 100644 --- a/tests/MidiTests/Android.bp +++ b/tests/MidiTests/Android.bp @@ -31,7 +31,7 @@ android_test { "mockito-target-inline-minus-junit4", "platform-test-annotations", "services.midi", - "truth-prebuilt", + "truth", ], jni_libs: ["libdexmakerjvmtiagent"], certificate: "platform", diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp index 1e1dc8458560..e0e6c4c43b16 100644 --- a/tests/PackageWatchdog/Android.bp +++ b/tests/PackageWatchdog/Android.bp @@ -32,7 +32,7 @@ android_test { "androidx.test.rules", "services.core", "services.net", - "truth-prebuilt", + "truth", ], libs: ["android.test.runner"], jni_libs: [ diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp index f0f9c4bdd721..fd992cf415cf 100644 --- a/tests/PlatformCompatGating/Android.bp +++ b/tests/PlatformCompatGating/Android.bp @@ -38,7 +38,7 @@ android_test { "androidx.test.ext.junit", "mockito-target-minus-junit4", "testng", - "truth-prebuilt", + "truth", "platform-compat-test-rules", ], } diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp index 5f91f9d0e505..f6a41c2f44b7 100644 --- a/tests/PlatformCompatGating/test-rules/Android.bp +++ b/tests/PlatformCompatGating/test-rules/Android.bp @@ -29,7 +29,7 @@ java_library { static_libs: [ "junit", "androidx.test.core", - "truth-prebuilt", - "core-compat-test-rules" + "truth", + "core-compat-test-rules", ], } diff --git a/tests/SurfaceViewBufferTests/Android.bp b/tests/SurfaceViewBufferTests/Android.bp index dc75f00e7cdc..d34f780fd40c 100644 --- a/tests/SurfaceViewBufferTests/Android.bp +++ b/tests/SurfaceViewBufferTests/Android.bp @@ -23,7 +23,10 @@ package { android_test { name: "SurfaceViewBufferTests", - srcs: ["**/*.java","**/*.kt"], + srcs: [ + "**/*.java", + "**/*.kt", + ], manifest: "AndroidManifest.xml", test_config: "AndroidTest.xml", platform_apis: true, @@ -41,7 +44,7 @@ android_test { "kotlin-stdlib", "kotlinx-coroutines-android", "flickerlib", - "truth-prebuilt", + "truth", "cts-wm-util", "CtsSurfaceValidatorLib", ], @@ -60,7 +63,7 @@ cc_library_shared { "libandroid", ], include_dirs: [ - "system/core/include" + "system/core/include", ], stl: "libc++_static", cflags: [ diff --git a/tests/TaskOrganizerTest/Android.bp b/tests/TaskOrganizerTest/Android.bp index 9b72d359aae6..2a92c42b8ae0 100644 --- a/tests/TaskOrganizerTest/Android.bp +++ b/tests/TaskOrganizerTest/Android.bp @@ -25,7 +25,10 @@ package { android_test { name: "TaskOrganizerTest", - srcs: ["**/*.java","**/*.kt"], + srcs: [ + "**/*.java", + "**/*.kt", + ], manifest: "AndroidManifest.xml", test_config: "AndroidTest.xml", platform_apis: true, @@ -39,6 +42,6 @@ android_test { "kotlin-stdlib", "kotlinx-coroutines-android", "flickerlib", - "truth-prebuilt", + "truth", ], -}
\ No newline at end of file +} diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp index 81ec265c2c29..b968e5d81148 100644 --- a/tests/TelephonyCommonTests/Android.bp +++ b/tests/TelephonyCommonTests/Android.bp @@ -32,11 +32,11 @@ android_test { static_libs: [ "mockito-target-extended", "androidx.test.rules", - "truth-prebuilt", + "truth", "platform-test-annotations", "androidx.core_core", "androidx.fragment_fragment", - "androidx.test.ext.junit" + "androidx.test.ext.junit", ], jni_libs: ["libdexmakerjvmtiagent"], diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp index c216bced81f0..4e75a1d02a41 100644 --- a/tests/TrustTests/Android.bp +++ b/tests/TrustTests/Android.bp @@ -28,7 +28,7 @@ android_test { "flag-junit", "mockito-target-minus-junit4", "servicestests-utils", - "truth-prebuilt", + "truth", ], libs: [ "android.test.runner", diff --git a/tests/TrustTests/src/android/trust/test/CanUnlockWithActiveUnlockTest.kt b/tests/TrustTests/src/android/trust/test/IsActiveUnlockRunningTest.kt index 7b68a829e23b..7b68a829e23b 100644 --- a/tests/TrustTests/src/android/trust/test/CanUnlockWithActiveUnlockTest.kt +++ b/tests/TrustTests/src/android/trust/test/IsActiveUnlockRunningTest.kt diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp index 9bfcc18ee301..ddb3649a8320 100644 --- a/tests/UpdatableSystemFontTest/Android.bp +++ b/tests/UpdatableSystemFontTest/Android.bp @@ -30,7 +30,7 @@ android_test { "androidx.test.uiautomator_uiautomator", "compatibility-device-util-axt", "platform-test-annotations", - "truth-prebuilt", + "truth", ], test_suites: [ "general-tests", diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp index 97fbf5b32035..c02d8e96abb0 100644 --- a/tests/UsbManagerTests/Android.bp +++ b/tests/UsbManagerTests/Android.bp @@ -31,7 +31,7 @@ android_test { "androidx.test.rules", "mockito-target-inline-minus-junit4", "platform-test-annotations", - "truth-prebuilt", + "truth", "UsbManagerTestLib", ], jni_libs: ["libdexmakerjvmtiagent"], diff --git a/tests/UsbManagerTests/lib/Android.bp b/tests/UsbManagerTests/lib/Android.bp index 994484cd63bf..4e5a70fef0ca 100644 --- a/tests/UsbManagerTests/lib/Android.bp +++ b/tests/UsbManagerTests/lib/Android.bp @@ -34,7 +34,7 @@ android_library { "services.core", "services.net", "services.usb", - "truth-prebuilt", + "truth", "androidx.core_core", ], libs: [ diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp index 9328b67795cb..1c2f746da5bd 100644 --- a/tests/UsbTests/Android.bp +++ b/tests/UsbTests/Android.bp @@ -34,7 +34,7 @@ android_test { "services.core", "services.net", "services.usb", - "truth-prebuilt", + "truth", "UsbManagerTestLib", ], jni_libs: ["libdexmakerjvmtiagent"], diff --git a/tests/componentalias/Android.bp b/tests/componentalias/Android.bp index 7af76e1144f8..bbd46c5fddfe 100644 --- a/tests/componentalias/Android.bp +++ b/tests/componentalias/Android.bp @@ -25,7 +25,7 @@ java_defaults { "androidx.test.rules", "compatibility-device-util-axt", "mockito-target-extended-minus-junit4", - "truth-prebuilt", + "truth", "ub-uiautomator", ], libs: ["android.test.base"], diff --git a/tools/processors/immutability/Android.bp b/tools/processors/immutability/Android.bp index a7d69039fcb0..ecc283b0b37e 100644 --- a/tools/processors/immutability/Android.bp +++ b/tools/processors/immutability/Android.bp @@ -50,7 +50,7 @@ java_test_host { static_libs: [ "compile-testing-prebuilt", - "truth-prebuilt", + "truth", "junit", "kotlin-reflect", "ImmutabilityAnnotationProcessorHostLibrary", diff --git a/tools/processors/intdef_mappings/Android.bp b/tools/processors/intdef_mappings/Android.bp index 7059c52ddc76..9c755b7d58c2 100644 --- a/tools/processors/intdef_mappings/Android.bp +++ b/tools/processors/intdef_mappings/Android.bp @@ -38,7 +38,7 @@ java_test_host { static_libs: [ "compile-testing-prebuilt", - "truth-prebuilt", + "truth", "junit", "guava", "libintdef-annotation-processor", diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp index 7a299694741a..5a0f742372d7 100644 --- a/wifi/tests/Android.bp +++ b/wifi/tests/Android.bp @@ -40,7 +40,7 @@ android_test { "frameworks-base-testutils", "guava", "mockito-target-minus-junit4", - "truth-prebuilt", + "truth", ], libs: [ |