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

Commit 90791068 authored by Kevin Chyn's avatar Kevin Chyn
Browse files

1/n: Add ClientMonitors for authenticatorId invalidation

InvalidationRequesterClient (for requesting other clients to
invalidate) will be fully implemented in subsequent CL's.

InvalidationClient (for requesting HALs to invalidate authenticatorId)
should be complete at this point.

Also updates BiometricUtils to persist a "invalidationInProgress"
flag on-disk for each <sensorId, userId> pair.

Bug: 159667191
Test: No effect on existing devices
Test: Existing enrollments not affected

Change-Id: I9eeb802b556ba86568cf41b456a4ceab4b896ef0
parent 8337a179
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -56,9 +56,9 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
    public AcquisitionClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
            @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
            @NonNull String owner, int cookie, int sensorId, int statsModality,
            int statsAction, int statsClient, boolean shouldLogMetrics) {
            int statsAction, int statsClient) {
        super(context, lazyDaemon, token, listener, userId, owner, cookie, sensorId, statsModality,
                statsAction, statsClient, shouldLogMetrics);
                statsAction, statsClient);
        mPowerManager = context.getSystemService(PowerManager.class);
        mSuccessVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
        mErrorVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
+1 −2
Original line number Diff line number Diff line
@@ -66,8 +66,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
            int statsModality, int statsClient, @Nullable TaskStackListener taskStackListener,
            @NonNull LockoutTracker lockoutTracker) {
        super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
                statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient,
                true /* shouldLogMetrics */);
                statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
        mIsStrongBiometric = isStrongBiometric;
        mOperationId = operationId;
        mRequireConfirmation = requireConfirmation;
+55 −8
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@ import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;

import com.android.internal.annotations.GuardedBy;
@@ -35,6 +37,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -46,17 +49,16 @@ import java.util.List;
public abstract class BiometricUserState<T extends BiometricAuthenticator.Identifier> {
    private static final String TAG = "UserState";

    private static final String TAG_INVALIDATION = "authenticatorIdInvalidation_tag";
    private static final String ATTR_INVALIDATION = "authenticatorIdInvalidation_attr";

    @GuardedBy("this")
    protected final ArrayList<T> mBiometrics = new ArrayList<>();
    protected boolean mInvalidationInProgress;
    protected final Context mContext;
    protected final File mFile;

    private final Runnable mWriteStateRunnable = new Runnable() {
        @Override
        public void run() {
            doWriteState();
        }
    };
    private final Runnable mWriteStateRunnable = this::doWriteStateInternal;

    /**
     * @return The tag for the biometrics. There may be multiple instances of a biometric within.
@@ -73,10 +75,40 @@ public abstract class BiometricUserState<T extends BiometricAuthenticator.Identi
     */
    protected abstract ArrayList<T> getCopy(ArrayList<T> array);

    protected abstract void doWriteState(@NonNull TypedXmlSerializer serializer) throws Exception;

    /**
     * @return Writes the cached data to persistent storage.
     * @Writes the cached data to persistent storage.
     */
    protected abstract void doWriteState();
    private void doWriteStateInternal() {
        AtomicFile destination = new AtomicFile(mFile);

        FileOutputStream out = null;

        try {
            out = destination.startWrite();
            TypedXmlSerializer serializer = Xml.resolveSerializer(out);
            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
            serializer.startDocument(null, true);

            // Store the authenticatorId
            serializer.startTag(null, TAG_INVALIDATION);
            serializer.attributeBoolean(null, ATTR_INVALIDATION, mInvalidationInProgress);
            serializer.endTag(null, TAG_INVALIDATION);

            // Do any additional serialization that subclasses may require
            doWriteState(serializer);

            serializer.endDocument();
            destination.finishWrite(out);
        } catch (Throwable t) {
            Slog.wtf(TAG, "Failed to write settings, restoring backup", t);
            destination.failWrite(out);
            throw new IllegalStateException("Failed to write to file: " + mFile.toString(), t);
        } finally {
            IoUtils.closeQuietly(out);
        }
    }

    /**
     * @return
@@ -93,6 +125,19 @@ public abstract class BiometricUserState<T extends BiometricAuthenticator.Identi
        }
    }

    public void setInvalidationInProgress(boolean invalidationInProgress) {
        synchronized (this) {
            mInvalidationInProgress = invalidationInProgress;
            scheduleWriteStateLocked();
        }
    }

    public boolean isInvalidationInProgress() {
        synchronized (this) {
            return mInvalidationInProgress;
        }
    }

    public void addBiometric(T identifier) {
        synchronized (this) {
            mBiometrics.add(identifier);
@@ -202,6 +247,8 @@ public abstract class BiometricUserState<T extends BiometricAuthenticator.Identi
            String tagName = parser.getName();
            if (tagName.equals(getBiometricsTag())) {
                parseBiometricsLocked(parser);
            } else if (tagName.equals(TAG_INVALIDATION)) {
                mInvalidationInProgress = parser.getAttributeBoolean(null, ATTR_INVALIDATION);
            }
        }
    }
+2 −0
Original line number Diff line number Diff line
@@ -31,4 +31,6 @@ public interface BiometricUtils<T extends BiometricAuthenticator.Identifier> {
    void removeBiometricForUser(Context context, int userId, int biometricId);
    void renameBiometricForUser(Context context, int userId, int biometricId, CharSequence name);
    CharSequence getUniqueName(Context context, int userId);
    void setInvalidationInProgress(Context context, int userId, boolean inProgress);
    boolean isInvalidationInProgress(Context context, int userId);
}
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -105,8 +105,8 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde
    public ClientMonitor(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
            @Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId,
            @NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction,
            int statsClient, boolean shouldLogMetrics) {
        super(statsModality, statsAction, statsClient, shouldLogMetrics);
            int statsClient) {
        super(statsModality, statsAction, statsClient);
        mSequentialId = sCount++;
        mContext = context;
        mLazyDaemon = lazyDaemon;
Loading