Merge "Created a clickable toast for sidefps enrollment" into tm-qpr-dev

This commit is contained in:
Joshua Mccloskey
2022-08-11 18:32:16 +00:00
committed by Android (Google) Code Review
7 changed files with 216 additions and 171 deletions

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2022 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="350dp"
android:layout_gravity="center"
android:theme="?attr/alertDialogTheme">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fp_power_button_enrollment_title"
android:singleLine="true"
android:ellipsize="end"
android:paddingLeft="20dp"/>
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/turn_off_screen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fp_power_button_enrollment_button_text"
android:paddingRight="20dp"
style="?android:attr/buttonBarNegativeButtonStyle"
android:maxLines="1"/>
</LinearLayout>

View File

@@ -3519,9 +3519,9 @@
(for side fingerprint) --> (for side fingerprint) -->
<integer name="config_sidefpsPostAuthDowntime">400</integer> <integer name="config_sidefpsPostAuthDowntime">400</integer>
<!-- The time (in millis) that a finger tap will wait for a power button <!-- The time (in millis) the clickable toast dialog will last until
before dismissing the power dialog during enrollment(for side fingerprint) --> automatically dismissing. This is currently used in SideFpsEventHandler -->
<integer name="config_sidefpsEnrollPowerPressWindow">300</integer> <integer name="config_sideFpsToastTimeout">3000</integer>
<!-- This config is used to force VoiceInteractionService to start on certain low ram devices. <!-- This config is used to force VoiceInteractionService to start on certain low ram devices.
It declares the package name of VoiceInteractionService that should be started. --> It declares the package name of VoiceInteractionService that should be started. -->

View File

@@ -3568,21 +3568,17 @@
<!-- [CHAR LIMIT=NONE] Message to show in upgrading dialog when the bulk of the upgrade work is done. --> <!-- [CHAR LIMIT=NONE] Message to show in upgrading dialog when the bulk of the upgrade work is done. -->
<string name="android_upgrading_complete">Finishing boot.</string> <string name="android_upgrading_complete">Finishing boot.</string>
<!-- [CHAR LIMIT=40] Title of dialog shown to confirm device going to sleep if the power button
is pressed during fingerprint enrollment. -->
<string name="fp_power_button_enrollment_title">Continue setup?</string>
<!-- [CHAR LIMIT=NONE] Message of dialog shown to confirm device going to sleep if the power <!-- [CHAR LIMIT=NONE] Message of dialog shown to confirm device going to sleep if the power
button is pressed during fingerprint enrollment. --> button is pressed during fingerprint enrollment. -->
<string name="fp_power_button_enrollment_message">You pressed the power button — this usually turns off the screen.\n\nTry tapping lightly while setting up your fingerprint.</string> <string name="fp_power_button_enrollment_message">You pressed the power button — this usually turns off the screen.\n\nTry tapping lightly while setting up your fingerprint.</string>
<!-- [CHAR LIMIT=40] Title of dialog shown to confirm device going to sleep if the power button
is pressed during fingerprint enrollment. -->
<string name="fp_power_button_enrollment_title">Tap to turn off screen</string>
<!-- [CHAR LIMIT=20] Positive button of dialog shown to confirm device going to sleep if the <!-- [CHAR LIMIT=20] Positive button of dialog shown to confirm device going to sleep if the
power button is pressed during fingerprint enrollment. --> power button is pressed during fingerprint enrollment. -->
<string name="fp_power_button_enrollment_positive_button">Turn off screen</string> <string name="fp_power_button_enrollment_button_text">Turn off screen</string>
<!-- [CHAR LIMIT=20] Negative button of dialog shown to confirm device going to sleep if the
power button is pressed during fingerprint enrollment. -->
<string name="fp_power_button_enrollment_negative_button">Continue setup</string>
<!-- [CHAR LIMIT=40] Title of dialog shown to confirm device going to sleep if the power button <!-- [CHAR LIMIT=40] Title of dialog shown to confirm device going to sleep if the power button
is pressed during biometric prompt when a side fingerprint sensor is present. --> is pressed during biometric prompt when a side fingerprint sensor is present. -->

View File

@@ -1853,8 +1853,7 @@
<java-symbol type="string" name="fp_power_button_bp_negative_button" /> <java-symbol type="string" name="fp_power_button_bp_negative_button" />
<java-symbol type="string" name="fp_power_button_enrollment_title" /> <java-symbol type="string" name="fp_power_button_enrollment_title" />
<java-symbol type="string" name="fp_power_button_enrollment_message" /> <java-symbol type="string" name="fp_power_button_enrollment_message" />
<java-symbol type="string" name="fp_power_button_enrollment_positive_button" /> <java-symbol type="string" name="fp_power_button_enrollment_button_text" />
<java-symbol type="string" name="fp_power_button_enrollment_negative_button" />
<java-symbol type="string" name="global_actions" /> <java-symbol type="string" name="global_actions" />
<java-symbol type="string" name="global_action_power_off" /> <java-symbol type="string" name="global_action_power_off" />
<java-symbol type="string" name="global_action_power_options" /> <java-symbol type="string" name="global_action_power_options" />
@@ -2631,7 +2630,11 @@
<java-symbol type="integer" name="config_sidefpsBpPowerPressWindow"/> <java-symbol type="integer" name="config_sidefpsBpPowerPressWindow"/>
<java-symbol type="integer" name="config_sidefpsKeyguardPowerPressWindow"/> <java-symbol type="integer" name="config_sidefpsKeyguardPowerPressWindow"/>
<java-symbol type="integer" name="config_sidefpsPostAuthDowntime"/> <java-symbol type="integer" name="config_sidefpsPostAuthDowntime"/>
<java-symbol type="integer" name="config_sidefpsEnrollPowerPressWindow"/> <java-symbol type="integer" name="config_sideFpsToastTimeout"/>
<!-- Clickable toast used during sidefps enrollment -->
<java-symbol type="layout" name="side_fps_toast" />
<java-symbol type="id" name="turn_off_screen" />
<!-- Face authentication messages --> <!-- Face authentication messages -->
<java-symbol type="string" name="face_recalibrate_notification_name" /> <java-symbol type="string" name="face_recalibrate_notification_name" />

View File

@@ -23,11 +23,8 @@ import static android.hardware.biometrics.BiometricStateListener.STATE_KEYGUARD_
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@@ -35,12 +32,11 @@ import android.hardware.biometrics.BiometricStateListener;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log; import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import com.android.internal.R; import com.android.internal.R;
@@ -48,49 +44,48 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
/** /**
* Defines behavior for handling interactions between power button events and fingerprint-related * Defines behavior for handling interactions between power button events and fingerprint-related
* operations, for devices where the fingerprint sensor (side fps) lives on the power button. * operations, for devices where the fingerprint sensor (side fps) lives on the power button.
*/ */
public class SideFpsEventHandler { public class SideFpsEventHandler implements View.OnClickListener {
private static final int DEBOUNCE_DELAY_MILLIS = 500; private static final int DEBOUNCE_DELAY_MILLIS = 500;
private int getTapWaitForPowerDuration(Context context) {
int tap = context.getResources().getInteger(
R.integer.config_sidefpsEnrollPowerPressWindow);
if (Build.isDebuggable()) {
tap = Settings.Secure.getIntForUser(context.getContentResolver(),
Settings.Secure.FINGERPRINT_SIDE_FPS_ENROLL_TAP_WINDOW, tap,
UserHandle.USER_CURRENT);
}
return tap;
}
private static final String TAG = "SideFpsEventHandler"; private static final String TAG = "SideFpsEventHandler";
@NonNull private final Context mContext; @NonNull
@NonNull private final Handler mHandler; private final Context mContext;
@NonNull private final PowerManager mPowerManager; @NonNull
@NonNull private final Supplier<AlertDialog.Builder> mDialogSupplier; private final Handler mHandler;
@NonNull private final AtomicBoolean mSideFpsEventHandlerReady; @NonNull
private final PowerManager mPowerManager;
@Nullable private Dialog mDialog; @NonNull
private final AtomicBoolean mSideFpsEventHandlerReady;
private final int mDismissDialogTimeout;
@Nullable
private SideFpsToast mDialog;
private final Runnable mTurnOffDialog = private final Runnable mTurnOffDialog =
() -> { () -> {
dismissDialog("mTurnOffDialog"); dismissDialog("mTurnOffDialog");
}; };
@NonNull private final DialogInterface.OnDismissListener mDialogDismissListener;
private @BiometricStateListener.State int mBiometricState; private @BiometricStateListener.State int mBiometricState;
private final int mTapWaitForPowerDuration;
private FingerprintManager mFingerprintManager; private FingerprintManager mFingerprintManager;
private DialogProvider mDialogProvider;
private long mLastPowerPressTime;
SideFpsEventHandler(Context context, Handler handler, PowerManager powerManager) { SideFpsEventHandler(
this(context, handler, powerManager, () -> new AlertDialog.Builder(context)); Context context,
Handler handler,
PowerManager powerManager) {
this(context, handler, powerManager, (ctx) -> {
SideFpsToast dialog = new SideFpsToast(ctx);
dialog.getWindow()
.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
});
} }
@VisibleForTesting @VisibleForTesting
@@ -98,23 +93,13 @@ public class SideFpsEventHandler {
Context context, Context context,
Handler handler, Handler handler,
PowerManager powerManager, PowerManager powerManager,
Supplier<AlertDialog.Builder> dialogSupplier) { DialogProvider provider) {
mContext = context; mContext = context;
mHandler = handler; mHandler = handler;
mPowerManager = powerManager; mPowerManager = powerManager;
mDialogSupplier = dialogSupplier;
mBiometricState = STATE_IDLE; mBiometricState = STATE_IDLE;
mSideFpsEventHandlerReady = new AtomicBoolean(false); mSideFpsEventHandlerReady = new AtomicBoolean(false);
mDialogDismissListener = mDialogProvider = provider;
(dialog) -> {
if (mDialog == dialog) {
if (mHandler != null) {
mHandler.removeCallbacks(mTurnOffDialog);
}
mDialog = null;
}
};
// ensure dialog is dismissed if screen goes off for unrelated reasons // ensure dialog is dismissed if screen goes off for unrelated reasons
context.registerReceiver( context.registerReceiver(
new BroadcastReceiver() { new BroadcastReceiver() {
@@ -127,7 +112,13 @@ public class SideFpsEventHandler {
} }
}, },
new IntentFilter(Intent.ACTION_SCREEN_OFF)); new IntentFilter(Intent.ACTION_SCREEN_OFF));
mTapWaitForPowerDuration = getTapWaitForPowerDuration(context); mDismissDialogTimeout = context.getResources().getInteger(
R.integer.config_sideFpsToastTimeout);
}
@Override
public void onClick(View v) {
goToSleep(mLastPowerPressTime);
} }
/** /**
@@ -165,8 +156,9 @@ public class SideFpsEventHandler {
Log.v(TAG, "Detected a tap to turn off dialog, ignoring"); Log.v(TAG, "Detected a tap to turn off dialog, ignoring");
mHandler.removeCallbacks(mTurnOffDialog); mHandler.removeCallbacks(mTurnOffDialog);
} }
showDialog(eventTime, "Enroll Power Press");
mHandler.postDelayed(mTurnOffDialog, mDismissDialogTimeout);
}); });
showDialog(eventTime, "Enroll Power Press");
return true; return true;
case STATE_BP_AUTH: case STATE_BP_AUTH:
return true; return true;
@@ -176,54 +168,11 @@ public class SideFpsEventHandler {
} }
} }
@NonNull private void goToSleep(long eventTime) {
private static Dialog showConfirmDialog( mPowerManager.goToSleep(
@NonNull AlertDialog.Builder dialogBuilder, eventTime,
@NonNull PowerManager powerManager, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
long eventTime, 0 /* flags */);
@BiometricStateListener.State int biometricState,
@NonNull DialogInterface.OnDismissListener dismissListener) {
final boolean enrolling = biometricState == STATE_ENROLLING;
final int title =
enrolling
? R.string.fp_power_button_enrollment_title
: R.string.fp_power_button_bp_title;
final int message =
enrolling
? R.string.fp_power_button_enrollment_message
: R.string.fp_power_button_bp_message;
final int positiveText =
enrolling
? R.string.fp_power_button_enrollment_positive_button
: R.string.fp_power_button_bp_positive_button;
final int negativeText =
enrolling
? R.string.fp_power_button_enrollment_negative_button
: R.string.fp_power_button_bp_negative_button;
final Dialog confirmScreenOffDialog =
dialogBuilder
.setTitle(title)
.setMessage(message)
.setPositiveButton(
positiveText,
(dialog, which) -> {
dialog.dismiss();
powerManager.goToSleep(
eventTime,
PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
0 /* flags */);
})
.setNegativeButton(negativeText, (dialog, which) -> dialog.dismiss())
.setOnDismissListener(dismissListener)
.setCancelable(false)
.create();
confirmScreenOffDialog
.getWindow()
.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
confirmScreenOffDialog.show();
return confirmScreenOffDialog;
} }
/** /**
@@ -247,7 +196,8 @@ public class SideFpsEventHandler {
if (fingerprintManager.isPowerbuttonFps()) { if (fingerprintManager.isPowerbuttonFps()) {
fingerprintManager.registerBiometricStateListener( fingerprintManager.registerBiometricStateListener(
new BiometricStateListener() { new BiometricStateListener() {
@Nullable private Runnable mStateRunnable = null; @Nullable
private Runnable mStateRunnable = null;
@Override @Override
public void onStateChanged( public void onStateChanged(
@@ -281,13 +231,6 @@ public class SideFpsEventHandler {
public void onBiometricAction( public void onBiometricAction(
@BiometricStateListener.Action int action) { @BiometricStateListener.Action int action) {
Log.d(TAG, "onBiometricAction " + action); Log.d(TAG, "onBiometricAction " + action);
switch (action) {
case BiometricStateListener.ACTION_SENSOR_TOUCH:
mHandler.postDelayed(
mTurnOffDialog,
mTapWaitForPowerDuration);
break;
}
} }
}); });
mSideFpsEventHandlerReady.set(true); mSideFpsEventHandlerReady.set(true);
@@ -309,12 +252,13 @@ public class SideFpsEventHandler {
Log.d(TAG, "Ignoring show dialog"); Log.d(TAG, "Ignoring show dialog");
return; return;
} }
mDialog = mDialog = mDialogProvider.provideDialog(mContext);
showConfirmDialog( mLastPowerPressTime = time;
mDialogSupplier.get(), mDialog.show();
mPowerManager, mDialog.setOnClickListener(this);
time, }
mBiometricState,
mDialogDismissListener); interface DialogProvider {
SideFpsToast provideDialog(Context context);
} }
} }

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2022 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.server.policy;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import com.android.internal.R;
/**
* Toast for side fps. This is typically shown during enrollment
* when a user presses the power button.
*
* This dialog is used by {@link SideFpsEventHandler}
*/
public class SideFpsToast extends Dialog {
SideFpsToast(Context context) {
super(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.side_fps_toast);
}
@Override
protected void onStart() {
super.onStart();
final Window window = this.getWindow();
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.dimAmount = 0;
windowParams.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
windowParams.gravity = Gravity.BOTTOM;
window.setAttributes(windowParams);
}
/**
* Sets the onClickListener for the toast dialog.
* @param listener
*/
public void setOnClickListener(View.OnClickListener listener) {
final Button turnOffScreen = findViewById(R.id.turn_off_screen);
if (turnOffScreen != null) {
turnOffScreen.setOnClickListener(listener);
}
}
}

View File

@@ -24,7 +24,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.AlertDialog;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricStateListener; import android.hardware.biometrics.BiometricStateListener;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
@@ -36,10 +35,13 @@ import android.os.test.TestLooper;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.testing.TestableContext; import android.testing.TestableContext;
import android.testing.TestableResources;
import android.view.Window; import android.view.Window;
import androidx.test.InstrumentationRegistry; import androidx.test.InstrumentationRegistry;
import com.android.internal.R;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@@ -47,7 +49,6 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import java.util.List; import java.util.List;
@@ -68,17 +69,22 @@ public class SideFpsEventHandlerTest {
BiometricStateListener.STATE_BP_AUTH, BiometricStateListener.STATE_BP_AUTH,
BiometricStateListener.STATE_AUTH_OTHER); BiometricStateListener.STATE_AUTH_OTHER);
private static final Integer AUTO_DISMISS_DIALOG = 500;
@Rule @Rule
public TestableContext mContext = public TestableContext mContext =
new TestableContext(InstrumentationRegistry.getContext(), null); new TestableContext(InstrumentationRegistry.getContext(), null);
@Mock private PackageManager mPackageManager; @Mock
@Mock private FingerprintManager mFingerprintManager; private PackageManager mPackageManager;
@Spy private AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(mContext); @Mock
@Mock private AlertDialog mAlertDialog; private FingerprintManager mFingerprintManager;
@Mock private Window mWindow; @Mock
private SideFpsToast mDialog;
@Mock
private Window mWindow;
private TestLooper mLooper = new TestLooper(); private final TestLooper mLooper = new TestLooper();
private SideFpsEventHandler mEventHandler; private SideFpsEventHandler mEventHandler;
private BiometricStateListener mBiometricStateListener; private BiometricStateListener mBiometricStateListener;
@@ -88,16 +94,17 @@ public class SideFpsEventHandlerTest {
mContext.addMockSystemService(PackageManager.class, mPackageManager); mContext.addMockSystemService(PackageManager.class, mPackageManager);
mContext.addMockSystemService(FingerprintManager.class, mFingerprintManager); mContext.addMockSystemService(FingerprintManager.class, mFingerprintManager);
TestableResources resources = mContext.getOrCreateTestableResources();
resources.addOverride(R.integer.config_sideFpsToastTimeout, AUTO_DISMISS_DIALOG);
when(mDialogBuilder.create()).thenReturn(mAlertDialog); when(mDialog.getWindow()).thenReturn(mWindow);
when(mAlertDialog.getWindow()).thenReturn(mWindow);
mEventHandler = mEventHandler =
new SideFpsEventHandler( new SideFpsEventHandler(
mContext, mContext,
new Handler(mLooper.getLooper()), new Handler(mLooper.getLooper()),
mContext.getSystemService(PowerManager.class), mContext.getSystemService(PowerManager.class),
() -> mDialogBuilder); (ctx) -> mDialog);
} }
@Test @Test
@@ -108,7 +115,7 @@ public class SideFpsEventHandlerTest {
assertThat(mEventHandler.shouldConsumeSinglePress(60L)).isFalse(); assertThat(mEventHandler.shouldConsumeSinglePress(60L)).isFalse();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog, never()).show(); verify(mDialog, never()).show();
} }
@Test @Test
@@ -120,7 +127,7 @@ public class SideFpsEventHandlerTest {
assertThat(mEventHandler.shouldConsumeSinglePress(200L)).isFalse(); assertThat(mEventHandler.shouldConsumeSinglePress(200L)).isFalse();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog, never()).show(); verify(mDialog, never()).show();
} }
} }
@@ -133,7 +140,7 @@ public class SideFpsEventHandlerTest {
assertThat(mEventHandler.shouldConsumeSinglePress(400L)).isFalse(); assertThat(mEventHandler.shouldConsumeSinglePress(400L)).isFalse();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog, never()).show(); verify(mDialog, never()).show();
} }
} }
@@ -148,7 +155,7 @@ public class SideFpsEventHandlerTest {
assertThat(mEventHandler.shouldConsumeSinglePress(90000L)).isFalse(); assertThat(mEventHandler.shouldConsumeSinglePress(90000L)).isFalse();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog, never()).show(); verify(mDialog, never()).show();
} }
@Test @Test
@@ -159,18 +166,18 @@ public class SideFpsEventHandlerTest {
assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isFalse(); assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isFalse();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog, never()).show(); verify(mDialog, never()).show();
} }
@Test @Test
public void promptsWhenBPisActive() throws Exception { public void doesNotpromptWhenBPisActive() throws Exception {
setupWithSensor(true /* hasSideFps */, true /* initialized */); setupWithSensor(true /* hasSideFps */, true /* initialized */);
setBiometricState(BiometricStateListener.STATE_BP_AUTH); setBiometricState(BiometricStateListener.STATE_BP_AUTH);
assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue(); assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog, never()).show(); verify(mDialog, never()).show();
} }
@Test @Test
@@ -181,57 +188,40 @@ public class SideFpsEventHandlerTest {
assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue(); assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog).show(); verify(mDialog).show();
verify(mAlertDialog, never()).dismiss();
} }
@Test @Test
public void dismissesDialogOnTouchWhenEnrolling() throws Exception { public void dialogDismissesAfterTime() throws Exception {
setupWithSensor(true /* hasSfps */, true /* initialized */); setupWithSensor(true /* hasSfps */, true /* initialized */);
setBiometricState(BiometricStateListener.STATE_ENROLLING); setBiometricState(BiometricStateListener.STATE_ENROLLING);
when(mAlertDialog.isShowing()).thenReturn(true); when(mDialog.isShowing()).thenReturn(true);
assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue(); assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog).show(); verify(mDialog).show();
mLooper.moveTimeForward(AUTO_DISMISS_DIALOG);
mBiometricStateListener.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
mLooper.moveTimeForward(10000);
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mDialog).dismiss();
verify(mAlertDialog).dismiss();
} }
@Test @Test
public void dismissesDialogFailsWhenPowerPressedAndDialogShowing() throws Exception { public void dialogDoesNotDismissOnSensorTouch() throws Exception {
setupWithSensor(true /* hasSfps */, true /* initialized */); setupWithSensor(true /* hasSfps */, true /* initialized */);
setBiometricState(BiometricStateListener.STATE_ENROLLING); setBiometricState(BiometricStateListener.STATE_ENROLLING);
when(mAlertDialog.isShowing()).thenReturn(true); when(mDialog.isShowing()).thenReturn(true);
assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue(); assertThat(mEventHandler.shouldConsumeSinglePress(80000L)).isTrue();
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog).show(); verify(mDialog).show();
mBiometricStateListener.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH); mBiometricStateListener.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
assertThat(mEventHandler.shouldConsumeSinglePress(60L)).isTrue(); mLooper.moveTimeForward(AUTO_DISMISS_DIALOG - 1);
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mAlertDialog, never()).dismiss();
}
@Test verify(mDialog, never()).dismiss();
public void showDialogAfterTap() throws Exception {
setupWithSensor(true /* hasSfps */, true /* initialized */);
setBiometricState(BiometricStateListener.STATE_ENROLLING);
when(mAlertDialog.isShowing()).thenReturn(true);
mBiometricStateListener.onBiometricAction(BiometricStateListener.ACTION_SENSOR_TOUCH);
assertThat(mEventHandler.shouldConsumeSinglePress(60L)).isTrue();
mLooper.dispatchAll();
verify(mAlertDialog).show();
} }
private void setBiometricState(@BiometricStateListener.State int newState) { private void setBiometricState(@BiometricStateListener.State int newState) {