diff options
author | 2024-08-08 19:22:53 +0000 | |
---|---|---|
committer | 2024-08-08 19:22:53 +0000 | |
commit | e5246ed9e3e6709d8d8cc521cd7357682b05148a (patch) | |
tree | 50828a859622cb24f654de22d82a297075df3e5a | |
parent | fb43a64675ba9617c0e79be106166929102208f5 (diff) |
Remove ConstraintBp Flag
Test: atest com.android.systemui.biometrics
Bug: 288175072
Flag: EXEMPT removing com.android.systemui.constraint_bp
Change-Id: I9b4de37a46ed3ee5ab6f3231db1adedf3b7766a5
22 files changed, 371 insertions, 2174 deletions
diff --git a/packages/SystemUI/aconfig/biometrics_framework.aconfig b/packages/SystemUI/aconfig/biometrics_framework.aconfig index e81d5d5ece5a..95e4b593a72f 100644 --- a/packages/SystemUI/aconfig/biometrics_framework.aconfig +++ b/packages/SystemUI/aconfig/biometrics_framework.aconfig @@ -3,9 +3,3 @@ container: "system" # NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors. -flag { - name: "constraint_bp" - namespace: "biometrics_framework" - description: "Refactors Biometric Prompt to use a ConstraintLayout" - bug: "288175072" -} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java index 9b1d4eca8b2b..752c93e077ac 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/AuthControllerTest.java @@ -148,8 +148,6 @@ public class AuthControllerTest extends SysuiTestCase { @Mock private WakefulnessLifecycle mWakefulnessLifecycle; @Mock - private AuthDialogPanelInteractionDetector mPanelInteractionDetector; - @Mock private UserManager mUserManager; @Mock private LockPatternUtils mLockPatternUtils; @@ -1059,10 +1057,9 @@ public class AuthControllerTest extends SysuiTestCase { super(context, null /* applicationCoroutineScope */, mExecution, mCommandQueue, mActivityTaskManager, mWindowManager, mFingerprintManager, mFaceManager, () -> mUdfpsController, mDisplayManager, - mWakefulnessLifecycle, mPanelInteractionDetector, mUserManager, - mLockPatternUtils, () -> mUdfpsLogger, () -> mLogContextInteractor, - () -> mPromptSelectionInteractor, () -> mCredentialViewModel, - () -> mPromptViewModel, mInteractionJankMonitor, + mWakefulnessLifecycle, mUserManager, mLockPatternUtils, () -> mUdfpsLogger, + () -> mLogContextInteractor, () -> mPromptSelectionInteractor, + () -> mCredentialViewModel, () -> mPromptViewModel, mInteractionJankMonitor, mHandler, mBackgroundExecutor, mUdfpsUtils, mVibratorHelper); } @@ -1071,7 +1068,6 @@ public class AuthControllerTest extends SysuiTestCase { boolean requireConfirmation, int userId, int[] sensorIds, String opPackageName, boolean skipIntro, long operationId, long requestId, WakefulnessLifecycle wakefulnessLifecycle, - AuthDialogPanelInteractionDetector panelInteractionDetector, UserManager userManager, LockPatternUtils lockPatternUtils, PromptViewModel viewModel) { diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java deleted file mode 100644 index cd9189bef7f1..000000000000 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2021 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.systemui.biometrics; - -import static org.junit.Assert.assertEquals; - -import android.hardware.biometrics.ComponentInfoInternal; -import android.hardware.biometrics.SensorLocationInternal; -import android.hardware.biometrics.SensorProperties; -import android.hardware.fingerprint.FingerprintSensorProperties; -import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.systemui.SysuiTestCase; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class UdfpsDialogMeasureAdapterTest extends SysuiTestCase { - @Test - public void testUdfpsBottomSpacerHeightForPortrait() { - final int displayHeightPx = 3000; - final int navbarHeightPx = 10; - final int dialogBottomMarginPx = 20; - final int buttonBarHeightPx = 100; - final int textIndicatorHeightPx = 200; - - final int sensorLocationX = 540; - final int sensorLocationY = 1600; - final int sensorRadius = 100; - - final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); - componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */, - "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */, - "00000001" /* serialNumber */, "" /* softwareVersion */)); - componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */, - "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */, - "vendor/version/revision" /* softwareVersion */)); - - final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal( - 0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, - componentInfo, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, - true /* halControlsIllumination */, - true /* resetLockoutRequiresHardwareAuthToken */, - List.of(new SensorLocationInternal("" /* displayId */, - sensorLocationX, sensorLocationY, sensorRadius))); - - assertEquals(970, - UdfpsDialogMeasureAdapter.calculateBottomSpacerHeightForPortrait( - props, displayHeightPx, textIndicatorHeightPx, buttonBarHeightPx, - dialogBottomMarginPx, navbarHeightPx, 1.0f /* resolutionScale */ - )); - } - - @Test - public void testUdfpsBottomSpacerHeightForLandscape_whenMoreSpaceAboveIcon() { - final int titleHeightPx = 320; - final int subtitleHeightPx = 240; - final int descriptionHeightPx = 200; - final int topSpacerHeightPx = 550; - final int textIndicatorHeightPx = 190; - final int buttonBarHeightPx = 160; - final int navbarBottomInsetPx = 75; - - assertEquals(885, - UdfpsDialogMeasureAdapter.calculateBottomSpacerHeightForLandscape( - titleHeightPx, subtitleHeightPx, descriptionHeightPx, topSpacerHeightPx, - textIndicatorHeightPx, buttonBarHeightPx, navbarBottomInsetPx)); - } - - @Test - public void testUdfpsBottomSpacerHeightForLandscape_whenMoreSpaceBelowIcon() { - final int titleHeightPx = 315; - final int subtitleHeightPx = 160; - final int descriptionHeightPx = 75; - final int topSpacerHeightPx = 220; - final int textIndicatorHeightPx = 290; - final int buttonBarHeightPx = 360; - final int navbarBottomInsetPx = 205; - - assertEquals(-85, - UdfpsDialogMeasureAdapter.calculateBottomSpacerHeightForLandscape( - titleHeightPx, subtitleHeightPx, descriptionHeightPx, topSpacerHeightPx, - textIndicatorHeightPx, buttonBarHeightPx, navbarBottomInsetPx)); - } - - @Test - public void testUdfpsHorizontalSpacerWidthForLandscape() { - final int displayWidthPx = 3000; - final int dialogMarginPx = 20; - final int navbarHorizontalInsetPx = 75; - - final int sensorLocationX = 540; - final int sensorLocationY = 1600; - final int sensorRadius = 100; - - final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); - componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */, - "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */, - "00000001" /* serialNumber */, "" /* softwareVersion */)); - componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */, - "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */, - "vendor/version/revision" /* softwareVersion */)); - - final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal( - 0 /* sensorId */, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, - componentInfo, - FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, - true /* halControlsIllumination */, - true /* resetLockoutRequiresHardwareAuthToken */, - List.of(new SensorLocationInternal("" /* displayId */, - sensorLocationX, sensorLocationY, sensorRadius))); - - assertEquals(1205, - UdfpsDialogMeasureAdapter.calculateHorizontalSpacerWidthForLandscape( - props, displayWidthPx, dialogMarginPx, navbarHorizontalInsetPx, - 1.0f /* resolutionScale */)); - } -} diff --git a/packages/SystemUI/res/layout/biometric_prompt_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_layout.xml deleted file mode 100644 index ff89ed9e6e7a..000000000000 --- a/packages/SystemUI/res/layout/biometric_prompt_layout.xml +++ /dev/null @@ -1,208 +0,0 @@ -<!-- - ~ 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. - --> -<com.android.systemui.biometrics.ui.BiometricPromptLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/contents" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical"> - - <ImageView - android:id="@+id/logo" - android:layout_width="@dimen/biometric_auth_icon_size" - android:layout_height="@dimen/biometric_auth_icon_size" - android:layout_gravity="center" - android:scaleType="fitXY"/> - - <TextView - android:id="@+id/logo_description" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="@integer/biometric_dialog_text_gravity" - android:singleLine="true" - android:marqueeRepeatLimit="1" - android:ellipsize="marquee"/> - - <TextView - android:id="@+id/title" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="@integer/biometric_dialog_text_gravity" - android:singleLine="true" - android:marqueeRepeatLimit="1" - android:ellipsize="marquee" - style="@style/TextAppearance.AuthCredential.OldTitle"/> - - <TextView - android:id="@+id/subtitle" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="@integer/biometric_dialog_text_gravity" - android:singleLine="true" - android:marqueeRepeatLimit="1" - android:ellipsize="marquee" - style="@style/TextAppearance.AuthCredential.OldSubtitle"/> - - <TextView - android:id="@+id/description" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:gravity="@integer/biometric_dialog_text_gravity" - android:scrollbars ="vertical" - android:importantForAccessibility="no" - style="@style/TextAppearance.AuthCredential.OldDescription"/> - - <Space - android:id="@+id/space_above_content" - android:layout_width="match_parent" - android:layout_height="24dp" - android:visibility="gone" /> - - <LinearLayout - android:id="@+id/customized_view_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:fadeScrollbars="false" - android:gravity="center_vertical" - android:orientation="vertical" - android:scrollbars="vertical" - android:visibility="gone" /> - - <Space android:id="@+id/space_above_icon" - android:layout_width="match_parent" - android:layout_height="48dp" /> - - <FrameLayout - android:id="@+id/biometric_icon_frame" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center"> - - <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper - android:id="@+id/biometric_icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:contentDescription="@null" - android:scaleType="fitXY" /> - - <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper - android:id="@+id/biometric_icon_overlay" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:contentDescription="@null" - android:scaleType="fitXY" /> - </FrameLayout> - - <!-- For sensors such as UDFPS, this view is used during custom measurement/layout to add extra - padding so that the biometric icon is always in the right physical position. --> - <Space android:id="@+id/space_below_icon" - android:layout_width="match_parent" - android:layout_height="12dp" /> - - <TextView - android:id="@+id/indicator" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingHorizontal="24dp" - android:textSize="12sp" - android:gravity="center_horizontal" - android:accessibilityLiveRegion="polite" - android:singleLine="true" - android:ellipsize="marquee" - android:marqueeRepeatLimit="marquee_forever" - android:scrollHorizontally="true" - android:fadingEdge="horizontal" - android:textColor="@color/biometric_dialog_gray"/> - - <LinearLayout - android:id="@+id/button_bar" - android:layout_width="match_parent" - android:layout_height="88dp" - style="?android:attr/buttonBarStyle" - android:orientation="horizontal" - android:paddingTop="24dp"> - - <Space android:id="@+id/leftSpacer" - android:layout_width="8dp" - android:layout_height="match_parent" - android:visibility="visible" /> - - <!-- Negative Button, reserved for app --> - <Button android:id="@+id/button_negative" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" - android:layout_gravity="center_vertical" - android:ellipsize="end" - android:maxLines="2" - android:maxWidth="@dimen/biometric_dialog_button_negative_max_width" - android:visibility="gone"/> - <!-- Cancel Button, replaces negative button when biometric is accepted --> - <Button android:id="@+id/button_cancel" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" - android:layout_gravity="center_vertical" - android:maxWidth="@dimen/biometric_dialog_button_negative_max_width" - android:text="@string/cancel" - android:visibility="gone"/> - <!-- "Use Credential" Button, replaces if device credential is allowed --> - <Button android:id="@+id/button_use_credential" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored" - android:layout_gravity="center_vertical" - android:maxWidth="@dimen/biometric_dialog_button_negative_max_width" - android:visibility="gone"/> - - <Space android:id="@+id/middleSpacer" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:visibility="visible"/> - - <!-- Positive Button --> - <Button android:id="@+id/button_confirm" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - style="@*android:style/Widget.DeviceDefault.Button.Colored" - android:layout_gravity="center_vertical" - android:ellipsize="end" - android:maxLines="2" - android:maxWidth="@dimen/biometric_dialog_button_positive_max_width" - android:text="@string/biometric_dialog_confirm" - android:visibility="gone"/> - <!-- Try Again Button --> - <Button android:id="@+id/button_try_again" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - style="@*android:style/Widget.DeviceDefault.Button.Colored" - android:layout_gravity="center_vertical" - android:ellipsize="end" - android:maxLines="2" - android:maxWidth="@dimen/biometric_dialog_button_positive_max_width" - android:text="@string/biometric_dialog_try_again" - android:visibility="gone"/> - - <Space android:id="@+id/rightSpacer" - android:layout_width="8dp" - android:layout_height="match_parent" - android:visibility="visible" /> - </LinearLayout> - -</com.android.systemui.biometrics.ui.BiometricPromptLayout> diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 9521be1f11a7..aed3c109abc5 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -17,11 +17,9 @@ package com.android.systemui.biometrics; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; -import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.internal.jank.InteractionJankMonitor.CUJ_BIOMETRIC_PROMPT_TRANSITION; -import static com.android.systemui.Flags.constraintBp; import android.animation.Animator; import android.annotation.IntDef; @@ -30,8 +28,6 @@ import android.annotation.Nullable; import android.app.AlertDialog; import android.content.Context; import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.graphics.Color; import android.graphics.PixelFormat; import android.hardware.biometrics.BiometricAuthenticator.Modality; import android.hardware.biometrics.BiometricConstants; @@ -41,17 +37,11 @@ import android.hardware.biometrics.PromptInfo; import android.hardware.face.FaceSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; -import android.os.Looper; import android.os.UserManager; import android.util.Log; -import android.view.Display; -import android.view.DisplayInfo; -import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; -import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; @@ -60,7 +50,6 @@ import android.view.animation.Interpolator; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.ScrollView; import android.window.OnBackInvokedCallback; import android.window.OnBackInvokedDispatcher; @@ -74,7 +63,6 @@ import com.android.systemui.biometrics.AuthController.ScaleFactorProvider; import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor; import com.android.systemui.biometrics.shared.model.BiometricModalities; import com.android.systemui.biometrics.shared.model.PromptKind; -import com.android.systemui.biometrics.ui.BiometricPromptLayout; import com.android.systemui.biometrics.ui.CredentialView; import com.android.systemui.biometrics.ui.binder.BiometricViewBinder; import com.android.systemui.biometrics.ui.binder.BiometricViewSizeBinder; @@ -111,7 +99,6 @@ public class AuthContainerView extends LinearLayout private static final int ANIMATION_DURATION_SHOW_MS = 250; private static final int ANIMATION_DURATION_AWAY_MS = 350; - private static final int ANIMATE_CREDENTIAL_START_DELAY_MS = 300; private static final int STATE_UNKNOWN = 0; private static final int STATE_ANIMATING_IN = 1; @@ -136,13 +123,11 @@ public class AuthContainerView extends LinearLayout private final Config mConfig; private final int mEffectiveUserId; - private final Handler mHandler; private final IBinder mWindowToken = new Binder(); private final WindowManager mWindowManager; private final Interpolator mLinearOutSlowIn; private final LockPatternUtils mLockPatternUtils; private final WakefulnessLifecycle mWakefulnessLifecycle; - private final AuthDialogPanelInteractionDetector mPanelInteractionDetector; private final InteractionJankMonitor mInteractionJankMonitor; private final CoroutineScope mApplicationCoroutineScope; @@ -159,10 +144,7 @@ public class AuthContainerView extends LinearLayout private final AuthPanelController mPanelController; private final ViewGroup mLayout; private final ImageView mBackgroundView; - private final ScrollView mBiometricScrollView; private final View mPanelView; - private final List<FingerprintSensorPropertiesInternal> mFpProps; - private final List<FaceSensorPropertiesInternal> mFaceProps; private final float mTranslationY; @VisibleForTesting @ContainerState int mContainerState = STATE_UNKNOWN; private final Set<Integer> mFailedModalities = new HashSet<Integer>(); @@ -229,13 +211,7 @@ public class AuthContainerView extends LinearLayout @Override public void onUseDeviceCredential() { mConfig.mCallback.onDeviceCredentialPressed(getRequestId()); - if (constraintBp()) { - addCredentialView(false /* animatePanel */, true /* animateContents */); - } else { - mHandler.postDelayed(() -> { - addCredentialView(false /* animatePanel */, true /* animateContents */); - }, mConfig.mSkipAnimation ? 0 : ANIMATE_CREDENTIAL_START_DELAY_MS); - } + addCredentialView(false /* animatePanel */, true /* animateContents */); // TODO(b/313469218): Remove Config mConfig.mPromptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL); @@ -303,36 +279,12 @@ public class AuthContainerView extends LinearLayout @Nullable List<FingerprintSensorPropertiesInternal> fpProps, @Nullable List<FaceSensorPropertiesInternal> faceProps, @NonNull WakefulnessLifecycle wakefulnessLifecycle, - @NonNull AuthDialogPanelInteractionDetector panelInteractionDetector, - @NonNull UserManager userManager, - @NonNull LockPatternUtils lockPatternUtils, - @NonNull InteractionJankMonitor jankMonitor, - @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractor, - @NonNull PromptViewModel promptViewModel, - @NonNull Provider<CredentialViewModel> credentialViewModelProvider, - @NonNull @Background DelayableExecutor bgExecutor, - @NonNull VibratorHelper vibratorHelper) { - this(config, applicationCoroutineScope, fpProps, faceProps, - wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils, - jankMonitor, promptSelectorInteractor, promptViewModel, - credentialViewModelProvider, new Handler(Looper.getMainLooper()), bgExecutor, - vibratorHelper); - } - - @VisibleForTesting - AuthContainerView(@NonNull Config config, - @NonNull CoroutineScope applicationCoroutineScope, - @Nullable List<FingerprintSensorPropertiesInternal> fpProps, - @Nullable List<FaceSensorPropertiesInternal> faceProps, - @NonNull WakefulnessLifecycle wakefulnessLifecycle, - @NonNull AuthDialogPanelInteractionDetector panelInteractionDetector, @NonNull UserManager userManager, @NonNull LockPatternUtils lockPatternUtils, @NonNull InteractionJankMonitor jankMonitor, @NonNull Provider<PromptSelectorInteractor> promptSelectorInteractorProvider, @NonNull PromptViewModel promptViewModel, @NonNull Provider<CredentialViewModel> credentialViewModelProvider, - @NonNull Handler mainHandler, @NonNull @Background DelayableExecutor bgExecutor, @NonNull VibratorHelper vibratorHelper) { super(config.mContext); @@ -340,10 +292,8 @@ public class AuthContainerView extends LinearLayout mConfig = config; mLockPatternUtils = lockPatternUtils; mEffectiveUserId = userManager.getCredentialOwnerProfile(mConfig.mUserId); - mHandler = mainHandler; mWindowManager = mContext.getSystemService(WindowManager.class); mWakefulnessLifecycle = wakefulnessLifecycle; - mPanelInteractionDetector = panelInteractionDetector; mApplicationCoroutineScope = applicationCoroutineScope; mPromptViewModel = promptViewModel; @@ -352,8 +302,6 @@ public class AuthContainerView extends LinearLayout mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN; mBiometricCallback = new BiometricCallback(); - mFpProps = fpProps; - mFaceProps = faceProps; final BiometricModalities biometricModalities = new BiometricModalities( Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds)); @@ -367,7 +315,7 @@ public class AuthContainerView extends LinearLayout final LayoutInflater layoutInflater = LayoutInflater.from(mContext); final PromptKind kind = mPromptViewModel.getPromptKind().getValue(); - if (constraintBp() && kind.isBiometric()) { + if (kind.isBiometric()) { if (kind.isTwoPaneLandscapeBiometric()) { mLayout = (ConstraintLayout) layoutInflater.inflate( R.layout.biometric_prompt_two_pane_layout, this, false /* attachToRoot */); @@ -379,26 +327,16 @@ public class AuthContainerView extends LinearLayout mLayout = (FrameLayout) layoutInflater.inflate( R.layout.auth_container_view, this, false /* attachToRoot */); } - mBiometricScrollView = mLayout.findViewById(R.id.biometric_scrollview); addView(mLayout); mBackgroundView = mLayout.findViewById(R.id.background); mPanelView = mLayout.findViewById(R.id.panel); - if (!constraintBp()) { - final TypedArray ta = mContext.obtainStyledAttributes(new int[]{ - android.R.attr.colorBackgroundFloating}); - mPanelView.setBackgroundColor(ta.getColor(0, Color.WHITE)); - ta.recycle(); - } mPanelController = new AuthPanelController(mContext, mPanelView); mBackgroundExecutor = bgExecutor; mInteractionJankMonitor = jankMonitor; mCredentialViewModelProvider = credentialViewModelProvider; - showPrompt(config, layoutInflater, promptViewModel, - Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds), - Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds), - vibratorHelper); + showPrompt(promptViewModel, vibratorHelper); // TODO: De-dupe the logic with AuthCredentialPasswordView setOnKeyListener((v, keyCode, event) -> { @@ -415,52 +353,25 @@ public class AuthContainerView extends LinearLayout requestFocus(); } - private void showPrompt(@NonNull Config config, @NonNull LayoutInflater layoutInflater, - @NonNull PromptViewModel viewModel, - @Nullable FingerprintSensorPropertiesInternal fpProps, - @Nullable FaceSensorPropertiesInternal faceProps, - @NonNull VibratorHelper vibratorHelper - ) { + private void showPrompt(@NonNull PromptViewModel viewModel, + @NonNull VibratorHelper vibratorHelper) { if (mPromptViewModel.getPromptKind().getValue().isBiometric()) { - addBiometricView(config, layoutInflater, viewModel, fpProps, faceProps, vibratorHelper); + addBiometricView(viewModel, vibratorHelper); } else if (mPromptViewModel.getPromptKind().getValue().isCredential()) { - if (constraintBp()) { - addCredentialView(true, false); - } + addCredentialView(true, false); } else { mPromptSelectorInteractorProvider.get().resetPrompt(getRequestId()); } } - private void addBiometricView(@NonNull Config config, @NonNull LayoutInflater layoutInflater, - @NonNull PromptViewModel viewModel, - @Nullable FingerprintSensorPropertiesInternal fpProps, - @Nullable FaceSensorPropertiesInternal faceProps, + private void addBiometricView(@NonNull PromptViewModel viewModel, @NonNull VibratorHelper vibratorHelper) { - - if (constraintBp()) { - mBiometricView = BiometricViewBinder.bind(mLayout, viewModel, null, - // TODO(b/201510778): This uses the wrong timeout in some cases - getJankListener(mLayout, TRANSIT, - BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), - mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, - vibratorHelper); - } else { - final BiometricPromptLayout view = (BiometricPromptLayout) layoutInflater.inflate( - R.layout.biometric_prompt_layout, null, false); - mBiometricView = BiometricViewBinder.bind(view, viewModel, mPanelController, - // TODO(b/201510778): This uses the wrong timeout in some cases - getJankListener(view, TRANSIT, - BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), - mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, - vibratorHelper); - - // TODO(b/251476085): migrate these dependencies - if (fpProps != null && fpProps.isAnyUdfpsType()) { - view.setUdfpsAdapter(new UdfpsDialogMeasureAdapter(view, fpProps), - config.mScaleProvider); - } - } + mBiometricView = BiometricViewBinder.bind(mLayout, viewModel, + // TODO(b/201510778): This uses the wrong timeout in some cases + getJankListener(mLayout, TRANSIT, + BiometricViewSizeBinder.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS), + mBackgroundView, mBiometricCallback, mApplicationCoroutineScope, + vibratorHelper); } @VisibleForTesting @@ -524,9 +435,6 @@ public class AuthContainerView extends LinearLayout @Override public void onOrientationChanged() { - if (!constraintBp()) { - updatePositionByCapability(true /* invalidate */); - } } @Override @@ -538,23 +446,6 @@ public class AuthContainerView extends LinearLayout } mWakefulnessLifecycle.addObserver(this); - if (constraintBp()) { - // Do nothing on attachment with constraintLayout - } else if (mPromptViewModel.getPromptKind().getValue().isBiometric()) { - mBiometricScrollView.addView(mBiometricView.asView()); - } else if (mPromptViewModel.getPromptKind().getValue().isCredential()) { - addCredentialView(true /* animatePanel */, false /* animateContents */); - } else { - throw new IllegalStateException("Unknown configuration: " - + mConfig.mPromptInfo.getAuthenticators()); - } - - if (!constraintBp()) { - mPanelInteractionDetector.enable( - () -> animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED)); - updatePositionByCapability(false /* invalidate */); - } - if (mConfig.mSkipIntro) { mContainerState = STATE_SHOWING; } else { @@ -618,120 +509,8 @@ public class AuthContainerView extends LinearLayout }; } - private void updatePositionByCapability(boolean forceInvalidate) { - final FingerprintSensorPropertiesInternal fpProp = Utils.findFirstSensorProperties( - mFpProps, mConfig.mSensorIds); - final FaceSensorPropertiesInternal faceProp = Utils.findFirstSensorProperties( - mFaceProps, mConfig.mSensorIds); - if (fpProp != null && fpProp.isAnyUdfpsType()) { - maybeUpdatePositionForUdfps(forceInvalidate /* invalidate */); - } - if (faceProp != null && mBiometricView != null && mBiometricView.isFaceOnly()) { - alwaysUpdatePositionAtScreenBottom(forceInvalidate /* invalidate */); - } - if (fpProp != null && fpProp.sensorType == TYPE_POWER_BUTTON) { - alwaysUpdatePositionAtScreenBottom(forceInvalidate /* invalidate */); - } - } - - private static boolean shouldUpdatePositionForUdfps(@NonNull View view) { - if (view instanceof BiometricPromptLayout) { - // this will force the prompt to align itself on the edge of the screen - // instead of centering (temporary workaround to prevent small implicit view - // from breaking due to the way gravity / margins are set in the legacy - // AuthPanelController - return true; - } - - return false; - } - - private boolean maybeUpdatePositionForUdfps(boolean invalidate) { - final Display display = getDisplay(); - if (display == null) { - return false; - } - - final DisplayInfo cachedDisplayInfo = new DisplayInfo(); - display.getDisplayInfo(cachedDisplayInfo); - if (mBiometricView == null || !shouldUpdatePositionForUdfps(mBiometricView.asView())) { - return false; - } - - final int displayRotation = cachedDisplayInfo.rotation; - switch (displayRotation) { - case Surface.ROTATION_0: - mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM); - setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - break; - - case Surface.ROTATION_90: - mPanelController.setPosition(AuthPanelController.POSITION_RIGHT); - setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT); - break; - - case Surface.ROTATION_270: - mPanelController.setPosition(AuthPanelController.POSITION_LEFT); - setScrollViewGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); - break; - - case Surface.ROTATION_180: - default: - Log.e(TAG, "Unsupported display rotation: " + displayRotation); - mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM); - setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - break; - } - - if (invalidate) { - mPanelView.invalidateOutline(); - } - - return true; - } - - private boolean alwaysUpdatePositionAtScreenBottom(boolean invalidate) { - final Display display = getDisplay(); - if (display == null) { - return false; - } - if (mBiometricView == null || !shouldUpdatePositionForUdfps(mBiometricView.asView())) { - return false; - } - - final int displayRotation = display.getRotation(); - switch (displayRotation) { - case Surface.ROTATION_0: - case Surface.ROTATION_90: - case Surface.ROTATION_270: - case Surface.ROTATION_180: - mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM); - setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - break; - default: - Log.e(TAG, "Unsupported display rotation: " + displayRotation); - mPanelController.setPosition(AuthPanelController.POSITION_BOTTOM); - setScrollViewGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); - break; - } - - if (invalidate) { - mPanelView.invalidateOutline(); - } - - return true; - } - - private void setScrollViewGravity(int gravity) { - final FrameLayout.LayoutParams params = - (FrameLayout.LayoutParams) mBiometricScrollView.getLayoutParams(); - params.gravity = gravity; - mBiometricScrollView.setLayoutParams(params); - } - @Override public void onDetachedFromWindow() { - mPanelInteractionDetector.disable(); OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher(); if (dispatcher != null) { findOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mBackCallback); @@ -878,7 +657,7 @@ public class AuthContainerView extends LinearLayout final Runnable endActionRunnable = () -> { setVisibility(View.INVISIBLE); - if (Flags.customBiometricPrompt() && constraintBp()) { + if (Flags.customBiometricPrompt()) { // TODO(b/288175645): resetPrompt calls should be lifecycle aware mPromptSelectorInteractorProvider.get().resetPrompt(getRequestId()); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index b466f31cc509..736400e1f719 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -173,7 +173,6 @@ public class AuthController implements @NonNull private final SparseBooleanArray mSfpsEnrolledForUser; @NonNull private final SensorPrivacyManager mSensorPrivacyManager; private final WakefulnessLifecycle mWakefulnessLifecycle; - private final AuthDialogPanelInteractionDetector mPanelInteractionDetector; private boolean mAllFingerprintAuthenticatorsRegistered; @NonNull private final UserManager mUserManager; @NonNull private final LockPatternUtils mLockPatternUtils; @@ -728,7 +727,6 @@ public class AuthController implements Provider<UdfpsController> udfpsControllerFactory, @NonNull DisplayManager displayManager, @NonNull WakefulnessLifecycle wakefulnessLifecycle, - @NonNull AuthDialogPanelInteractionDetector panelInteractionDetector, @NonNull UserManager userManager, @NonNull LockPatternUtils lockPatternUtils, @NonNull Lazy<UdfpsLogger> udfpsLogger, @@ -779,7 +777,6 @@ public class AuthController implements }); mWakefulnessLifecycle = wakefulnessLifecycle; - mPanelInteractionDetector = panelInteractionDetector; mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null; @@ -1229,7 +1226,6 @@ public class AuthController implements operationId, requestId, mWakefulnessLifecycle, - mPanelInteractionDetector, mUserManager, mLockPatternUtils, viewModel); @@ -1306,7 +1302,6 @@ public class AuthController implements PromptInfo promptInfo, boolean requireConfirmation, int userId, int[] sensorIds, String opPackageName, boolean skipIntro, long operationId, long requestId, @NonNull WakefulnessLifecycle wakefulnessLifecycle, - @NonNull AuthDialogPanelInteractionDetector panelInteractionDetector, @NonNull UserManager userManager, @NonNull LockPatternUtils lockPatternUtils, @NonNull PromptViewModel viewModel) { @@ -1323,7 +1318,7 @@ public class AuthController implements config.mSensorIds = sensorIds; config.mScaleProvider = this::getScaleFactor; return new AuthContainerView(config, mApplicationCoroutineScope, mFpProps, mFaceProps, - wakefulnessLifecycle, panelInteractionDetector, userManager, lockPatternUtils, + wakefulnessLifecycle, userManager, lockPatternUtils, mInteractionJankMonitor, mPromptSelectorInteractor, viewModel, mCredentialViewModelProvider, bgExecutor, mVibratorHelper); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt deleted file mode 100644 index 04c2351c1a3e..000000000000 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetector.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 com.android.systemui.biometrics - -import android.annotation.MainThread -import android.util.Log -import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.shade.domain.interactor.ShadeInteractor -import dagger.Lazy -import javax.inject.Inject -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.launch - -class AuthDialogPanelInteractionDetector -@Inject -constructor( - @Application private val scope: CoroutineScope, - private val shadeInteractorLazy: Lazy<ShadeInteractor>, -) { - private var shadeExpansionCollectorJob: Job? = null - - @MainThread - fun enable(onShadeInteraction: Runnable) { - if (shadeExpansionCollectorJob != null) { - Log.e(TAG, "Already enabled") - return - } - //TODO(b/313957306) delete this check - if (shadeInteractorLazy.get().isUserInteracting.value) { - // Workaround for b/311266890. This flow is in an error state that breaks this. - Log.e(TAG, "isUserInteracting already true, skipping enable") - return - } - shadeExpansionCollectorJob = - scope.launch { - Log.i(TAG, "Enable detector") - // wait for it to emit true once - shadeInteractorLazy.get().isUserInteracting.first { it } - Log.i(TAG, "Detector detected shade interaction") - onShadeInteraction.run() - } - shadeExpansionCollectorJob?.invokeOnCompletion { shadeExpansionCollectorJob = null } - } - - @MainThread - fun disable() { - Log.i(TAG, "Disable detector") - shadeExpansionCollectorJob?.cancel() - } -} - -private const val TAG = "AuthDialogPanelInteractionDetector" diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java deleted file mode 100644 index 02eae9cedf74..000000000000 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapter.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (C) 2021 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.systemui.biometrics; - -import android.annotation.IdRes; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.graphics.Insets; -import android.graphics.Rect; -import android.hardware.biometrics.SensorLocationInternal; -import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; -import android.os.Build; -import android.util.Log; -import android.view.Surface; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewGroup; -import android.view.WindowInsets; -import android.view.WindowManager; -import android.view.WindowMetrics; -import android.widget.FrameLayout; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.res.R; - -/** - * Adapter that remeasures an auth dialog view to ensure that it matches the location of a physical - * under-display fingerprint sensor (UDFPS). - */ -public class UdfpsDialogMeasureAdapter { - private static final String TAG = "UdfpsDialogMeasurementAdapter"; - private static final boolean DEBUG = Build.IS_USERDEBUG || Build.IS_ENG; - - @NonNull private final ViewGroup mView; - @NonNull private final FingerprintSensorPropertiesInternal mSensorProps; - @Nullable private WindowManager mWindowManager; - private int mBottomSpacerHeight; - - public UdfpsDialogMeasureAdapter( - @NonNull ViewGroup view, @NonNull FingerprintSensorPropertiesInternal sensorProps) { - mView = view; - mSensorProps = sensorProps; - mWindowManager = mView.getContext().getSystemService(WindowManager.class); - } - - @NonNull - FingerprintSensorPropertiesInternal getSensorProps() { - return mSensorProps; - } - - @NonNull - public AuthDialog.LayoutParams onMeasureInternal( - int width, int height, @NonNull AuthDialog.LayoutParams layoutParams, - float scaleFactor) { - - final int displayRotation = mView.getDisplay().getRotation(); - switch (displayRotation) { - case Surface.ROTATION_0: - return onMeasureInternalPortrait(width, height, scaleFactor); - case Surface.ROTATION_90: - case Surface.ROTATION_270: - return onMeasureInternalLandscape(width, height, scaleFactor); - default: - Log.e(TAG, "Unsupported display rotation: " + displayRotation); - return layoutParams; - } - } - - /** - * @return the actual (and possibly negative) bottom spacer height. If negative, this indicates - * that the UDFPS sensor is too low. Our current xml and custom measurement logic is very hard - * too cleanly support this case. So, let's have the onLayout code translate the sensor location - * instead. - */ - public int getBottomSpacerHeight() { - return mBottomSpacerHeight; - } - - /** - * @return sensor diameter size as scaleFactor - */ - public int getSensorDiameter(float scaleFactor) { - return (int) (scaleFactor * mSensorProps.getLocation().sensorRadius * 2); - } - - @NonNull - private AuthDialog.LayoutParams onMeasureInternalPortrait(int width, int height, - float scaleFactor) { - final WindowMetrics windowMetrics = mWindowManager.getMaximumWindowMetrics(); - - // Figure out where the bottom of the sensor anim should be. - final int textIndicatorHeight = getViewHeightPx(R.id.indicator); - final int buttonBarHeight = getViewHeightPx(R.id.button_bar); - final int dialogMargin = getDialogMarginPx(); - final int displayHeight = getMaximumWindowBounds(windowMetrics).height(); - final Insets navbarInsets = getNavbarInsets(windowMetrics); - mBottomSpacerHeight = calculateBottomSpacerHeightForPortrait( - mSensorProps, displayHeight, textIndicatorHeight, buttonBarHeight, - dialogMargin, navbarInsets.bottom, scaleFactor); - - // Go through each of the children and do the custom measurement. - int totalHeight = 0; - final int numChildren = mView.getChildCount(); - final int sensorDiameter = getSensorDiameter(scaleFactor); - for (int i = 0; i < numChildren; i++) { - final View child = mView.getChildAt(i); - if (child.getId() == R.id.biometric_icon_frame) { - final FrameLayout iconFrame = (FrameLayout) child; - final View icon = iconFrame.getChildAt(0); - // Create a frame that's exactly the height of the sensor circle. - iconFrame.measure( - MeasureSpec.makeMeasureSpec( - child.getLayoutParams().width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY)); - - // Ensure that the icon is never larger than the sensor. - icon.measure( - MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST)); - } else if (child.getId() == R.id.space_above_icon - || child.getId() == R.id.space_above_content - || child.getId() == R.id.button_bar) { - child.measure( - MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec( - child.getLayoutParams().height, MeasureSpec.EXACTLY)); - } else if (child.getId() == R.id.space_below_icon) { - // Set the spacer height so the fingerprint icon is on the physical sensor area - final int clampedSpacerHeight = Math.max(mBottomSpacerHeight, 0); - child.measure( - MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(clampedSpacerHeight, MeasureSpec.EXACTLY)); - } else if (child.getId() == R.id.description - || child.getId() == R.id.customized_view_container) { - //skip description view and compute later - continue; - } else if (child.getId() == R.id.logo) { - child.measure( - MeasureSpec.makeMeasureSpec(child.getLayoutParams().width, - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(child.getLayoutParams().height, - MeasureSpec.EXACTLY)); - } else { - child.measure( - MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)); - } - - if (child.getVisibility() != View.GONE) { - totalHeight += child.getMeasuredHeight(); - } - } - - //re-calculate the height of body content - View description = mView.findViewById(R.id.description); - View contentView = mView.findViewById(R.id.customized_view_container); - if (description != null && description.getVisibility() != View.GONE) { - totalHeight += measureDescription(description, displayHeight, width, totalHeight); - } else if (contentView != null && contentView.getVisibility() != View.GONE) { - totalHeight += measureDescription(contentView, displayHeight, width, totalHeight); - } - - return new AuthDialog.LayoutParams(width, totalHeight); - } - - private int measureDescription(View bodyContent, int displayHeight, int currWidth, - int currHeight) { - int newHeight = bodyContent.getMeasuredHeight() + currHeight; - int limit = (int) (displayHeight * 0.75); - if (newHeight > limit) { - bodyContent.measure( - MeasureSpec.makeMeasureSpec(currWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(limit - currHeight, MeasureSpec.EXACTLY)); - } - return bodyContent.getMeasuredHeight(); - } - - @NonNull - private AuthDialog.LayoutParams onMeasureInternalLandscape(int width, int height, - float scaleFactor) { - final WindowMetrics windowMetrics = mWindowManager.getMaximumWindowMetrics(); - - // Find the spacer height needed to vertically align the icon with the sensor. - final int titleHeight = getViewHeightPx(R.id.title); - final int subtitleHeight = getViewHeightPx(R.id.subtitle); - final int descriptionHeight = getViewHeightPx(R.id.description); - final int topSpacerHeight = getViewHeightPx(R.id.space_above_icon); - final int textIndicatorHeight = getViewHeightPx(R.id.indicator); - final int buttonBarHeight = getViewHeightPx(R.id.button_bar); - - final Insets navbarInsets = getNavbarInsets(windowMetrics); - final int bottomSpacerHeight = calculateBottomSpacerHeightForLandscape(titleHeight, - subtitleHeight, descriptionHeight, topSpacerHeight, textIndicatorHeight, - buttonBarHeight, navbarInsets.bottom); - - // Find the spacer width needed to horizontally align the icon with the sensor. - final int displayWidth = getMaximumWindowBounds(windowMetrics).width(); - final int dialogMargin = getDialogMarginPx(); - final int horizontalInset = navbarInsets.left + navbarInsets.right; - final int horizontalSpacerWidth = calculateHorizontalSpacerWidthForLandscape( - mSensorProps, displayWidth, dialogMargin, horizontalInset, scaleFactor); - - final int sensorDiameter = getSensorDiameter(scaleFactor); - final int remeasuredWidth = sensorDiameter + 2 * horizontalSpacerWidth; - - int remeasuredHeight = 0; - final int numChildren = mView.getChildCount(); - for (int i = 0; i < numChildren; i++) { - final View child = mView.getChildAt(i); - if (child.getId() == R.id.biometric_icon_frame) { - final FrameLayout iconFrame = (FrameLayout) child; - final View icon = iconFrame.getChildAt(0); - // Create a frame that's exactly the height of the sensor circle. - iconFrame.measure( - MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.EXACTLY)); - - // Ensure that the icon is never larger than the sensor. - icon.measure( - MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(sensorDiameter, MeasureSpec.AT_MOST)); - } else if (child.getId() == R.id.space_above_icon) { - // Adjust the width and height of the top spacer if necessary. - final int newTopSpacerHeight = child.getLayoutParams().height - - Math.min(bottomSpacerHeight, 0); - child.measure( - MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(newTopSpacerHeight, MeasureSpec.EXACTLY)); - } else if (child.getId() == R.id.button_bar) { - // Adjust the width of the button bar while preserving its height. - child.measure( - MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec( - child.getLayoutParams().height, MeasureSpec.EXACTLY)); - } else if (child.getId() == R.id.space_below_icon) { - // Adjust the bottom spacer height to align the fingerprint icon with the sensor. - final int newBottomSpacerHeight = Math.max(bottomSpacerHeight, 0); - child.measure( - MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(newBottomSpacerHeight, MeasureSpec.EXACTLY)); - } else { - // Use the remeasured width for all other child views. - child.measure( - MeasureSpec.makeMeasureSpec(remeasuredWidth, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)); - } - - if (child.getVisibility() != View.GONE) { - remeasuredHeight += child.getMeasuredHeight(); - } - } - - return new AuthDialog.LayoutParams(remeasuredWidth, remeasuredHeight); - } - - private int getViewHeightPx(@IdRes int viewId) { - final View view = mView.findViewById(viewId); - return view != null && view.getVisibility() != View.GONE ? view.getMeasuredHeight() : 0; - } - - private int getDialogMarginPx() { - return mView.getResources().getDimensionPixelSize(R.dimen.biometric_dialog_border_padding); - } - - @NonNull - private static Insets getNavbarInsets(@Nullable WindowMetrics windowMetrics) { - return windowMetrics != null - ? windowMetrics.getWindowInsets().getInsets(WindowInsets.Type.navigationBars()) - : Insets.NONE; - } - - @NonNull - private static Rect getMaximumWindowBounds(@Nullable WindowMetrics windowMetrics) { - return windowMetrics != null ? windowMetrics.getBounds() : new Rect(); - } - - /** - * For devices in portrait orientation where the sensor is too high up, calculates the amount of - * padding necessary to center the biometric icon within the sensor's physical location. - */ - @VisibleForTesting - static int calculateBottomSpacerHeightForPortrait( - @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayHeightPx, - int textIndicatorHeightPx, int buttonBarHeightPx, int dialogMarginPx, - int navbarBottomInsetPx, float scaleFactor) { - final SensorLocationInternal location = sensorProperties.getLocation(); - final int sensorDistanceFromBottom = displayHeightPx - - (int) (scaleFactor * location.sensorLocationY) - - (int) (scaleFactor * location.sensorRadius); - - final int spacerHeight = sensorDistanceFromBottom - - textIndicatorHeightPx - - buttonBarHeightPx - - dialogMarginPx - - navbarBottomInsetPx; - - if (DEBUG) { - Log.d(TAG, "Display height: " + displayHeightPx - + ", Distance from bottom: " + sensorDistanceFromBottom - + ", Bottom margin: " + dialogMarginPx - + ", Navbar bottom inset: " + navbarBottomInsetPx - + ", Bottom spacer height (portrait): " + spacerHeight - + ", Scale Factor: " + scaleFactor); - } - - return spacerHeight; - } - - /** - * For devices in landscape orientation where the sensor is too high up, calculates the amount - * of padding necessary to center the biometric icon within the sensor's physical location. - */ - @VisibleForTesting - static int calculateBottomSpacerHeightForLandscape(int titleHeightPx, int subtitleHeightPx, - int descriptionHeightPx, int topSpacerHeightPx, int textIndicatorHeightPx, - int buttonBarHeightPx, int navbarBottomInsetPx) { - - final int dialogHeightAboveIcon = titleHeightPx - + subtitleHeightPx - + descriptionHeightPx - + topSpacerHeightPx; - - final int dialogHeightBelowIcon = textIndicatorHeightPx + buttonBarHeightPx; - - final int bottomSpacerHeight = dialogHeightAboveIcon - - dialogHeightBelowIcon - - navbarBottomInsetPx; - - if (DEBUG) { - Log.d(TAG, "Title height: " + titleHeightPx - + ", Subtitle height: " + subtitleHeightPx - + ", Description height: " + descriptionHeightPx - + ", Top spacer height: " + topSpacerHeightPx - + ", Text indicator height: " + textIndicatorHeightPx - + ", Button bar height: " + buttonBarHeightPx - + ", Navbar bottom inset: " + navbarBottomInsetPx - + ", Bottom spacer height (landscape): " + bottomSpacerHeight); - } - - return bottomSpacerHeight; - } - - /** - * For devices in landscape orientation where the sensor is too left/right, calculates the - * amount of padding necessary to center the biometric icon within the sensor's physical - * location. - */ - @VisibleForTesting - static int calculateHorizontalSpacerWidthForLandscape( - @NonNull FingerprintSensorPropertiesInternal sensorProperties, int displayWidthPx, - int dialogMarginPx, int navbarHorizontalInsetPx, float scaleFactor) { - final SensorLocationInternal location = sensorProperties.getLocation(); - final int sensorDistanceFromEdge = displayWidthPx - - (int) (scaleFactor * location.sensorLocationY) - - (int) (scaleFactor * location.sensorRadius); - - final int horizontalPadding = sensorDistanceFromEdge - - dialogMarginPx - - navbarHorizontalInsetPx; - - if (DEBUG) { - Log.d(TAG, "Display width: " + displayWidthPx - + ", Distance from edge: " + sensorDistanceFromEdge - + ", Dialog margin: " + dialogMarginPx - + ", Navbar horizontal inset: " + navbarHorizontalInsetPx - + ", Horizontal spacer width (landscape): " + horizontalPadding - + ", Scale Factor: " + scaleFactor); - } - - return horizontalPadding; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt index 5e2b5ff5c1ac..6da5e42c12d9 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt @@ -188,7 +188,6 @@ constructor( val hasCredentialViewShown = promptKind.value.isCredential() val showBpForCredential = Flags.customBiometricPrompt() && - com.android.systemui.Flags.constraintBp() && !Utils.isBiometricAllowed(promptInfo) && isDeviceCredentialAllowed(promptInfo) && promptInfo.contentView != null && diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java b/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java deleted file mode 100644 index b450896729b7..000000000000 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/BiometricPromptLayout.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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 com.android.systemui.biometrics.ui; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.graphics.Insets; -import android.util.AttributeSet; -import android.util.Log; -import android.view.View; -import android.view.WindowInsets; -import android.view.WindowManager; -import android.widget.FrameLayout; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.android.systemui.biometrics.AuthController; -import com.android.systemui.biometrics.AuthDialog; -import com.android.systemui.biometrics.UdfpsDialogMeasureAdapter; -import com.android.systemui.res.R; - -import kotlin.Pair; - -/** - * Contains the Biometric views (title, subtitle, icon, buttons, etc.). - * - * TODO(b/251476085): get the udfps junk out of here, at a minimum. Likely can be replaced with a - * normal LinearLayout. - */ -public class BiometricPromptLayout extends LinearLayout { - - private static final String TAG = "BiometricPromptLayout"; - - @NonNull - private final WindowManager mWindowManager; - @Nullable - private AuthController.ScaleFactorProvider mScaleFactorProvider; - @Nullable - private UdfpsDialogMeasureAdapter mUdfpsAdapter; - - private final boolean mUseCustomBpSize; - private final int mCustomBpWidth; - private final int mCustomBpHeight; - - public BiometricPromptLayout(Context context) { - this(context, null); - } - - public BiometricPromptLayout(Context context, AttributeSet attrs) { - super(context, attrs); - - mWindowManager = context.getSystemService(WindowManager.class); - - mUseCustomBpSize = getResources().getBoolean(R.bool.use_custom_bp_size); - mCustomBpWidth = getResources().getDimensionPixelSize(R.dimen.biometric_dialog_width); - mCustomBpHeight = getResources().getDimensionPixelSize(R.dimen.biometric_dialog_height); - } - - @Deprecated - public void setUdfpsAdapter(@NonNull UdfpsDialogMeasureAdapter adapter, - @NonNull AuthController.ScaleFactorProvider scaleProvider) { - mUdfpsAdapter = adapter; - mScaleFactorProvider = scaleProvider != null ? scaleProvider : () -> 1.0f; - } - - @Deprecated - public boolean isUdfps() { - return mUdfpsAdapter != null; - } - - @Deprecated - public Pair<Integer, Integer> getUpdatedFingerprintAffordanceSize() { - if (mUdfpsAdapter != null) { - final int sensorDiameter = mUdfpsAdapter.getSensorDiameter( - mScaleFactorProvider.provide()); - return new Pair(sensorDiameter, sensorDiameter); - } - return null; - } - - @NonNull - private AuthDialog.LayoutParams onMeasureInternal(int width, int height) { - int totalHeight = 0; - final int numChildren = getChildCount(); - for (int i = 0; i < numChildren; i++) { - final View child = getChildAt(i); - - if (child.getId() == R.id.space_above_icon - || child.getId() == R.id.space_above_content - || child.getId() == R.id.space_below_icon - || child.getId() == R.id.button_bar) { - child.measure( - MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(child.getLayoutParams().height, - MeasureSpec.EXACTLY)); - } else if (child.getId() == R.id.biometric_icon_frame) { - final View iconView = findViewById(R.id.biometric_icon); - child.measure( - MeasureSpec.makeMeasureSpec(iconView.getLayoutParams().width, - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(iconView.getLayoutParams().height, - MeasureSpec.EXACTLY)); - } else if (child.getId() == R.id.logo) { - child.measure( - MeasureSpec.makeMeasureSpec(child.getLayoutParams().width, - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(child.getLayoutParams().height, - MeasureSpec.EXACTLY)); - } else if (child.getId() == R.id.biometric_icon) { - child.measure( - MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)); - } else { - child.measure( - MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST)); - } - - if (child.getVisibility() != View.GONE) { - totalHeight += child.getMeasuredHeight(); - } - } - - final AuthDialog.LayoutParams params = new AuthDialog.LayoutParams(width, totalHeight); - if (mUdfpsAdapter != null) { - return mUdfpsAdapter.onMeasureInternal(width, height, params, - (mScaleFactorProvider != null) ? mScaleFactorProvider.provide() : 1.0f); - } else { - return params; - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int width = MeasureSpec.getSize(widthMeasureSpec); - int height = MeasureSpec.getSize(heightMeasureSpec); - - if (mUseCustomBpSize) { - width = mCustomBpWidth; - height = mCustomBpHeight; - } else { - width = Math.min(width, height); - } - - // add nav bar insets since the parent AuthContainerView - // uses LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS - final Insets insets = mWindowManager.getMaximumWindowMetrics().getWindowInsets() - .getInsets(WindowInsets.Type.navigationBars()); - final AuthDialog.LayoutParams params = onMeasureInternal(width, height); - setMeasuredDimension(params.mMediumWidth + insets.left + insets.right, - params.mMediumHeight + insets.bottom); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - - if (mUdfpsAdapter != null) { - // Move the UDFPS icon and indicator text if necessary. This probably only needs to - // happen for devices where the UDFPS sensor is too low. - // TODO(b/201510778): Update this logic to support cases where the sensor or text - // overlap the button bar area. - final float bottomSpacerHeight = mUdfpsAdapter.getBottomSpacerHeight(); - Log.w(TAG, "bottomSpacerHeight: " + bottomSpacerHeight); - if (bottomSpacerHeight < 0) { - final FrameLayout iconFrame = findViewById(R.id.biometric_icon_frame); - iconFrame.setTranslationY(-bottomSpacerHeight); - final TextView indicator = findViewById(R.id.indicator); - indicator.setTranslationY(-bottomSpacerHeight); - } - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt index 7ccac03bcac6..0b474f8092a4 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt @@ -38,14 +38,13 @@ import android.widget.LinearLayout import android.widget.Space import android.widget.TextView import com.android.settingslib.Utils -import com.android.systemui.biometrics.ui.BiometricPromptLayout import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.res.R import kotlin.math.ceil private const val TAG = "BiometricCustomizedViewBinder" -/** Sub-binder for [BiometricPromptLayout.customized_view_container]. */ +/** Sub-binder for Biometric Prompt Customized View */ object BiometricCustomizedViewBinder { fun bind( customizedViewContainer: LinearLayout, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt index 43ba097684d6..a20a17f13a42 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt @@ -45,13 +45,10 @@ import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView import com.airbnb.lottie.LottieCompositionFactory -import com.android.systemui.Flags.constraintBp -import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.shared.model.BiometricModalities import com.android.systemui.biometrics.shared.model.BiometricModality import com.android.systemui.biometrics.shared.model.PromptKind import com.android.systemui.biometrics.shared.model.asBiometricModality -import com.android.systemui.biometrics.ui.BiometricPromptLayout import com.android.systemui.biometrics.ui.viewmodel.FingerprintStartMode import com.android.systemui.biometrics.ui.viewmodel.PromptMessage import com.android.systemui.biometrics.ui.viewmodel.PromptSize @@ -72,28 +69,18 @@ private const val MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER = 30 /** Top-most view binder for BiometricPrompt views. */ object BiometricViewBinder { - /** Binds a [BiometricPromptLayout] to a [PromptViewModel]. */ + /** Binds a Biometric Prompt View to a [PromptViewModel]. */ @SuppressLint("ClickableViewAccessibility") @JvmStatic fun bind( view: View, viewModel: PromptViewModel, - panelViewController: AuthPanelController?, jankListener: BiometricJankListener, backgroundView: View, legacyCallback: Spaghetti.Callback, applicationScope: CoroutineScope, vibratorHelper: VibratorHelper, ): Spaghetti { - /** - * View is only set visible in BiometricViewSizeBinder once PromptSize is determined that - * accounts for iconView size, to prevent prompt resizing being visible to the user. - * - * TODO(b/288175072): May be able to remove this once constraint layout is implemented - */ - if (!constraintBp()) { - view.visibility = View.INVISIBLE - } val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!! val textColorError = @@ -104,9 +91,7 @@ object BiometricViewBinder { R.style.TextAppearance_AuthCredential_Indicator, intArrayOf(android.R.attr.textColor) ) - val textColorHint = - if (constraintBp()) attributes.getColor(0, 0) - else view.resources.getColor(R.color.biometric_dialog_gray, view.context.theme) + val textColorHint = attributes.getColor(0, 0) attributes.recycle() val logoView = view.requireViewById<ImageView>(R.id.logo) @@ -116,12 +101,7 @@ object BiometricViewBinder { val descriptionView = view.requireViewById<TextView>(R.id.description) val customizedViewContainer = view.requireViewById<LinearLayout>(R.id.customized_view_container) - val udfpsGuidanceView = - if (constraintBp()) { - view.requireViewById<View>(R.id.panel) - } else { - backgroundView - } + val udfpsGuidanceView = view.requireViewById<View>(R.id.panel) // set selected to enable marquee unless a screen reader is enabled titleView.isSelected = @@ -130,14 +110,6 @@ object BiometricViewBinder { !accessibilityManager.isEnabled || !accessibilityManager.isTouchExplorationEnabled val iconView = view.requireViewById<LottieAnimationView>(R.id.biometric_icon) - - val iconSizeOverride = - if (constraintBp()) { - null - } else { - (view as BiometricPromptLayout).updatedFingerprintAffordanceSize - } - val indicatorMessageView = view.requireViewById<TextView>(R.id.indicator) // Negative-side (left) buttons @@ -213,7 +185,7 @@ object BiometricViewBinder { subtitleView.text = viewModel.subtitle.first() descriptionView.text = viewModel.description.first() - if (Flags.customBiometricPrompt() && constraintBp()) { + if (Flags.customBiometricPrompt()) { BiometricCustomizedViewBinder.bind( customizedViewContainer, viewModel.contentView.first(), @@ -250,22 +222,6 @@ object BiometricViewBinder { descriptionView, customizedViewContainer, ), - viewsToFadeInOnSizeChange = - listOf( - logoView, - logoDescriptionView, - titleView, - subtitleView, - descriptionView, - customizedViewContainer, - indicatorMessageView, - negativeButton, - cancelButton, - retryButton, - confirmationButton, - credentialFallbackButton, - ), - panelViewController = panelViewController, jankListener = jankListener, ) } @@ -275,7 +231,6 @@ object BiometricViewBinder { if (!showWithoutIcon) { PromptIconViewBinder.bind( iconView, - iconSizeOverride, viewModel, ) } @@ -329,20 +284,6 @@ object BiometricViewBinder { } } - // set padding - launch { - viewModel.promptPadding.collect { promptPadding -> - if (!constraintBp()) { - view.setPadding( - promptPadding.left, - promptPadding.top, - promptPadding.right, - promptPadding.bottom - ) - } - } - } - // configure & hide/disable buttons launch { viewModel.credentialKind @@ -546,24 +487,6 @@ class Spaghetti( fun onAuthenticatedAndConfirmed() } - @Deprecated("TODO(b/330788871): remove after replacing AuthContainerView") - enum class BiometricState { - /** Authentication hardware idle. */ - STATE_IDLE, - /** UI animating in, authentication hardware active. */ - STATE_AUTHENTICATING_ANIMATING_IN, - /** UI animated in, authentication hardware active. */ - STATE_AUTHENTICATING, - /** UI animated in, authentication hardware active. */ - STATE_HELP, - /** Hard error, e.g. ERROR_TIMEOUT. Authentication hardware idle. */ - STATE_ERROR, - /** Authenticated, waiting for user confirmation. Authentication hardware idle. */ - STATE_PENDING_CONFIRMATION, - /** Authenticated, dialog animating away soon. */ - STATE_AUTHENTICATED, - } - private var lifecycleScope: CoroutineScope? = null private var modalities: BiometricModalities = BiometricModalities() private var legacyCallback: Callback? = null @@ -699,15 +622,8 @@ class Spaghetti( } fun startTransitionToCredentialUI(isError: Boolean) { - if (!constraintBp()) { - applicationScope.launch { - viewModel.onSwitchToCredential() - legacyCallback?.onUseDeviceCredential() - } - } else { - viewModel.onSwitchToCredential() - legacyCallback?.onUseDeviceCredential() - } + viewModel.onSwitchToCredential() + legacyCallback?.onUseDeviceCredential() } fun cancelAnimation() { diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt index b9ec2de63269..85c3ae3f214e 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt @@ -38,10 +38,7 @@ import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.Guideline import androidx.core.animation.addListener import androidx.core.view.doOnLayout -import androidx.core.view.isGone import androidx.lifecycle.lifecycleScope -import com.android.systemui.Flags.constraintBp -import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.ui.viewmodel.PromptPosition import com.android.systemui.biometrics.ui.viewmodel.PromptSize @@ -49,7 +46,6 @@ import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel import com.android.systemui.biometrics.ui.viewmodel.isLarge import com.android.systemui.biometrics.ui.viewmodel.isLeft import com.android.systemui.biometrics.ui.viewmodel.isMedium -import com.android.systemui.biometrics.ui.viewmodel.isNullOrNotSmall import com.android.systemui.biometrics.ui.viewmodel.isSmall import com.android.systemui.biometrics.ui.viewmodel.isTop import com.android.systemui.lifecycle.repeatWhenAttached @@ -71,8 +67,6 @@ object BiometricViewSizeBinder { view: View, viewModel: PromptViewModel, viewsToHideWhenSmall: List<View>, - viewsToFadeInOnSizeChange: List<View>, - panelViewController: AuthPanelController?, jankListener: BiometricJankListener, ) { val windowManager = requireNotNull(view.context.getSystemService(WindowManager::class.java)) @@ -92,553 +86,366 @@ object BiometricViewSizeBinder { } } - if (constraintBp()) { - val leftGuideline = view.requireViewById<Guideline>(R.id.leftGuideline) - val topGuideline = view.requireViewById<Guideline>(R.id.topGuideline) - val rightGuideline = view.requireViewById<Guideline>(R.id.rightGuideline) - val midGuideline = view.findViewById<Guideline>(R.id.midGuideline) - - val iconHolderView = view.requireViewById<View>(R.id.biometric_icon) - val panelView = view.requireViewById<View>(R.id.panel) - val cornerRadius = view.resources.getDimension(R.dimen.biometric_dialog_corner_size) - val pxToDp = - TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 1f, - view.resources.displayMetrics - ) - val cornerRadiusPx = (pxToDp * cornerRadius).toInt() - - var currentSize: PromptSize? = null - var currentPosition: PromptPosition = PromptPosition.Bottom - panelView.outlineProvider = - object : ViewOutlineProvider() { - override fun getOutline(view: View, outline: Outline) { - when (currentPosition) { - PromptPosition.Right -> { - outline.setRoundRect( - 0, - 0, - view.width + cornerRadiusPx, - view.height, - cornerRadiusPx.toFloat() - ) - } - PromptPosition.Left -> { - outline.setRoundRect( - -cornerRadiusPx, - 0, - view.width, - view.height, - cornerRadiusPx.toFloat() - ) - } - PromptPosition.Bottom, - PromptPosition.Top -> { - outline.setRoundRect( - 0, - 0, - view.width, - view.height + cornerRadiusPx, - cornerRadiusPx.toFloat() - ) - } + val leftGuideline = view.requireViewById<Guideline>(R.id.leftGuideline) + val topGuideline = view.requireViewById<Guideline>(R.id.topGuideline) + val rightGuideline = view.requireViewById<Guideline>(R.id.rightGuideline) + val midGuideline = view.findViewById<Guideline>(R.id.midGuideline) + + val iconHolderView = view.requireViewById<View>(R.id.biometric_icon) + val panelView = view.requireViewById<View>(R.id.panel) + val cornerRadius = view.resources.getDimension(R.dimen.biometric_dialog_corner_size) + val pxToDp = + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + 1f, + view.resources.displayMetrics + ) + val cornerRadiusPx = (pxToDp * cornerRadius).toInt() + + var currentSize: PromptSize? = null + var currentPosition: PromptPosition = PromptPosition.Bottom + panelView.outlineProvider = + object : ViewOutlineProvider() { + override fun getOutline(view: View, outline: Outline) { + when (currentPosition) { + PromptPosition.Right -> { + outline.setRoundRect( + 0, + 0, + view.width + cornerRadiusPx, + view.height, + cornerRadiusPx.toFloat() + ) } - } - } - - // ConstraintSets for animating between prompt sizes - val mediumConstraintSet = ConstraintSet() - mediumConstraintSet.clone(view as ConstraintLayout) - - val smallConstraintSet = ConstraintSet() - smallConstraintSet.clone(mediumConstraintSet) - - val largeConstraintSet = ConstraintSet() - largeConstraintSet.clone(mediumConstraintSet) - largeConstraintSet.constrainMaxWidth(R.id.panel, 0) - largeConstraintSet.setGuidelineBegin(R.id.leftGuideline, 0) - largeConstraintSet.setGuidelineEnd(R.id.rightGuideline, 0) - - // TODO: Investigate better way to handle 180 rotations - val flipConstraintSet = ConstraintSet() - - view.doOnLayout { - fun setVisibilities(hideSensorIcon: Boolean, size: PromptSize) { - viewsToHideWhenSmall.forEach { it.showContentOrHide(forceHide = size.isSmall) } - largeConstraintSet.setVisibility(iconHolderView.id, View.GONE) - largeConstraintSet.setVisibility(R.id.indicator, View.GONE) - largeConstraintSet.setVisibility(R.id.scrollView, View.GONE) - - if (hideSensorIcon) { - smallConstraintSet.setVisibility(iconHolderView.id, View.GONE) - smallConstraintSet.setVisibility(R.id.indicator, View.GONE) - mediumConstraintSet.setVisibility(iconHolderView.id, View.GONE) - mediumConstraintSet.setVisibility(R.id.indicator, View.GONE) - } - } - - view.repeatWhenAttached { - lifecycleScope.launch { - viewModel.iconPosition.collect { position -> - if (position != Rect()) { - val iconParams = - iconHolderView.layoutParams as ConstraintLayout.LayoutParams - - if (position.left != 0) { - iconParams.endToEnd = ConstraintSet.UNSET - iconParams.leftMargin = position.left - mediumConstraintSet.clear( - R.id.biometric_icon, - ConstraintSet.RIGHT - ) - mediumConstraintSet.connect( - R.id.biometric_icon, - ConstraintSet.LEFT, - ConstraintSet.PARENT_ID, - ConstraintSet.LEFT - ) - mediumConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.LEFT, - position.left - ) - smallConstraintSet.clear( - R.id.biometric_icon, - ConstraintSet.RIGHT - ) - smallConstraintSet.connect( - R.id.biometric_icon, - ConstraintSet.LEFT, - ConstraintSet.PARENT_ID, - ConstraintSet.LEFT - ) - smallConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.LEFT, - position.left - ) - } - if (position.top != 0) { - iconParams.bottomToBottom = ConstraintSet.UNSET - iconParams.topMargin = position.top - mediumConstraintSet.clear( - R.id.biometric_icon, - ConstraintSet.BOTTOM - ) - mediumConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.TOP, - position.top - ) - smallConstraintSet.clear( - R.id.biometric_icon, - ConstraintSet.BOTTOM - ) - smallConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.TOP, - position.top - ) - } - if (position.right != 0) { - iconParams.startToStart = ConstraintSet.UNSET - iconParams.rightMargin = position.right - mediumConstraintSet.clear( - R.id.biometric_icon, - ConstraintSet.LEFT - ) - mediumConstraintSet.connect( - R.id.biometric_icon, - ConstraintSet.RIGHT, - ConstraintSet.PARENT_ID, - ConstraintSet.RIGHT - ) - mediumConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.RIGHT, - position.right - ) - smallConstraintSet.clear( - R.id.biometric_icon, - ConstraintSet.LEFT - ) - smallConstraintSet.connect( - R.id.biometric_icon, - ConstraintSet.RIGHT, - ConstraintSet.PARENT_ID, - ConstraintSet.RIGHT - ) - smallConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.RIGHT, - position.right - ) - } - if (position.bottom != 0) { - iconParams.topToTop = ConstraintSet.UNSET - iconParams.bottomMargin = position.bottom - mediumConstraintSet.clear( - R.id.biometric_icon, - ConstraintSet.TOP - ) - mediumConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.BOTTOM, - position.bottom - ) - smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.TOP) - smallConstraintSet.setMargin( - R.id.biometric_icon, - ConstraintSet.BOTTOM, - position.bottom - ) - } - iconHolderView.layoutParams = iconParams - } + PromptPosition.Left -> { + outline.setRoundRect( + -cornerRadiusPx, + 0, + view.width, + view.height, + cornerRadiusPx.toFloat() + ) } - } - - lifecycleScope.launch { - viewModel.iconSize.collect { iconSize -> - iconHolderView.layoutParams.width = iconSize.first - iconHolderView.layoutParams.height = iconSize.second - mediumConstraintSet.constrainWidth(R.id.biometric_icon, iconSize.first) - mediumConstraintSet.constrainHeight( - R.id.biometric_icon, - iconSize.second + PromptPosition.Bottom, + PromptPosition.Top -> { + outline.setRoundRect( + 0, + 0, + view.width, + view.height + cornerRadiusPx, + cornerRadiusPx.toFloat() ) } } + } + } - lifecycleScope.launch { - viewModel.guidelineBounds.collect { bounds -> - val bottomInset = - windowManager.maximumWindowMetrics.windowInsets - .getInsets(WindowInsets.Type.navigationBars()) - .bottom - mediumConstraintSet.setGuidelineEnd(R.id.bottomGuideline, bottomInset) - - if (bounds.left >= 0) { - mediumConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left) - smallConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left) - } else if (bounds.left < 0) { - mediumConstraintSet.setGuidelineEnd( - leftGuideline.id, - abs(bounds.left) + // ConstraintSets for animating between prompt sizes + val mediumConstraintSet = ConstraintSet() + mediumConstraintSet.clone(view as ConstraintLayout) + + val smallConstraintSet = ConstraintSet() + smallConstraintSet.clone(mediumConstraintSet) + + val largeConstraintSet = ConstraintSet() + largeConstraintSet.clone(mediumConstraintSet) + largeConstraintSet.constrainMaxWidth(R.id.panel, 0) + largeConstraintSet.setGuidelineBegin(R.id.leftGuideline, 0) + largeConstraintSet.setGuidelineEnd(R.id.rightGuideline, 0) + + // TODO: Investigate better way to handle 180 rotations + val flipConstraintSet = ConstraintSet() + + view.doOnLayout { + fun setVisibilities(hideSensorIcon: Boolean, size: PromptSize) { + viewsToHideWhenSmall.forEach { it.showContentOrHide(forceHide = size.isSmall) } + largeConstraintSet.setVisibility(iconHolderView.id, View.GONE) + largeConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) + largeConstraintSet.setVisibility(R.id.indicator, View.GONE) + largeConstraintSet.setVisibility(R.id.scrollView, View.GONE) + + if (hideSensorIcon) { + smallConstraintSet.setVisibility(iconHolderView.id, View.GONE) + smallConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) + smallConstraintSet.setVisibility(R.id.indicator, View.GONE) + mediumConstraintSet.setVisibility(iconHolderView.id, View.GONE) + mediumConstraintSet.setVisibility(R.id.biometric_icon_overlay, View.GONE) + mediumConstraintSet.setVisibility(R.id.indicator, View.GONE) + } + } + + view.repeatWhenAttached { + lifecycleScope.launch { + viewModel.iconPosition.collect { position -> + if (position != Rect()) { + val iconParams = + iconHolderView.layoutParams as ConstraintLayout.LayoutParams + + if (position.left != 0) { + iconParams.endToEnd = ConstraintSet.UNSET + iconParams.leftMargin = position.left + mediumConstraintSet.clear(R.id.biometric_icon, ConstraintSet.RIGHT) + mediumConstraintSet.connect( + R.id.biometric_icon, + ConstraintSet.LEFT, + ConstraintSet.PARENT_ID, + ConstraintSet.LEFT ) - smallConstraintSet.setGuidelineEnd( - leftGuideline.id, - abs(bounds.left) + mediumConstraintSet.setMargin( + R.id.biometric_icon, + ConstraintSet.LEFT, + position.left ) - } - - if (bounds.right >= 0) { - mediumConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right) - smallConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right) - } else if (bounds.right < 0) { - mediumConstraintSet.setGuidelineBegin( - rightGuideline.id, - abs(bounds.right) + smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.RIGHT) + smallConstraintSet.connect( + R.id.biometric_icon, + ConstraintSet.LEFT, + ConstraintSet.PARENT_ID, + ConstraintSet.LEFT ) - smallConstraintSet.setGuidelineBegin( - rightGuideline.id, - abs(bounds.right) + smallConstraintSet.setMargin( + R.id.biometric_icon, + ConstraintSet.LEFT, + position.left ) } - - if (bounds.top >= 0) { - mediumConstraintSet.setGuidelineBegin(topGuideline.id, bounds.top) - smallConstraintSet.setGuidelineBegin(topGuideline.id, bounds.top) - } else if (bounds.top < 0) { - mediumConstraintSet.setGuidelineEnd( - topGuideline.id, - abs(bounds.top) + if (position.top != 0) { + iconParams.bottomToBottom = ConstraintSet.UNSET + iconParams.topMargin = position.top + mediumConstraintSet.clear(R.id.biometric_icon, ConstraintSet.BOTTOM) + mediumConstraintSet.setMargin( + R.id.biometric_icon, + ConstraintSet.TOP, + position.top ) - smallConstraintSet.setGuidelineEnd(topGuideline.id, abs(bounds.top)) - } - - if (midGuideline != null) { - val left = - if (bounds.left >= 0) { - abs(bounds.left) - } else { - view.width - abs(bounds.left) - } - val right = - if (bounds.right >= 0) { - view.width - abs(bounds.right) - } else { - abs(bounds.right) - } - val mid = (left + right) / 2 - mediumConstraintSet.setGuidelineBegin(midGuideline.id, mid) - } - } - } - - lifecycleScope.launch { - combine(viewModel.hideSensorIcon, viewModel.size, ::Pair).collect { - (hideSensorIcon, size) -> - setVisibilities(hideSensorIcon, size) - } - } - - lifecycleScope.launch { - combine(viewModel.position, viewModel.size, ::Pair).collect { - (position, size) -> - if (position.isLeft) { - if (size.isSmall) { - flipConstraintSet.clone(smallConstraintSet) - } else { - flipConstraintSet.clone(mediumConstraintSet) - } - - // Move all content to other panel - flipConstraintSet.connect( - R.id.scrollView, - ConstraintSet.LEFT, - R.id.midGuideline, - ConstraintSet.LEFT + smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.BOTTOM) + smallConstraintSet.setMargin( + R.id.biometric_icon, + ConstraintSet.TOP, + position.top ) - flipConstraintSet.connect( - R.id.scrollView, + } + if (position.right != 0) { + iconParams.startToStart = ConstraintSet.UNSET + iconParams.rightMargin = position.right + mediumConstraintSet.clear(R.id.biometric_icon, ConstraintSet.LEFT) + mediumConstraintSet.connect( + R.id.biometric_icon, ConstraintSet.RIGHT, - R.id.rightGuideline, + ConstraintSet.PARENT_ID, ConstraintSet.RIGHT ) - } else if (position.isTop) { - // Top position is only used for 180 rotation Udfps - // Requires repositioning due to sensor location at top of screen - mediumConstraintSet.connect( - R.id.scrollView, - ConstraintSet.TOP, - R.id.indicator, - ConstraintSet.BOTTOM + mediumConstraintSet.setMargin( + R.id.biometric_icon, + ConstraintSet.RIGHT, + position.right ) - mediumConstraintSet.connect( - R.id.scrollView, - ConstraintSet.BOTTOM, - R.id.button_bar, - ConstraintSet.TOP + smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.LEFT) + smallConstraintSet.connect( + R.id.biometric_icon, + ConstraintSet.RIGHT, + ConstraintSet.PARENT_ID, + ConstraintSet.RIGHT ) - mediumConstraintSet.connect( - R.id.panel, - ConstraintSet.TOP, + smallConstraintSet.setMargin( R.id.biometric_icon, - ConstraintSet.TOP + ConstraintSet.RIGHT, + position.right ) + } + if (position.bottom != 0) { + iconParams.topToTop = ConstraintSet.UNSET + iconParams.bottomMargin = position.bottom + mediumConstraintSet.clear(R.id.biometric_icon, ConstraintSet.TOP) mediumConstraintSet.setMargin( - R.id.panel, - ConstraintSet.TOP, - (-24 * pxToDp).toInt() + R.id.biometric_icon, + ConstraintSet.BOTTOM, + position.bottom + ) + smallConstraintSet.clear(R.id.biometric_icon, ConstraintSet.TOP) + smallConstraintSet.setMargin( + R.id.biometric_icon, + ConstraintSet.BOTTOM, + position.bottom ) - mediumConstraintSet.setVerticalBias(R.id.scrollView, 0f) } + iconHolderView.layoutParams = iconParams + } + } + } - when { - size.isSmall -> { - if (position.isLeft) { - flipConstraintSet.applyTo(view) - } else { - smallConstraintSet.applyTo(view) - } - } - size.isMedium && currentSize.isSmall -> { - val autoTransition = AutoTransition() - autoTransition.setDuration( - ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() - ) - - TransitionManager.beginDelayedTransition(view, autoTransition) - - if (position.isLeft) { - flipConstraintSet.applyTo(view) - } else { - mediumConstraintSet.applyTo(view) - } - } - size.isMedium -> { - if (position.isLeft) { - flipConstraintSet.applyTo(view) - } else { - mediumConstraintSet.applyTo(view) - } - } - size.isLarge && currentSize.isMedium -> { - val autoTransition = AutoTransition() - autoTransition.setDuration( - ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() - ) - - TransitionManager.beginDelayedTransition(view, autoTransition) - largeConstraintSet.applyTo(view) - } - } + lifecycleScope.launch { + viewModel.iconSize.collect { iconSize -> + iconHolderView.layoutParams.width = iconSize.first + iconHolderView.layoutParams.height = iconSize.second + mediumConstraintSet.constrainWidth(R.id.biometric_icon, iconSize.first) + mediumConstraintSet.constrainHeight(R.id.biometric_icon, iconSize.second) + } + } + + lifecycleScope.launch { + viewModel.guidelineBounds.collect { bounds -> + val bottomInset = + windowManager.maximumWindowMetrics.windowInsets + .getInsets(WindowInsets.Type.navigationBars()) + .bottom + mediumConstraintSet.setGuidelineEnd(R.id.bottomGuideline, bottomInset) + + if (bounds.left >= 0) { + mediumConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left) + smallConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left) + } else if (bounds.left < 0) { + mediumConstraintSet.setGuidelineEnd(leftGuideline.id, abs(bounds.left)) + smallConstraintSet.setGuidelineEnd(leftGuideline.id, abs(bounds.left)) + } + + if (bounds.right >= 0) { + mediumConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right) + smallConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right) + } else if (bounds.right < 0) { + mediumConstraintSet.setGuidelineBegin( + rightGuideline.id, + abs(bounds.right) + ) + smallConstraintSet.setGuidelineBegin( + rightGuideline.id, + abs(bounds.right) + ) + } - currentSize = size - currentPosition = position - notifyAccessibilityChanged() + if (bounds.top >= 0) { + mediumConstraintSet.setGuidelineBegin(topGuideline.id, bounds.top) + smallConstraintSet.setGuidelineBegin(topGuideline.id, bounds.top) + } else if (bounds.top < 0) { + mediumConstraintSet.setGuidelineEnd(topGuideline.id, abs(bounds.top)) + smallConstraintSet.setGuidelineEnd(topGuideline.id, abs(bounds.top)) + } - panelView.invalidateOutline() - view.invalidate() - view.requestLayout() + if (midGuideline != null) { + val left = + if (bounds.left >= 0) { + abs(bounds.left) + } else { + view.width - abs(bounds.left) + } + val right = + if (bounds.right >= 0) { + view.width - abs(bounds.right) + } else { + abs(bounds.right) + } + val mid = (left + right) / 2 + mediumConstraintSet.setGuidelineBegin(midGuideline.id, mid) } } } - } - } else if (panelViewController != null) { - val iconHolderView = view.requireViewById<View>(R.id.biometric_icon_frame) - val iconPadding = view.resources.getDimension(R.dimen.biometric_dialog_icon_padding) - val fullSizeYOffset = - view.resources.getDimension( - R.dimen.biometric_dialog_medium_to_large_translation_offset - ) - - // cache the original position of the icon view (as done in legacy view) - // this must happen before any size changes can be made - view.doOnLayout { - // TODO(b/251476085): this old way of positioning has proven itself unreliable - // remove this and associated thing like (UdfpsDialogMeasureAdapter) and - // pin to the physical sensor - val iconHolderOriginalY = iconHolderView.y - - // bind to prompt - // TODO(b/251476085): migrate the legacy panel controller and simplify this - view.repeatWhenAttached { - var currentSize: PromptSize? = null - lifecycleScope.launch { - /** - * View is only set visible in BiometricViewSizeBinder once PromptSize is - * determined that accounts for iconView size, to prevent prompt resizing - * being visible to the user. - * - * TODO(b/288175072): May be able to remove isIconViewLoaded once constraint - * layout is implemented - */ - combine(viewModel.isIconViewLoaded, viewModel.size, ::Pair).collect { - (isIconViewLoaded, size) -> - if (!isIconViewLoaded) { - return@collect - } - // prepare for animated size transitions - for (v in viewsToHideWhenSmall) { - v.showContentOrHide(forceHide = size.isSmall) - } + lifecycleScope.launch { + combine(viewModel.hideSensorIcon, viewModel.size, ::Pair).collect { + (hideSensorIcon, size) -> + setVisibilities(hideSensorIcon, size) + } + } - if (viewModel.hideSensorIcon.first()) { - iconHolderView.visibility = View.GONE + lifecycleScope.launch { + combine(viewModel.position, viewModel.size, ::Pair).collect { (position, size) + -> + if (position.isLeft) { + if (size.isSmall) { + flipConstraintSet.clone(smallConstraintSet) + } else { + flipConstraintSet.clone(mediumConstraintSet) } - if (currentSize == null && size.isSmall) { - iconHolderView.alpha = 0f - } - if ((currentSize.isSmall && size.isMedium) || size.isSmall) { - viewsToFadeInOnSizeChange.forEach { it.alpha = 0f } + // Move all content to other panel + flipConstraintSet.connect( + R.id.scrollView, + ConstraintSet.LEFT, + R.id.midGuideline, + ConstraintSet.LEFT + ) + flipConstraintSet.connect( + R.id.scrollView, + ConstraintSet.RIGHT, + R.id.rightGuideline, + ConstraintSet.RIGHT + ) + } else if (position.isTop) { + // Top position is only used for 180 rotation Udfps + // Requires repositioning due to sensor location at top of screen + mediumConstraintSet.connect( + R.id.scrollView, + ConstraintSet.TOP, + R.id.indicator, + ConstraintSet.BOTTOM + ) + mediumConstraintSet.connect( + R.id.scrollView, + ConstraintSet.BOTTOM, + R.id.button_bar, + ConstraintSet.TOP + ) + mediumConstraintSet.connect( + R.id.panel, + ConstraintSet.TOP, + R.id.biometric_icon, + ConstraintSet.TOP + ) + mediumConstraintSet.setMargin( + R.id.panel, + ConstraintSet.TOP, + (-24 * pxToDp).toInt() + ) + mediumConstraintSet.setVerticalBias(R.id.scrollView, 0f) + } + + when { + size.isSmall -> { + if (position.isLeft) { + flipConstraintSet.applyTo(view) + } else { + smallConstraintSet.applyTo(view) + } } + size.isMedium && currentSize.isSmall -> { + val autoTransition = AutoTransition() + autoTransition.setDuration( + ANIMATE_SMALL_TO_MEDIUM_DURATION_MS.toLong() + ) - // propagate size changes to legacy panel controller and animate - // transitions - view.doOnLayout { - val width = view.measuredWidth - val height = view.measuredHeight - - when { - size.isSmall -> { - iconHolderView.alpha = 1f - val bottomInset = - windowManager.maximumWindowMetrics.windowInsets - .getInsets(WindowInsets.Type.navigationBars()) - .bottom - iconHolderView.y = - if (view.isLandscape()) { - (view.height - - iconHolderView.height - - bottomInset) / 2f - } else { - view.height - - iconHolderView.height - - iconPadding - - bottomInset - } - val newHeight = - iconHolderView.height + (2 * iconPadding.toInt()) - - iconHolderView.paddingTop - - iconHolderView.paddingBottom - panelViewController.updateForContentDimensions( - width, - newHeight + bottomInset, - 0, /* animateDurationMs */ - ) - } - size.isMedium && currentSize.isSmall -> { - val duration = ANIMATE_SMALL_TO_MEDIUM_DURATION_MS - panelViewController.updateForContentDimensions( - width, - height, - duration, - ) - startMonitoredAnimation( - listOf( - iconHolderView.asVerticalAnimator( - duration = duration.toLong(), - toY = - iconHolderOriginalY - - viewsToHideWhenSmall - .filter { it.isGone } - .sumOf { it.height }, - ), - viewsToFadeInOnSizeChange.asFadeInAnimator( - duration = duration.toLong(), - delay = duration.toLong(), - ), - ) - ) - } - size.isMedium && currentSize.isNullOrNotSmall -> { - panelViewController.updateForContentDimensions( - width, - height, - 0, /* animateDurationMs */ - ) - } - size.isLarge -> { - val duration = ANIMATE_MEDIUM_TO_LARGE_DURATION_MS - panelViewController.setUseFullScreen(true) - panelViewController.updateForContentDimensions( - panelViewController.containerWidth, - panelViewController.containerHeight, - duration, - ) - - startMonitoredAnimation( - listOf( - view.asVerticalAnimator( - duration.toLong() * 2 / 3, - toY = view.y - fullSizeYOffset - ), - listOf(view) - .asFadeInAnimator( - duration = duration.toLong() / 2, - delay = duration.toLong(), - ), - ) - ) - // TODO(b/251476085): clean up (copied from legacy) - if (view.isAttachedToWindow) { - val parent = view.parent as? ViewGroup - parent?.removeView(view) - } - } + TransitionManager.beginDelayedTransition(view, autoTransition) + + if (position.isLeft) { + flipConstraintSet.applyTo(view) + } else { + mediumConstraintSet.applyTo(view) + } + } + size.isMedium -> { + if (position.isLeft) { + flipConstraintSet.applyTo(view) + } else { + mediumConstraintSet.applyTo(view) } + } + size.isLarge && currentSize.isMedium -> { + val autoTransition = AutoTransition() + autoTransition.setDuration( + ANIMATE_MEDIUM_TO_LARGE_DURATION_MS.toLong() + ) - currentSize = size - view.visibility = View.VISIBLE - viewModel.setIsIconViewLoaded(false) - notifyAccessibilityChanged() + TransitionManager.beginDelayedTransition(view, autoTransition) + largeConstraintSet.applyTo(view) } } + + currentSize = size + currentPosition = position + notifyAccessibilityChanged() + + panelView.invalidateOutline() + view.invalidate() + view.requestLayout() } } } @@ -646,17 +453,6 @@ object BiometricViewSizeBinder { } } -private fun View.isLandscape(): Boolean { - val r = context.display.rotation - return if ( - context.resources.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation) - ) { - r == Surface.ROTATION_0 || r == Surface.ROTATION_180 - } else { - r == Surface.ROTATION_90 || r == Surface.ROTATION_270 - } -} - private fun View.showContentOrHide(forceHide: Boolean = false) { val isTextViewWithBlankText = this is TextView && this.text.isBlank() val isImageViewWithoutImage = this is ImageView && this.drawable == null @@ -667,26 +463,3 @@ private fun View.showContentOrHide(forceHide: Boolean = false) { View.VISIBLE } } - -private fun View.asVerticalAnimator( - duration: Long, - toY: Float, - fromY: Float = this.y -): ValueAnimator { - val animator = ValueAnimator.ofFloat(fromY, toY) - animator.duration = duration - animator.addUpdateListener { y = it.animatedValue as Float } - return animator -} - -private fun List<View>.asFadeInAnimator(duration: Long, delay: Long): ValueAnimator { - forEach { it.alpha = 0f } - val animator = ValueAnimator.ofFloat(0f, 1f) - animator.duration = duration - animator.startDelay = delay - animator.addUpdateListener { - val alpha = it.animatedValue as Float - forEach { view -> view.alpha = alpha } - } - return animator -} diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt index 18e2a56e5e78..49f4b05e2cd9 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/CredentialViewBinder.kt @@ -10,7 +10,6 @@ import android.widget.TextView import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators -import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.AuthPanelController import com.android.systemui.biometrics.ui.CredentialPasswordView import com.android.systemui.biometrics.ui.CredentialPatternView @@ -82,7 +81,7 @@ object CredentialViewBinder { subtitleView.textOrHide = header.subtitle descriptionView.textOrHide = header.description - if (Flags.customBiometricPrompt() && constraintBp()) { + if (Flags.customBiometricPrompt()) { BiometricCustomizedViewBinder.bind( customizedViewContainer, header.contentView, diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt index 9e4aaaa44085..fa3230e19b0c 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt @@ -22,9 +22,7 @@ import android.util.Log import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.airbnb.lottie.LottieAnimationView -import com.airbnb.lottie.LottieOnCompositionLoadedListener import com.android.settingslib.widget.LottieColorUtils -import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel.AuthType import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel @@ -44,55 +42,12 @@ object PromptIconViewBinder { @JvmStatic fun bind( iconView: LottieAnimationView, - iconViewLayoutParamSizeOverride: Pair<Int, Int>?, promptViewModel: PromptViewModel ) { val viewModel = promptViewModel.iconViewModel iconView.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.onConfigurationChanged(iconView.context.resources.configuration) - if (iconViewLayoutParamSizeOverride != null) { - iconView.layoutParams.width = iconViewLayoutParamSizeOverride.first - iconView.layoutParams.height = iconViewLayoutParamSizeOverride.second - } - - if (!constraintBp()) { - launch { - var lottieOnCompositionLoadedListener: LottieOnCompositionLoadedListener? = - null - - viewModel.iconSize.collect { iconSize -> - /** - * When we bind the BiometricPrompt View and ViewModel in - * [BiometricViewBinder], the view is set invisible and - * [isIconViewLoaded] is set to false. We configure the iconView with a - * LottieOnCompositionLoadedListener that sets [isIconViewLoaded] to - * true, in order to wait for the iconView to load before determining - * the prompt size, and prevent any prompt resizing from being visible - * to the user. - * - * TODO(b/288175072): May be able to remove this once constraint layout - * is unflagged - */ - if (lottieOnCompositionLoadedListener != null) { - iconView.removeLottieOnCompositionLoadedListener( - lottieOnCompositionLoadedListener!! - ) - } - lottieOnCompositionLoadedListener = LottieOnCompositionLoadedListener { - promptViewModel.setIsIconViewLoaded(true) - } - iconView.addLottieOnCompositionLoadedListener( - lottieOnCompositionLoadedListener!! - ) - - if (iconViewLayoutParamSizeOverride == null) { - iconView.layoutParams.width = iconSize.first - iconView.layoutParams.height = iconSize.second - } - } - } - } launch { viewModel.iconAsset diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt index 31af126eb3f0..761c3da77a4d 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/CredentialViewModel.kt @@ -6,7 +6,6 @@ import android.hardware.biometrics.Flags.customBiometricPrompt import android.hardware.biometrics.PromptContentView import android.text.InputType import com.android.internal.widget.LockPatternView -import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.domain.interactor.CredentialStatus import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor @@ -39,7 +38,7 @@ constructor( credentialInteractor.prompt.filterIsInstance<BiometricPromptRequest.Credential>(), credentialInteractor.showTitleOnly ) { request, showTitleOnly -> - val flagEnabled = customBiometricPrompt() && constraintBp() + val flagEnabled = customBiometricPrompt() val showTitleOnlyForCredential = showTitleOnly && flagEnabled BiometricPromptHeaderViewModelImpl( request, @@ -82,8 +81,8 @@ constructor( val errorMessage: Flow<String> = combine(credentialInteractor.verificationError, credentialInteractor.prompt) { error, p -> when (error) { - is CredentialStatus.Fail.Error -> error.error - ?: applicationContext.asBadCredentialErrorMessage(p) + is CredentialStatus.Fail.Error -> + error.error ?: applicationContext.asBadCredentialErrorMessage(p) is CredentialStatus.Fail.Throttled -> error.error null -> "" } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt index 214420d45560..865035ef3051 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt @@ -36,7 +36,6 @@ import android.util.RotationUtils import android.view.HapticFeedbackConstants import android.view.MotionEvent import com.android.launcher3.icons.IconProvider -import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.UdfpsUtils import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.Utils.isSystem @@ -470,7 +469,7 @@ constructor( promptSelectorInteractor.prompt .map { when { - !(customBiometricPrompt() && constraintBp()) || it == null -> Pair(null, "") + !(customBiometricPrompt()) || it == null -> Pair(null, "") else -> context.getUserBadgedLogoInfo(it, iconProvider, activityTaskManager) } } @@ -487,7 +486,7 @@ constructor( /** Custom content view for the prompt. */ val contentView: Flow<PromptContentView?> = promptSelectorInteractor.prompt - .map { if (customBiometricPrompt() && constraintBp()) it?.contentView else null } + .map { if (customBiometricPrompt()) it?.contentView else null } .distinctUntilChanged() private val originalDescription = diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt index 19ea007fc60f..c2a4ee36dec6 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt @@ -28,7 +28,6 @@ import android.view.WindowManager import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY import com.airbnb.lottie.model.KeyPath -import com.android.systemui.Flags.constraintBp import com.android.systemui.biometrics.Utils import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor import com.android.systemui.biometrics.domain.interactor.SideFpsSensorInteractor @@ -152,21 +151,6 @@ constructor( -> val topLeft = Point(sensorLocation.left, sensorLocation.top) - if (!constraintBp()) { - if (sensorLocation.isSensorVerticalInDefaultOrientation) { - if (displayRotation == DisplayRotation.ROTATION_0) { - topLeft.x -= bounds!!.width() - } else if (displayRotation == DisplayRotation.ROTATION_270) { - topLeft.y -= bounds!!.height() - } - } else { - if (displayRotation == DisplayRotation.ROTATION_180) { - topLeft.y -= bounds!!.height() - } else if (displayRotation == DisplayRotation.ROTATION_270) { - topLeft.x -= bounds!!.width() - } - } - } defaultOverlayViewParams.apply { x = topLeft.x y = topLeft.y diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt index dc69cdadc320..f94a6f24a106 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt @@ -29,7 +29,6 @@ import android.hardware.biometrics.PromptVerticalListContentView import android.hardware.face.FaceSensorPropertiesInternal import android.hardware.fingerprint.FingerprintManager import android.hardware.fingerprint.FingerprintSensorPropertiesInternal -import android.os.Handler import android.os.IBinder import android.os.UserManager import android.testing.TestableLooper @@ -45,7 +44,6 @@ import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.widget.LockPatternUtils import com.android.launcher3.icons.IconProvider -import com.android.systemui.Flags.FLAG_CONSTRAINT_BP import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository @@ -105,7 +103,6 @@ open class AuthContainerViewTest : SysuiTestCase() { @Mock lateinit var fingerprintManager: FingerprintManager @Mock lateinit var lockPatternUtils: LockPatternUtils @Mock lateinit var wakefulnessLifecycle: WakefulnessLifecycle - @Mock lateinit var panelInteractionDetector: AuthDialogPanelInteractionDetector @Mock lateinit var windowToken: IBinder @Mock lateinit var interactionJankMonitor: InteractionJankMonitor @Mock lateinit var vibrator: VibratorHelper @@ -265,14 +262,6 @@ open class AuthContainerViewTest : SysuiTestCase() { } @Test - fun testActionCancel_panelInteractionDetectorDisable() { - val container = initializeFingerprintContainer() - container.mBiometricCallback.onUserCanceled() - waitForIdleSync() - verify(panelInteractionDetector).disable() - } - - @Test fun testActionAuthenticated_sendsDismissedAuthenticated() { val container = initializeFingerprintContainer() container.mBiometricCallback.onAuthenticated() @@ -416,19 +405,7 @@ open class AuthContainerViewTest : SysuiTestCase() { } @Test - fun testShowBiometricUI() { - mSetFlagsRule.disableFlags(FLAG_CONSTRAINT_BP) - val container = initializeFingerprintContainer() - - waitForIdleSync() - - assertThat(container.hasCredentialView()).isFalse() - assertThat(container.hasBiometricPrompt()).isTrue() - } - - @Test fun testShowBiometricUI_ContentViewWithMoreOptionsButton() { - mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) var isButtonClicked = false val contentView = @@ -466,7 +443,6 @@ open class AuthContainerViewTest : SysuiTestCase() { @Test fun testShowCredentialUI_withVerticalListContentView() { - mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) val container = initializeFingerprintContainer( @@ -488,7 +464,6 @@ open class AuthContainerViewTest : SysuiTestCase() { @Test fun testShowCredentialUI_withContentViewWithMoreOptionsButton() { - mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP) mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) val contentView = PromptContentViewWithMoreOptionsButton.Builder() @@ -674,7 +649,6 @@ open class AuthContainerViewTest : SysuiTestCase() { fingerprintProps, faceProps, wakefulnessLifecycle, - panelInteractionDetector, userManager, lockPatternUtils, interactionJankMonitor, @@ -690,7 +664,6 @@ open class AuthContainerViewTest : SysuiTestCase() { activityTaskManager ), { credentialViewModel }, - Handler(TestableLooper.get(this).looper), fakeExecutor, vibrator ) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt deleted file mode 100644 index 023148603b50..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthDialogPanelInteractionDetectorTest.kt +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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 com.android.systemui.biometrics - -import android.platform.test.flag.junit.FlagsParameterization -import androidx.test.filters.SmallTest -import com.android.systemui.SysuiTestCase -import com.android.systemui.flags.andSceneContainer -import com.android.systemui.kosmos.applicationCoroutineScope -import com.android.systemui.kosmos.testScope -import com.android.systemui.shade.domain.interactor.shadeInteractor -import com.android.systemui.shade.shadeTestUtil -import com.android.systemui.testKosmos -import kotlinx.coroutines.test.runCurrent -import kotlinx.coroutines.test.runTest -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations -import org.mockito.kotlin.verifyZeroInteractions -import platform.test.runner.parameterized.ParameterizedAndroidJunit4 -import platform.test.runner.parameterized.Parameters - -@SmallTest -@RunWith(ParameterizedAndroidJunit4::class) -class AuthDialogPanelInteractionDetectorTest(flags: FlagsParameterization?) : SysuiTestCase() { - - companion object { - @JvmStatic - @Parameters(name = "{0}") - fun getParams(): List<FlagsParameterization> { - return FlagsParameterization.allCombinationsOf().andSceneContainer() - } - } - - init { - mSetFlagsRule.setFlagsParameterization(flags!!) - } - - private val kosmos = testKosmos() - private val testScope = kosmos.testScope - - private val shadeTestUtil by lazy { kosmos.shadeTestUtil } - - @Mock private lateinit var action: Runnable - - lateinit var detector: AuthDialogPanelInteractionDetector - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - detector = - AuthDialogPanelInteractionDetector( - kosmos.applicationCoroutineScope, - { kosmos.shadeInteractor }, - ) - } - - @Test - fun enableDetector_expand_shouldRunAction() = - testScope.runTest { - // GIVEN shade is closed and detector is enabled - shadeTestUtil.setShadeExpansion(0f) - detector.enable(action) - runCurrent() - - // WHEN shade expands - shadeTestUtil.setTracking(true) - shadeTestUtil.setShadeExpansion(.5f) - runCurrent() - - // THEN action was run - verify(action).run() - } - - @Test - fun enableDetector_isUserInteractingTrue_shouldNotPostRunnable() = - testScope.runTest { - // GIVEN isInteracting starts true - shadeTestUtil.setTracking(true) - runCurrent() - detector.enable(action) - - // THEN action was not run - verifyZeroInteractions(action) - } - - @Test - fun enableDetector_shadeExpandImmediate_shouldNotPostRunnable() = - testScope.runTest { - // GIVEN shade is closed and detector is enabled - shadeTestUtil.setShadeExpansion(0f) - detector.enable(action) - runCurrent() - - // WHEN shade expands fully instantly - shadeTestUtil.setShadeExpansion(1f) - runCurrent() - - // THEN action not run - verifyZeroInteractions(action) - detector.disable() - } - - @Test - fun disableDetector_shouldNotPostRunnable() = - testScope.runTest { - // GIVEN shade is closed and detector is enabled - shadeTestUtil.setShadeExpansion(0f) - detector.enable(action) - runCurrent() - - // WHEN detector is disabled and shade opens - detector.disable() - runCurrent() - shadeTestUtil.setTracking(true) - shadeTestUtil.setShadeExpansion(.5f) - runCurrent() - - // THEN action not run - verifyZeroInteractions(action) - } - - @Test - fun enableDetector_beginCollapse_shouldNotPostRunnable() = - testScope.runTest { - // GIVEN shade is open and detector is enabled - shadeTestUtil.setShadeExpansion(1f) - detector.enable(action) - runCurrent() - - // WHEN shade begins to collapse - shadeTestUtil.programmaticCollapseShade() - runCurrent() - - // THEN action not run - verifyZeroInteractions(action) - detector.disable() - } -} diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt index 534f25c33900..6047e7d1bf79 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt @@ -43,7 +43,6 @@ import android.view.MotionEvent import android.view.Surface import androidx.test.filters.SmallTest import com.android.app.activityTaskManager -import com.android.systemui.Flags.FLAG_CONSTRAINT_BP import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.AuthController import com.android.systemui.biometrics.Utils.toBitmap @@ -1385,7 +1384,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun descriptionOverriddenByVerticalListContentView() = runGenericTest(description = "test description", contentView = promptContentView) { val contentView by collectLastValue(kosmos.promptViewModel.contentView) @@ -1396,7 +1395,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun descriptionOverriddenByContentViewWithMoreOptionsButton() = runGenericTest( description = "test description", @@ -1410,7 +1409,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun descriptionWithoutContentView() = runGenericTest(description = "test description") { val contentView by collectLastValue(kosmos.promptViewModel.contentView) @@ -1421,7 +1420,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logo_nullIfPkgNameNotFound() = runGenericTest(packageName = OP_PACKAGE_NAME_CAN_NOT_BE_FOUND) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1430,7 +1429,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logo_defaultFromActivityInfo() = runGenericTest(packageName = OP_PACKAGE_NAME_WITH_ACTIVITY_LOGO) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1445,7 +1444,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logo_defaultIsNull() = runGenericTest(packageName = OP_PACKAGE_NAME_NO_ICON) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1454,7 +1453,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logo_default() = runGenericTest { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) assertThat(logoInfo).isNotNull() @@ -1462,7 +1461,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logo_resSetByApp() = runGenericTest(logoRes = logoResFromApp) { val expectedBitmap = context.getDrawable(logoResFromApp).toBitmap() @@ -1472,7 +1471,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logo_bitmapSetByApp() = runGenericTest(logoBitmap = logoBitmapFromApp) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1480,7 +1479,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logoDescription_emptyIfPkgNameNotFound() = runGenericTest(packageName = OP_PACKAGE_NAME_CAN_NOT_BE_FOUND) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1488,7 +1487,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logoDescription_defaultFromActivityInfo() = runGenericTest(packageName = OP_PACKAGE_NAME_WITH_ACTIVITY_LOGO) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1500,7 +1499,7 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logoDescription_defaultIsEmpty() = runGenericTest(packageName = OP_PACKAGE_NAME_NO_ICON) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1508,14 +1507,14 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logoDescription_default() = runGenericTest { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) assertThat(logoInfo!!.second).isEqualTo(defaultLogoDescriptionFromAppInfo) } @Test - @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP) + @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT) fun logoDescription_setByApp() = runGenericTest(logoDescription = logoDescriptionFromApp) { val logoInfo by collectLastValue(kosmos.promptViewModel.logoInfo) @@ -1523,7 +1522,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun position_bottom_rotation0() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0) val position by collectLastValue(kosmos.promptViewModel.position) @@ -1531,7 +1529,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } // TODO(b/335278136): Add test for no sensor landscape @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun position_bottom_forceLarge() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270) kosmos.promptViewModel.onSwitchToCredential() @@ -1540,7 +1537,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun position_bottom_largeScreen() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270) kosmos.displayStateRepository.setIsLargeScreen(true) @@ -1549,7 +1545,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun position_right_rotation90() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90) val position by collectLastValue(kosmos.promptViewModel.position) @@ -1557,7 +1552,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun position_left_rotation270() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270) val position by collectLastValue(kosmos.promptViewModel.position) @@ -1565,7 +1559,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun position_top_rotation180() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180) val position by collectLastValue(kosmos.promptViewModel.position) @@ -1577,7 +1570,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun guideline_bottom() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0) val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds) @@ -1585,7 +1577,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } // TODO(b/335278136): Add test for no sensor landscape @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun guideline_right() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90) @@ -1602,7 +1593,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun guideline_right_onlyShortTitle() = runGenericTest(subtitle = "") { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90) @@ -1617,7 +1607,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun guideline_left() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270) @@ -1634,7 +1623,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun guideline_left_onlyShortTitle() = runGenericTest(subtitle = "") { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270) @@ -1649,7 +1637,6 @@ internal class PromptViewModelTest(private val testCase: TestCase) : SysuiTestCa } @Test - @EnableFlags(FLAG_CONSTRAINT_BP) fun guideline_top() = runGenericTest { kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180) val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds) diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt index 3b2cf61dde68..0db7b62b8ef1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt @@ -32,7 +32,6 @@ import androidx.test.filters.SmallTest import com.airbnb.lottie.model.KeyPath import com.android.keyguard.keyguardUpdateMonitor import com.android.settingslib.Utils -import com.android.systemui.Flags.FLAG_CONSTRAINT_BP import com.android.systemui.SysuiTestCase import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider import com.android.systemui.biometrics.data.repository.biometricStatusRepository @@ -199,7 +198,6 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() { @Test fun updatesOverlayViewParams_onDisplayRotationChange_xAlignedSensor() { kosmos.testScope.runTest { - mSetFlagsRule.disableFlags(FLAG_CONSTRAINT_BP) setupTestConfiguration( DeviceConfig.X_ALIGNED, rotation = DisplayRotation.ROTATION_0, @@ -230,11 +228,11 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() { .isEqualTo( displayWidth - sensorLocation.sensorLocationX - sensorLocation.sensorRadius * 2 ) - assertThat(overlayViewParams!!.y).isEqualTo(displayHeight - boundsHeight) + assertThat(overlayViewParams!!.y).isEqualTo(displayHeight) kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270) assertThat(overlayViewParams).isNotNull() - assertThat(overlayViewParams!!.x).isEqualTo(displayWidth - boundsWidth) + assertThat(overlayViewParams!!.x).isEqualTo(displayWidth) assertThat(overlayViewParams!!.y).isEqualTo(sensorLocation.sensorLocationX) } } @@ -242,7 +240,6 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() { @Test fun updatesOverlayViewParams_onDisplayRotationChange_yAlignedSensor() { kosmos.testScope.runTest { - mSetFlagsRule.disableFlags(FLAG_CONSTRAINT_BP) setupTestConfiguration( DeviceConfig.Y_ALIGNED, rotation = DisplayRotation.ROTATION_0, @@ -256,7 +253,7 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() { runCurrent() assertThat(overlayViewParams).isNotNull() - assertThat(overlayViewParams!!.x).isEqualTo(displayWidth - boundsWidth) + assertThat(overlayViewParams!!.x).isEqualTo(displayWidth) assertThat(overlayViewParams!!.y).isEqualTo(sensorLocation.sensorLocationY) kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90) @@ -278,7 +275,7 @@ class SideFpsOverlayViewModelTest : SysuiTestCase() { .isEqualTo( displayWidth - sensorLocation.sensorLocationY - sensorLocation.sensorRadius * 2 ) - assertThat(overlayViewParams!!.y).isEqualTo(displayHeight - boundsHeight) + assertThat(overlayViewParams!!.y).isEqualTo(displayHeight) } } |