Merge "Make auth dialog in large size expand into cutout area" into udc-dev

This commit is contained in:
Shawn Lin
2023-05-17 06:31:10 +00:00
committed by Android (Google) Code Review
5 changed files with 106 additions and 4 deletions

View File

@@ -28,6 +28,7 @@ import android.annotation.Nullable;
import android.annotation.StringRes;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Insets;
import android.hardware.biometrics.BiometricAuthenticator.Modality;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.PromptInfo;
@@ -298,9 +299,25 @@ public abstract class AuthBiometricView extends LinearLayout {
mJankListener = jankListener;
}
private void updatePaddings(int size) {
final Insets navBarInsets = Utils.getNavbarInsets(mContext);
if (size != AuthDialog.SIZE_LARGE) {
if (mPanelController.getPosition() == AuthPanelController.POSITION_LEFT) {
setPadding(navBarInsets.left, 0, 0, 0);
} else if (mPanelController.getPosition() == AuthPanelController.POSITION_RIGHT) {
setPadding(0, 0, navBarInsets.right, 0);
} else {
setPadding(0, 0, 0, navBarInsets.bottom);
}
} else {
setPadding(0, 0, 0, 0);
}
}
@VisibleForTesting
final void updateSize(@AuthDialog.DialogSize int newSize) {
Log.v(TAG, "Current size: " + mSize + " New size: " + newSize);
updatePaddings(newSize);
if (newSize == AuthDialog.SIZE_SMALL) {
mTitleView.setVisibility(View.GONE);
mSubtitleView.setVisibility(View.GONE);
@@ -527,6 +544,11 @@ public abstract class AuthBiometricView extends LinearLayout {
mState = newState;
}
void onOrientationChanged() {
// Update padding and AuthPanel outline by calling updateSize when the orientation changed.
updateSize(mSize);
}
public void onDialogAnimatedIn() {
updateState(STATE_AUTHENTICATING);
}
@@ -868,6 +890,25 @@ public abstract class AuthBiometricView extends LinearLayout {
}
mLayoutParams = onMeasureInternal(width, height);
final Insets navBarInsets = Utils.getNavbarInsets(mContext);
final int navBarHeight = navBarInsets.bottom;
final int navBarWidth;
if (mPanelController.getPosition() == AuthPanelController.POSITION_LEFT) {
navBarWidth = navBarInsets.left;
} else if (mPanelController.getPosition() == AuthPanelController.POSITION_RIGHT) {
navBarWidth = navBarInsets.right;
} else {
navBarWidth = 0;
}
// The actual auth dialog w/h should include navigation bar size.
if (navBarWidth != 0 || navBarHeight != 0) {
mLayoutParams = new AuthDialog.LayoutParams(
mLayoutParams.mMediumWidth + navBarWidth,
mLayoutParams.mMediumHeight + navBarInsets.bottom);
}
setMeasuredDimension(mLayoutParams.mMediumWidth, mLayoutParams.mMediumHeight);
}

View File

@@ -19,6 +19,7 @@ package com.android.systemui.biometrics;
import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
import static android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION;
@@ -512,6 +513,9 @@ public class AuthContainerView extends LinearLayout
@Override
public void onOrientationChanged() {
maybeUpdatePositionForUdfps(true /* invalidate */);
if (mBiometricView != null) {
mBiometricView.onOrientationChanged();
}
}
@Override
@@ -899,7 +903,9 @@ public class AuthContainerView extends LinearLayout
windowFlags,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime());
lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~WindowInsets.Type.ime()
& ~WindowInsets.Type.systemBars());
lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
lp.setTitle("BiometricPrompt");
lp.accessibilityTitle = title;
lp.dimAmount = BACKGROUND_DIM_AMOUNT;

View File

@@ -20,6 +20,7 @@ import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Outline;
import android.util.Log;
import android.view.View;
@@ -64,13 +65,12 @@ public class AuthPanelController extends ViewOutlineProvider {
@Override
public void getOutline(View view, Outline outline) {
final int left = getLeftBound(mPosition);
final int right = left + mContentWidth;
final int right = getRightBound(mPosition, left);
// If the content fits in the container, shrink the height to wrap it. Otherwise, expand to
// fill the display (minus the margin), since the content is scrollable.
final int top = getTopBound(mPosition);
final int bottom = Math.min(top + mContentHeight, mContainerHeight - mMargin);
final int bottom = getBottomBound(top);
outline.setRoundRect(left, top, right, bottom, mCornerRadius);
}
@@ -79,6 +79,10 @@ public class AuthPanelController extends ViewOutlineProvider {
case POSITION_BOTTOM:
return (mContainerWidth - mContentWidth) / 2;
case POSITION_LEFT:
if (!mUseFullScreen) {
final Insets navBarInsets = Utils.getNavbarInsets(mContext);
return mMargin + navBarInsets.left;
}
return mMargin;
case POSITION_RIGHT:
return mContainerWidth - mContentWidth - mMargin;
@@ -88,6 +92,27 @@ public class AuthPanelController extends ViewOutlineProvider {
}
}
private int getRightBound(@Position int position, int left) {
if (!mUseFullScreen) {
final Insets navBarInsets = Utils.getNavbarInsets(mContext);
if (position == POSITION_RIGHT) {
return left + mContentWidth - navBarInsets.right;
} else if (position == POSITION_LEFT) {
return left + mContentWidth - navBarInsets.left;
}
}
return left + mContentWidth;
}
private int getBottomBound(int top) {
if (!mUseFullScreen) {
final Insets navBarInsets = Utils.getNavbarInsets(mContext);
return Math.min(top + mContentHeight - navBarInsets.bottom,
mContainerHeight - mMargin - navBarInsets.bottom);
}
return Math.min(top + mContentHeight, mContainerHeight - mMargin);
}
private int getTopBound(@Position int position) {
switch (position) {
case POSITION_BOTTOM:
@@ -113,6 +138,10 @@ public class AuthPanelController extends ViewOutlineProvider {
mPosition = position;
}
public @Position int getPosition() {
return mPosition;
}
public void setUseFullScreen(boolean fullScreen) {
mUseFullScreen = fullScreen;
}

View File

@@ -26,13 +26,16 @@ import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.Insets
import android.hardware.biometrics.BiometricManager.Authenticators
import android.hardware.biometrics.PromptInfo
import android.hardware.biometrics.SensorPropertiesInternal
import android.os.UserManager
import android.util.DisplayMetrics
import android.view.ViewGroup
import android.view.WindowInsets
import android.view.WindowManager
import android.view.WindowMetrics
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityManager
import com.android.internal.widget.LockPatternUtils
@@ -114,6 +117,14 @@ object Utils {
return hasPermission && "android" == clientPackage
}
@JvmStatic
fun getNavbarInsets(context: Context): Insets {
val windowManager: WindowManager? = context.getSystemService(WindowManager::class.java)
val windowMetrics: WindowMetrics? = windowManager?.maximumWindowMetrics
return windowMetrics?.windowInsets?.getInsets(WindowInsets.Type.navigationBars())
?: Insets.NONE
}
@Retention(RetentionPolicy.SOURCE)
@IntDef(CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD)
internal annotation class CredentialType

View File

@@ -504,6 +504,21 @@ class AuthContainerViewTest : SysuiTestCase() {
waitForIdleSync()
assertThat(isAttachedToWindow()).isTrue()
}
@Test
fun testLayoutParams_hasCutoutModeAlwaysFlag() {
val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
val lpFlags = layoutParams.flags
assertThat((lpFlags and WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS)
!= 0).isTrue()
}
@Test
fun testLayoutParams_excludesSystemBarInsets() {
val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.systemBars()) == 0).isTrue()
}
}
private fun AuthContainerView.hasBiometricPrompt() =