Previously, we show settings's udfps enroll animation view (the fingerprint icon and progress view) once the FingerprintEnrollEnrolling is shown. However, touch events have to wait for systemui's udfps overlay to be valid. This CL lets settings's udfps enroll view wait for systemui's overlay. 1. Sets udfps enroll animation view's default visibility Gone. 2. Propagates FingerprintManager#onUdfpsOverlayShown to FingerprintEnrollEnrolling and when it's called, set the enroll view visible. Besides, this CL renames onPointerDown() and onPointerUp() with Udfps. Bug: 280718879 Test: atest FingerprintEnrollEnrollingTest Change-Id: Ieed3e74c182828918785edcacb021f19a3665f2a
315 lines
9.1 KiB
Java
315 lines
9.1 KiB
Java
/*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License
|
|
*/
|
|
|
|
package com.android.settings.biometrics;
|
|
|
|
import android.annotation.Nullable;
|
|
import android.app.Activity;
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.os.CancellationSignal;
|
|
import android.os.Handler;
|
|
import android.os.UserHandle;
|
|
|
|
import com.android.settings.core.InstrumentedFragment;
|
|
import com.android.settings.password.ChooseLockSettingsHelper;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* Abstract sidecar fragment to handle the state around biometric enrollment. This sidecar manages
|
|
* the state of enrollment throughout the activity lifecycle so the app can continue after an
|
|
* event like rotation.
|
|
*/
|
|
public abstract class BiometricEnrollSidecar extends InstrumentedFragment {
|
|
|
|
public interface Listener {
|
|
void onEnrollmentHelp(int helpMsgId, CharSequence helpString);
|
|
void onEnrollmentError(int errMsgId, CharSequence errString);
|
|
void onEnrollmentProgressChange(int steps, int remaining);
|
|
/**
|
|
* Called when a fingerprint image has been acquired.
|
|
* @param isAcquiredGood whether the fingerprint image was good.
|
|
*/
|
|
default void onAcquired(boolean isAcquiredGood) { }
|
|
/**
|
|
* Called when a pointer down event has occurred.
|
|
*/
|
|
default void onUdfpsPointerDown(int sensorId) { }
|
|
/**
|
|
* Called when a pointer up event has occurred.
|
|
*/
|
|
default void onUdfpsPointerUp(int sensorId) { }
|
|
|
|
/**
|
|
* Called when udfps overlay is shown.
|
|
*/
|
|
default void onUdfpsOverlayShown() { }
|
|
}
|
|
|
|
private int mEnrollmentSteps = -1;
|
|
private int mEnrollmentRemaining = 0;
|
|
private Listener mListener;
|
|
private boolean mEnrolling;
|
|
private Handler mHandler = new Handler();
|
|
private boolean mDone;
|
|
private ArrayList<QueuedEvent> mQueuedEvents;
|
|
|
|
protected CancellationSignal mEnrollmentCancel;
|
|
protected byte[] mToken;
|
|
protected int mUserId;
|
|
|
|
private abstract class QueuedEvent {
|
|
public abstract void send(Listener listener);
|
|
}
|
|
|
|
private class QueuedEnrollmentProgress extends QueuedEvent {
|
|
int enrollmentSteps;
|
|
int remaining;
|
|
public QueuedEnrollmentProgress(int enrollmentSteps, int remaining) {
|
|
this.enrollmentSteps = enrollmentSteps;
|
|
this.remaining = remaining;
|
|
}
|
|
|
|
@Override
|
|
public void send(Listener listener) {
|
|
listener.onEnrollmentProgressChange(enrollmentSteps, remaining);
|
|
}
|
|
}
|
|
|
|
private class QueuedEnrollmentHelp extends QueuedEvent {
|
|
int helpMsgId;
|
|
CharSequence helpString;
|
|
public QueuedEnrollmentHelp(int helpMsgId, CharSequence helpString) {
|
|
this.helpMsgId = helpMsgId;
|
|
this.helpString = helpString;
|
|
}
|
|
|
|
@Override
|
|
public void send(Listener listener) {
|
|
listener.onEnrollmentHelp(helpMsgId, helpString);
|
|
}
|
|
}
|
|
|
|
private class QueuedEnrollmentError extends QueuedEvent {
|
|
int errMsgId;
|
|
CharSequence errString;
|
|
public QueuedEnrollmentError(int errMsgId, CharSequence errString) {
|
|
this.errMsgId = errMsgId;
|
|
this.errString = errString;
|
|
}
|
|
|
|
@Override
|
|
public void send(Listener listener) {
|
|
listener.onEnrollmentError(errMsgId, errString);
|
|
}
|
|
}
|
|
|
|
private class QueuedAcquired extends QueuedEvent {
|
|
private final boolean isAcquiredGood;
|
|
|
|
public QueuedAcquired(boolean isAcquiredGood) {
|
|
this.isAcquiredGood = isAcquiredGood;
|
|
}
|
|
|
|
@Override
|
|
public void send(Listener listener) {
|
|
listener.onAcquired(isAcquiredGood);
|
|
}
|
|
}
|
|
|
|
private class QueuedUdfpsPointerDown extends QueuedEvent {
|
|
private final int sensorId;
|
|
|
|
QueuedUdfpsPointerDown(int sensorId) {
|
|
this.sensorId = sensorId;
|
|
}
|
|
|
|
@Override
|
|
public void send(Listener listener) {
|
|
listener.onUdfpsPointerDown(sensorId);
|
|
}
|
|
}
|
|
|
|
private class QueuedUdfpsPointerUp extends QueuedEvent {
|
|
private final int sensorId;
|
|
|
|
QueuedUdfpsPointerUp(int sensorId) {
|
|
this.sensorId = sensorId;
|
|
}
|
|
|
|
@Override
|
|
public void send(Listener listener) {
|
|
listener.onUdfpsPointerUp(sensorId);
|
|
}
|
|
}
|
|
|
|
private class QueuedUdfpsOverlayShown extends QueuedEvent {
|
|
@Override
|
|
public void send(Listener listener) {
|
|
listener.onUdfpsOverlayShown();
|
|
}
|
|
}
|
|
|
|
private final Runnable mTimeoutRunnable = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
cancelEnrollment();
|
|
}
|
|
};
|
|
|
|
public BiometricEnrollSidecar() {
|
|
mQueuedEvents = new ArrayList<>();
|
|
}
|
|
|
|
@Override
|
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setRetainInstance(true);
|
|
}
|
|
|
|
@Override
|
|
public void onAttach(Activity activity) {
|
|
super.onAttach(activity);
|
|
mToken = activity.getIntent().getByteArrayExtra(
|
|
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
|
|
mUserId = activity.getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL);
|
|
}
|
|
|
|
@Override
|
|
public void onStart() {
|
|
super.onStart();
|
|
if (!mEnrolling) {
|
|
startEnrollment();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onStop() {
|
|
super.onStop();
|
|
if (!getActivity().isChangingConfigurations()) {
|
|
cancelEnrollment();
|
|
}
|
|
}
|
|
|
|
protected void startEnrollment() {
|
|
mHandler.removeCallbacks(mTimeoutRunnable);
|
|
mEnrollmentSteps = -1;
|
|
mEnrollmentCancel = new CancellationSignal();
|
|
mEnrolling = true;
|
|
}
|
|
|
|
public boolean cancelEnrollment() {
|
|
mHandler.removeCallbacks(mTimeoutRunnable);
|
|
if (mEnrolling) {
|
|
mEnrollmentCancel.cancel();
|
|
mEnrolling = false;
|
|
mEnrollmentSteps = -1;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected void onEnrollmentProgress(int remaining) {
|
|
if (mEnrollmentSteps == -1) {
|
|
mEnrollmentSteps = remaining;
|
|
}
|
|
mEnrollmentRemaining = remaining;
|
|
mDone = remaining == 0;
|
|
if (mListener != null) {
|
|
mListener.onEnrollmentProgressChange(mEnrollmentSteps, remaining);
|
|
} else {
|
|
mQueuedEvents.add(new QueuedEnrollmentProgress(mEnrollmentSteps, remaining));
|
|
}
|
|
}
|
|
|
|
protected void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
|
|
if (mListener != null) {
|
|
mListener.onEnrollmentHelp(helpMsgId, helpString);
|
|
} else {
|
|
mQueuedEvents.add(new QueuedEnrollmentHelp(helpMsgId, helpString));
|
|
}
|
|
}
|
|
|
|
protected void onEnrollmentError(int errMsgId, CharSequence errString) {
|
|
if (mListener != null) {
|
|
mListener.onEnrollmentError(errMsgId, errString);
|
|
} else {
|
|
mQueuedEvents.add(new QueuedEnrollmentError(errMsgId, errString));
|
|
}
|
|
mEnrolling = false;
|
|
}
|
|
|
|
protected void onAcquired(boolean isAcquiredGood) {
|
|
if (mListener != null) {
|
|
mListener.onAcquired(isAcquiredGood);
|
|
} else {
|
|
mQueuedEvents.add(new QueuedAcquired(isAcquiredGood));
|
|
}
|
|
}
|
|
|
|
protected void onUdfpsPointerDown(int sensorId) {
|
|
if (mListener != null) {
|
|
mListener.onUdfpsPointerDown(sensorId);
|
|
} else {
|
|
mQueuedEvents.add(new QueuedUdfpsPointerDown(sensorId));
|
|
}
|
|
}
|
|
|
|
protected void onUdfpsPointerUp(int sensorId) {
|
|
if (mListener != null) {
|
|
mListener.onUdfpsPointerUp(sensorId);
|
|
} else {
|
|
mQueuedEvents.add(new QueuedUdfpsPointerUp(sensorId));
|
|
}
|
|
}
|
|
|
|
protected void onUdfpsOverlayShown() {
|
|
if (mListener != null) {
|
|
mListener.onUdfpsOverlayShown();
|
|
} else {
|
|
mQueuedEvents.add(new QueuedUdfpsOverlayShown());
|
|
}
|
|
}
|
|
|
|
public void setListener(Listener listener) {
|
|
mListener = listener;
|
|
if (mListener != null) {
|
|
for (int i=0; i<mQueuedEvents.size(); i++) {
|
|
QueuedEvent event = mQueuedEvents.get(i);
|
|
event.send(mListener);
|
|
}
|
|
mQueuedEvents.clear();
|
|
}
|
|
}
|
|
|
|
public int getEnrollmentSteps() {
|
|
return mEnrollmentSteps;
|
|
}
|
|
|
|
public int getEnrollmentRemaining() {
|
|
return mEnrollmentRemaining;
|
|
}
|
|
|
|
public boolean isDone() {
|
|
return mDone;
|
|
}
|
|
|
|
public boolean isEnrolling() {
|
|
return mEnrolling;
|
|
}
|
|
}
|