Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d27d4b2 authored by Dmitry Dementyev's avatar Dmitry Dementyev
Browse files

Refactor remote lockscreen verification API.

Follow-up to API review:
1. Rename parcelable to RemoteLockscreenValidationSession.
2. Rename getLockscreenUiType to getLockType.
3. Add RESULT_SESSION_EXPIRED

Temporary keep StartLockscreenValidationRequest to avoid build errors.

Test: manual
Bug: 269256333
Change-Id: If7a92c56a048525139ba532f0b9f678a79aaaac1
parent 81b1f902
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -923,7 +923,7 @@ package android.app {
  public class KeyguardManager {
    method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public long addWeakEscrowToken(@NonNull byte[], @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.WeakEscrowTokenActivatedListener);
    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.content.Intent createConfirmDeviceCredentialForRemoteValidationIntent(@NonNull android.app.StartLockscreenValidationRequest, @NonNull android.content.ComponentName, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence);
    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.content.Intent createConfirmDeviceCredentialForRemoteValidationIntent(@NonNull android.app.RemoteLockscreenValidationSession, @NonNull android.content.ComponentName, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence, @Nullable CharSequence);
    method public android.content.Intent createConfirmFactoryResetCredentialIntent(CharSequence, CharSequence, CharSequence);
    method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public int getMinLockLength(boolean, int);
    method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public boolean getPrivateNotificationsAllowed();
@@ -935,7 +935,7 @@ package android.app {
    method @RequiresPermission(android.Manifest.permission.SHOW_KEYGUARD_MESSAGE) public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable CharSequence, @Nullable android.app.KeyguardManager.KeyguardDismissCallback);
    method @RequiresPermission("android.permission.SET_INITIAL_LOCK") public boolean setLock(int, @NonNull byte[], int);
    method @RequiresPermission(android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS) public void setPrivateNotificationsAllowed(boolean);
    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.app.StartLockscreenValidationRequest startRemoteLockscreenValidation();
    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.app.RemoteLockscreenValidationSession startRemoteLockscreenValidation();
    method @RequiresPermission(android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN) public boolean unregisterWeakEscrowTokenRemovedListener(@NonNull android.app.KeyguardManager.WeakEscrowTokenRemovedListener);
    method @NonNull @RequiresPermission(android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN) public android.app.RemoteLockscreenValidationResult validateRemoteLockscreen(@NonNull byte[]);
    field public static final int PASSWORD = 0; // 0x0
@@ -1024,6 +1024,7 @@ package android.app {
    field public static final int RESULT_GUESS_VALID = 1; // 0x1
    field public static final int RESULT_LOCKOUT = 3; // 0x3
    field public static final int RESULT_NO_REMAINING_ATTEMPTS = 4; // 0x4
    field public static final int RESULT_SESSION_EXPIRED = 5; // 0x5
  }
  public static final class RemoteLockscreenValidationResult.Builder {
@@ -1033,6 +1034,23 @@ package android.app {
    method @NonNull public android.app.RemoteLockscreenValidationResult.Builder setTimeoutMillis(long);
  }
  public final class RemoteLockscreenValidationSession implements android.os.Parcelable {
    method public int describeContents();
    method public int getLockType();
    method public int getRemainingAttempts();
    method @NonNull public byte[] getSourcePublicKey();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.RemoteLockscreenValidationSession> CREATOR;
  }
  public static final class RemoteLockscreenValidationSession.Builder {
    ctor public RemoteLockscreenValidationSession.Builder();
    method @NonNull public android.app.RemoteLockscreenValidationSession build();
    method @NonNull public android.app.RemoteLockscreenValidationSession.Builder setLockType(int);
    method @NonNull public android.app.RemoteLockscreenValidationSession.Builder setRemainingAttempts(int);
    method @NonNull public android.app.RemoteLockscreenValidationSession.Builder setSourcePublicKey(@NonNull byte[]);
  }
  public final class RuntimeAppOpAccessMessage implements android.os.Parcelable {
    ctor public RuntimeAppOpAccessMessage(@IntRange(from=0L) int, @IntRange(from=0L) int, @NonNull String, @Nullable String, @NonNull String, int);
    method public int describeContents();
+15 −9
Original line number Diff line number Diff line
@@ -154,6 +154,15 @@ public class KeyguardManager {
    public static final String EXTRA_START_LOCKSCREEN_VALIDATION_REQUEST =
            "android.app.extra.START_LOCKSCREEN_VALIDATION_REQUEST";

    /**
     * A {@link RemoteLockscreenValidationSession} extra to be sent along with
     * {@link #ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL} containing the data needed to prompt for
     * a remote device's lock screen.
     * @hide
     */
    public static final String EXTRA_REMOTE_LOCKSCREEN_VALIDATION_SESSION =
            "android.app.extra.REMOTE_LOCKSCREEN_VALIDATION_SESSION";

    /**
     * Result code returned by the activity started by
     * {@link #createConfirmFactoryResetCredentialIntent} or
@@ -359,8 +368,7 @@ public class KeyguardManager {
    /**
     * Get an Intent to launch an activity to prompt the user to confirm the
     * credentials (pin, pattern or password) of a remote device.
     * @param startLockscreenValidationRequest contains information necessary to start remote device
     *                                         credential validation.
     * @param session contains information necessary to start remote device credential validation.
     * @param remoteLockscreenValidationServiceComponent
     *          the {@link ComponentName} of the implementation of
     *          {@link android.service.remotelockscreenvalidation.RemoteLockscreenValidationService}
@@ -376,15 +384,14 @@ public class KeyguardManager {
    @RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
    @NonNull
    public Intent createConfirmDeviceCredentialForRemoteValidationIntent(
            @NonNull StartLockscreenValidationRequest startLockscreenValidationRequest,
            @NonNull RemoteLockscreenValidationSession session,
            @NonNull ComponentName remoteLockscreenValidationServiceComponent,
            @Nullable CharSequence title,
            @Nullable CharSequence description,
            @Nullable CharSequence checkboxLabel,
            @Nullable CharSequence alternateButtonLabel) {
        Intent intent = new Intent(ACTION_CONFIRM_REMOTE_DEVICE_CREDENTIAL)
                .putExtra(
                        EXTRA_START_LOCKSCREEN_VALIDATION_REQUEST, startLockscreenValidationRequest)
                .putExtra(EXTRA_REMOTE_LOCKSCREEN_VALIDATION_SESSION, session)
                .putExtra(Intent.EXTRA_COMPONENT_NAME, remoteLockscreenValidationServiceComponent)
                .putExtra(EXTRA_TITLE, title)
                .putExtra(EXTRA_DESCRIPTION, description)
@@ -1157,7 +1164,7 @@ public class KeyguardManager {
    @SystemApi
    @RequiresPermission(Manifest.permission.CHECK_REMOTE_LOCKSCREEN)
    @NonNull
    public StartLockscreenValidationRequest startRemoteLockscreenValidation() {
    public RemoteLockscreenValidationSession startRemoteLockscreenValidation() {
        return mLockPatternUtils.startRemoteLockscreenValidation();
    }

@@ -1165,11 +1172,10 @@ public class KeyguardManager {
     * Verifies credentials guess from a remote device.
     *
     * <p>Secret must be encrypted using {@code SecureBox} library
     * with public key from {@code StartLockscreenValidationRequest}
     * with public key from {@code RemoteLockscreenValidationSession}
     * and header set to {@code "encrypted_remote_credentials"} in UTF-8 encoding.
     *
     * @throws IllegalStateException if there is no active lock screen validation session or
     * there was a decryption error.
     * @throws IllegalStateException if there was a decryption error.
     *
     * @hide
     */
+7 −1
Original line number Diff line number Diff line
@@ -55,10 +55,16 @@ public final class RemoteLockscreenValidationResult implements Parcelable {
     */
    public static final int RESULT_NO_REMAINING_ATTEMPTS = 4;

    /**
     * New lockscreen validation session is required to verify guess.
     */
    public static final int RESULT_SESSION_EXPIRED = 5;

    @IntDef({RESULT_GUESS_VALID,
            RESULT_GUESS_INVALID,
            RESULT_LOCKOUT,
            RESULT_NO_REMAINING_ATTEMPTS})
            RESULT_NO_REMAINING_ATTEMPTS,
            RESULT_SESSION_EXPIRED})
    @Retention(RetentionPolicy.SOURCE)
    @interface ResultCode {}

+20 −0
Original line number Diff line number Diff line
/*
 * 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.app;

/** {@hide} */
parcelable RemoteLockscreenValidationSession;
+149 −0
Original line number Diff line number Diff line
/*
 * 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.app;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.KeyguardManager.LockTypes;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Objects;

/**
 * Provides information necessary to perform remote lock screen credentials check.
 *
 * @hide
 */
@SystemApi
public final class RemoteLockscreenValidationSession implements Parcelable {

    @LockTypes
    private int mLockType;

    private byte[] mSourcePublicKey;

    private int mRemainingAttempts;

    public static final @NonNull Parcelable.Creator<RemoteLockscreenValidationSession> CREATOR = new
            Parcelable.Creator<RemoteLockscreenValidationSession>() {
        @Override
        public RemoteLockscreenValidationSession createFromParcel(Parcel source) {
            return new RemoteLockscreenValidationSession(source);
        }

        @Override
        public RemoteLockscreenValidationSession[] newArray(int size) {
            return new RemoteLockscreenValidationSession[size];
        }
    };


    /**
     * Builder for {@code RemoteLockscreenValidationSession}
     */
    public static final class Builder {
        private RemoteLockscreenValidationSession mInstance =
                new RemoteLockscreenValidationSession();

        /**
         * Sets UI type.
         * Default value is {@code LockTypes.PASSWORD}
         *
         * @param lockType The UI format
         * @return This builder.
         */
        public @NonNull Builder setLockType(@LockTypes int lockType) {
            mInstance.mLockType = lockType;
            return this;
        }

        /**
         * Sets public key using secure box encoding
         * @return This builder.
         */
        public @NonNull Builder setSourcePublicKey(@NonNull byte[] publicKey) {
            mInstance.mSourcePublicKey = publicKey;
            return this;
        }

        /**
         * Sets the number of remaining credentials check
         * Default value is {@code 0}
         *
         * @return This builder.
         */
        public @NonNull Builder setRemainingAttempts(int remainingAttempts) {
            mInstance.mRemainingAttempts = remainingAttempts;
            return this;
        }

        /**
         * Creates {@code RemoteLockscreenValidationSession}
         *
         * @throws NullPointerException if required fields are not set.
         */
        public @NonNull RemoteLockscreenValidationSession build() {
            Objects.requireNonNull(mInstance.mSourcePublicKey);
            return mInstance;
        }
    }

    /**
     * Specifies lock screen credential type.
     */
    public @LockTypes int getLockType() {
        return mLockType;
    }

    /**
     * Public key used to send encrypted credentials.
     */
    public @NonNull byte[] getSourcePublicKey() {
        return mSourcePublicKey;
    }

    /**
     * Number of remaining attempts to verify credentials.
     *
     * <p>After correct guess counter is reset to {@code 5}.
     */
    public int getRemainingAttempts() {
        return mRemainingAttempts;
    }

    @Override
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeInt(mLockType);
        out.writeByteArray(mSourcePublicKey);
        out.writeInt(mRemainingAttempts);
    }

    private RemoteLockscreenValidationSession() {
    }

    private RemoteLockscreenValidationSession(Parcel in) {
        mLockType = in.readInt();
        mSourcePublicKey = in.createByteArray();
        mRemainingAttempts = in.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
Loading