diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 7c6792c..d10a3fe 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -29,7 +29,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.provider.Settings;
 import android.util.Log;
 import android.view.WindowManager;
 
@@ -46,8 +45,6 @@
  */
 public class AuthController extends SystemUI implements CommandQueue.Callbacks,
         AuthDialogCallback {
-    private static final String DISABLE_NEW_DIALOG =
-            "com.android.systemui.biometrics.AuthController.DISABLE_NEW_DIALOG";
 
     private static final String TAG = "BiometricPrompt/AuthController";
     private static final boolean DEBUG = true;
@@ -316,25 +313,13 @@
 
     protected AuthDialog buildDialog(Bundle biometricPromptBundle, boolean requireConfirmation,
             int userId, int type, String opPackageName, boolean skipIntro) {
-        if (Settings.Secure.getIntForUser(
-                mContext.getContentResolver(), DISABLE_NEW_DIALOG, userId, 0) == 0) {
-            return new AuthContainerView.Builder(mContext)
-                    .setCallback(this)
-                    .setBiometricPromptBundle(biometricPromptBundle)
-                    .setRequireConfirmation(requireConfirmation)
-                    .setUserId(userId)
-                    .setOpPackageName(opPackageName)
-                    .setSkipIntro(skipIntro)
-                    .build(type);
-        } else {
-            return new BiometricDialogView.Builder(mContext)
-                    .setCallback(this)
-                    .setBiometricPromptBundle(biometricPromptBundle)
-                    .setRequireConfirmation(requireConfirmation)
-                    .setUserId(userId)
-                    .setOpPackageName(opPackageName)
-                    .setSkipIntro(skipIntro)
-                    .build(type);
-        }
+        return new AuthContainerView.Builder(mContext)
+                .setCallback(this)
+                .setBiometricPromptBundle(biometricPromptBundle)
+                .setRequireConfirmation(requireConfirmation)
+                .setUserId(userId)
+                .setOpPackageName(opPackageName)
+                .setSkipIntro(skipIntro)
+                .build(type);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
deleted file mode 100644
index b985e1c..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ /dev/null
@@ -1,963 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.graphics.Outline;
-import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricPrompt;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.UserManager;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewOutlineProvider;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.Interpolator;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.util.leak.RotationUtils;
-
-/**
- * Abstract base class. Shows a dialog for BiometricPrompt.
- */
-public abstract class BiometricDialogView extends LinearLayout implements AuthDialog {
-
-    private static final String TAG = "BiometricPrompt/DialogView";
-
-    public static final String KEY_TRY_AGAIN_VISIBILITY = "key_try_again_visibility";
-    public static final String KEY_CONFIRM_VISIBILITY = "key_confirm_visibility";
-    public static final String KEY_CONFIRM_ENABLED = "key_confirm_enabled";
-    public static final String KEY_STATE = "key_state";
-    public static final String KEY_ERROR_TEXT_VISIBILITY = "key_error_text_visibility";
-    public static final String KEY_ERROR_TEXT_STRING = "key_error_text_string";
-    public static final String KEY_ERROR_TEXT_IS_TEMPORARY = "key_error_text_is_temporary";
-    public static final String KEY_ERROR_TEXT_COLOR = "key_error_text_color";
-    public static final String KEY_DIALOG_SIZE = "key_dialog_size";
-
-    private static final int ANIMATION_DURATION_SHOW = 250; // ms
-    private static final int ANIMATION_DURATION_AWAY = 350; // ms
-
-    protected static final int MSG_RESET_MESSAGE = 1;
-
-    protected static final int STATE_IDLE = 0;
-    protected static final int STATE_AUTHENTICATING = 1;
-    protected static final int STATE_ERROR = 2;
-    protected static final int STATE_PENDING_CONFIRMATION = 3;
-    protected static final int STATE_AUTHENTICATED = 4;
-
-    // Dialog layout/animation
-    private static final int IMPLICIT_Y_PADDING = 16; // dp
-    private static final int GROW_DURATION = 150; // ms
-    private static final int TEXT_ANIMATE_DISTANCE = 32; // dp
-    @VisibleForTesting static final int SIZE_UNKNOWN = 0;
-    @VisibleForTesting static final int SIZE_SMALL = 1;
-    @VisibleForTesting static final int SIZE_GROWING = 2;
-    @VisibleForTesting static final int SIZE_BIG = 3;
-    @IntDef({SIZE_UNKNOWN, SIZE_SMALL, SIZE_GROWING, SIZE_BIG})
-    @interface DialogSize {}
-
-    @VisibleForTesting final WakefulnessLifecycle mWakefulnessLifecycle;
-    private final AccessibilityManager mAccessibilityManager;
-    private final IBinder mWindowToken = new Binder();
-    private final Interpolator mLinearOutSlowIn;
-    private final WindowManager mWindowManager;
-    private final UserManager mUserManager;
-    private final DevicePolicyManager mDevicePolicyManager;
-    private final float mAnimationTranslationOffset;
-    private final int mErrorColor;
-    private final float mDialogWidth;
-    protected final AuthDialogCallback mCallback;
-    private final DialogOutlineProvider mOutlineProvider = new DialogOutlineProvider();
-
-    protected final ViewGroup mLayout;
-    protected final LinearLayout mDialog;
-    @VisibleForTesting final TextView mTitleText;
-    @VisibleForTesting final TextView mSubtitleText;
-    @VisibleForTesting final TextView mDescriptionText;
-    @VisibleForTesting final ImageView mBiometricIcon;
-    @VisibleForTesting final TextView mErrorText;
-    @VisibleForTesting final Button mPositiveButton;
-    @VisibleForTesting final Button mNegativeButton;
-    @VisibleForTesting final Button mTryAgainButton;
-
-    protected final int mTextColor;
-
-    private Bundle mBundle;
-    private Bundle mRestoredState;
-    private String mOpPackageName;
-
-    private int mState = STATE_IDLE;
-    private boolean mWasForceRemoved;
-    private boolean mSkipIntro;
-    protected boolean mRequireConfirmation;
-    private int mUserId; // used to determine if we should show work background
-    private @DialogSize int mSize;
-    private float mIconOriginalY;
-
-    private boolean mCompletedAnimatingIn;
-    private boolean mPendingDismissDialog;
-
-    protected abstract int getHintStringResourceId();
-    protected abstract int getAuthenticatedAccessibilityResourceId();
-    protected abstract int getIconDescriptionResourceId();
-    protected abstract int getDelayAfterAuthenticatedDurationMs();
-    protected abstract boolean shouldGrayAreaDismissDialog();
-    protected abstract void handleResetMessage();
-    protected abstract void updateIcon(int oldState, int newState);
-    protected abstract boolean supportsSmallDialog();
-
-    private final Runnable mShowAnimationRunnable = new Runnable() {
-        @Override
-        public void run() {
-            mLayout.animate()
-                    .alpha(1f)
-                    .setDuration(ANIMATION_DURATION_SHOW)
-                    .setInterpolator(mLinearOutSlowIn)
-                    .withLayer()
-                    .start();
-            mDialog.animate()
-                    .translationY(0)
-                    .setDuration(ANIMATION_DURATION_SHOW)
-                    .setInterpolator(mLinearOutSlowIn)
-                    .withLayer()
-                    .withEndAction(() -> onDialogAnimatedIn())
-                    .start();
-        }
-    };
-
-    @VisibleForTesting
-    final WakefulnessLifecycle.Observer mWakefulnessObserver =
-            new WakefulnessLifecycle.Observer() {
-                @Override
-                public void onStartedGoingToSleep() {
-                    animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
-                }
-            };
-
-    private final class DialogOutlineProvider extends ViewOutlineProvider {
-
-        float mY;
-
-        @Override
-        public void getOutline(View view, Outline outline) {
-            outline.setRoundRect(
-                    0 /* left */,
-                    (int) mY, /* top */
-                    mDialog.getWidth() /* right */,
-                    mDialog.getBottom(), /* bottom */
-                    getResources().getDimension(R.dimen.biometric_dialog_corner_size));
-        }
-
-        int calculateSmall() {
-            final float padding = Utils.dpToPixels(mContext, IMPLICIT_Y_PADDING);
-            return mDialog.getHeight() - mBiometricIcon.getHeight() - 2 * (int) padding;
-        }
-
-        void setOutlineY(float y) {
-            mY = y;
-        }
-    }
-
-    protected Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch(msg.what) {
-                case MSG_RESET_MESSAGE:
-                    handleResetMessage();
-                    break;
-                default:
-                    Log.e(TAG, "Unhandled message: " + msg.what);
-                    break;
-            }
-        }
-    };
-
-    /**
-     * Builds the dialog with specified parameters.
-     */
-    public static class Builder {
-        public static final int TYPE_FINGERPRINT = BiometricAuthenticator.TYPE_FINGERPRINT;
-        public static final int TYPE_FACE = BiometricAuthenticator.TYPE_FACE;
-
-        private Context mContext;
-        private AuthDialogCallback mCallback;
-        private Bundle mBundle;
-        private boolean mRequireConfirmation;
-        private int mUserId;
-        private String mOpPackageName;
-        private boolean mSkipIntro;
-
-        public Builder(Context context) {
-            mContext = context;
-        }
-
-        public Builder setCallback(AuthDialogCallback callback) {
-            mCallback = callback;
-            return this;
-        }
-
-        public Builder setBiometricPromptBundle(Bundle bundle) {
-            mBundle = bundle;
-            return this;
-        }
-
-        public Builder setRequireConfirmation(boolean requireConfirmation) {
-            mRequireConfirmation = requireConfirmation;
-            return this;
-        }
-
-        public Builder setUserId(int userId) {
-            mUserId = userId;
-            return this;
-        }
-
-        public Builder setOpPackageName(String opPackageName) {
-            mOpPackageName = opPackageName;
-            return this;
-        }
-
-        public Builder setSkipIntro(boolean skipIntro) {
-            mSkipIntro = skipIntro;
-            return this;
-        }
-
-        public BiometricDialogView build(int type) {
-            return build(type, new Injector());
-        }
-
-        public BiometricDialogView build(int type, Injector injector) {
-            BiometricDialogView dialog;
-            if (type == TYPE_FINGERPRINT) {
-                dialog = new FingerprintDialogView(mContext, mCallback, injector);
-            } else if (type == TYPE_FACE) {
-                dialog = new FaceDialogView(mContext, mCallback, injector);
-            } else {
-                return null;
-            }
-            dialog.setBundle(mBundle);
-            dialog.setRequireConfirmation(mRequireConfirmation);
-            dialog.setUserId(mUserId);
-            dialog.setOpPackageName(mOpPackageName);
-            dialog.setSkipIntro(mSkipIntro);
-            return dialog;
-        }
-    }
-
-    public static class Injector {
-        public WakefulnessLifecycle getWakefulnessLifecycle() {
-            return Dependency.get(WakefulnessLifecycle.class);
-        }
-    }
-
-    protected BiometricDialogView(Context context, AuthDialogCallback callback, Injector injector) {
-        super(context);
-        mWakefulnessLifecycle = injector.getWakefulnessLifecycle();
-
-        mCallback = callback;
-        mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
-        mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
-        mWindowManager = mContext.getSystemService(WindowManager.class);
-        mUserManager = mContext.getSystemService(UserManager.class);
-        mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
-        mAnimationTranslationOffset = getResources()
-                .getDimension(R.dimen.biometric_dialog_animation_translation_offset);
-        mErrorColor = getResources().getColor(R.color.biometric_dialog_error);
-        mTextColor = getResources().getColor(R.color.biometric_dialog_gray);
-
-        DisplayMetrics metrics = new DisplayMetrics();
-        mWindowManager.getDefaultDisplay().getMetrics(metrics);
-        mDialogWidth = Math.min(metrics.widthPixels, metrics.heightPixels);
-
-        // Create the dialog
-        LayoutInflater factory = LayoutInflater.from(getContext());
-        mLayout = (ViewGroup) factory.inflate(R.layout.biometric_dialog, this, false);
-        addView(mLayout);
-
-        mLayout.setOnKeyListener(new View.OnKeyListener() {
-            @Override
-            public boolean onKey(View v, int keyCode, KeyEvent event) {
-                if (keyCode != KeyEvent.KEYCODE_BACK) {
-                    return false;
-                }
-                if (event.getAction() == KeyEvent.ACTION_UP) {
-                    animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
-                }
-                return true;
-            }
-        });
-
-        final View space = mLayout.findViewById(R.id.space);
-        final View leftSpace = mLayout.findViewById(R.id.left_space);
-        final View rightSpace = mLayout.findViewById(R.id.right_space);
-
-        mDialog = mLayout.findViewById(R.id.dialog);
-        mTitleText = mLayout.findViewById(R.id.title);
-        mSubtitleText = mLayout.findViewById(R.id.subtitle);
-        mDescriptionText = mLayout.findViewById(R.id.description);
-        mBiometricIcon = mLayout.findViewById(R.id.biometric_icon);
-        mErrorText = mLayout.findViewById(R.id.error);
-        mNegativeButton = mLayout.findViewById(R.id.button2);
-        mPositiveButton = mLayout.findViewById(R.id.button1);
-        mTryAgainButton = mLayout.findViewById(R.id.button_try_again);
-
-        mBiometricIcon.setContentDescription(
-                getResources().getString(getIconDescriptionResourceId()));
-
-        setDismissesDialog(space);
-        setDismissesDialog(leftSpace);
-        setDismissesDialog(rightSpace);
-
-        mNegativeButton.setOnClickListener((View v) -> {
-            if (mState == STATE_PENDING_CONFIRMATION || mState == STATE_AUTHENTICATED) {
-                animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
-            } else {
-                animateAway(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE);
-            }
-        });
-
-        mPositiveButton.setOnClickListener((View v) -> {
-            updateState(STATE_AUTHENTICATED);
-            mHandler.postDelayed(() -> {
-                animateAway(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE);
-            }, getDelayAfterAuthenticatedDurationMs());
-        });
-
-        mTryAgainButton.setOnClickListener((View v) -> {
-            handleResetMessage();
-            updateState(STATE_AUTHENTICATING);
-            showTryAgainButton(false /* show */);
-
-            mPositiveButton.setVisibility(View.VISIBLE);
-            mPositiveButton.setEnabled(false);
-
-            mCallback.onTryAgainPressed();
-        });
-
-        // Must set these in order for the back button events to be received.
-        mLayout.setFocusableInTouchMode(true);
-        mLayout.requestFocus();
-    }
-
-    @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
-
-        final ImageView backgroundView = mLayout.findViewById(R.id.background);
-        if (mUserManager.isManagedProfile(mUserId)) {
-            final Drawable image = getResources().getDrawable(R.drawable.work_challenge_background,
-                    mContext.getTheme());
-            image.setColorFilter(mDevicePolicyManager.getOrganizationColorForUser(mUserId),
-                    PorterDuff.Mode.DARKEN);
-            backgroundView.setScaleType(ImageView.ScaleType.CENTER_CROP);
-            backgroundView.setImageDrawable(image);
-        } else {
-            backgroundView.setImageDrawable(null);
-            backgroundView.setBackgroundColor(R.color.biometric_dialog_dim_color);
-        }
-
-        mNegativeButton.setVisibility(View.VISIBLE);
-        mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));
-
-        if (RotationUtils.getRotation(mContext) != RotationUtils.ROTATION_NONE) {
-            mDialog.getLayoutParams().width = (int) mDialogWidth;
-        }
-
-        if (mRestoredState == null) {
-            updateState(STATE_AUTHENTICATING);
-            final int hint = getHintStringResourceId();
-            if (hint != 0) {
-                mErrorText.setText(hint);
-                mErrorText.setContentDescription(mContext.getString(hint));
-                mErrorText.setVisibility(View.VISIBLE);
-            } else {
-                mErrorText.setVisibility(View.INVISIBLE);
-            }
-            announceAccessibilityEvent();
-        } else {
-            updateState(mState);
-        }
-
-        CharSequence titleText = mBundle.getCharSequence(BiometricPrompt.KEY_TITLE);
-
-        mTitleText.setVisibility(View.VISIBLE);
-        mTitleText.setText(titleText);
-
-        final CharSequence subtitleText = mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE);
-        if (TextUtils.isEmpty(subtitleText)) {
-            mSubtitleText.setVisibility(View.GONE);
-            announceAccessibilityEvent();
-        } else {
-            mSubtitleText.setVisibility(View.VISIBLE);
-            mSubtitleText.setText(subtitleText);
-        }
-
-        final CharSequence descriptionText =
-                mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION);
-        if (TextUtils.isEmpty(descriptionText)) {
-            mDescriptionText.setVisibility(View.GONE);
-            announceAccessibilityEvent();
-        } else {
-            mDescriptionText.setVisibility(View.VISIBLE);
-            mDescriptionText.setText(descriptionText);
-        }
-
-        if (requiresConfirmation() && mRestoredState == null) {
-            mPositiveButton.setVisibility(View.VISIBLE);
-            mPositiveButton.setEnabled(false);
-        }
-
-        if (mWasForceRemoved || mSkipIntro) {
-            // Show the dialog immediately
-            mLayout.animate().cancel();
-            mDialog.animate().cancel();
-            mDialog.setAlpha(1.0f);
-            mDialog.setTranslationY(0);
-            mLayout.setAlpha(1.0f);
-            mCompletedAnimatingIn = true;
-        } else {
-            // Dim the background and slide the dialog up
-            mDialog.setTranslationY(mAnimationTranslationOffset);
-            mLayout.setAlpha(0f);
-            postOnAnimation(mShowAnimationRunnable);
-        }
-        mWasForceRemoved = false;
-        mSkipIntro = false;
-    }
-
-    /**
-     * Do small/big layout here instead of onAttachedToWindow, since:
-     * 1) We need the big layout to be measured, etc for small -> big animation
-     * 2) We need the dialog measurements to know where to move the biometric icon to
-     *
-     * BiometricDialogView already sets the views to their default big state, so here we only
-     * need to hide the ones that are unnecessary.
-     */
-    @Override
-    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-
-        if (mIconOriginalY == 0) {
-            mIconOriginalY = mBiometricIcon.getY();
-        }
-
-        // UNKNOWN means size hasn't been set yet. First time we create the dialog.
-        // onLayout can happen when visibility of views change (during animation, etc).
-        if (getSize() != SIZE_UNKNOWN) {
-            // Probably not the cleanest way to do this, but since dialog is big by default,
-            // and small dialogs can persist across orientation changes, we need to set it to
-            // small size here again.
-            if (getSize() == SIZE_SMALL) {
-                updateSize(SIZE_SMALL);
-            }
-            return;
-        }
-
-        // If we don't require confirmation, show the small dialog first (until errors occur).
-        if (!requiresConfirmation() && supportsSmallDialog()) {
-            updateSize(SIZE_SMALL);
-        } else {
-            updateSize(SIZE_BIG);
-        }
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
-        mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
-    }
-
-    @VisibleForTesting
-    void updateSize(@DialogSize int newSize) {
-        final float padding = Utils.dpToPixels(mContext, IMPLICIT_Y_PADDING);
-        final float iconSmallPositionY = mDialog.getHeight() - mBiometricIcon.getHeight() - padding;
-
-        if (newSize == SIZE_SMALL) {
-            if (!supportsSmallDialog()) {
-                Log.e(TAG, "Small dialog unsupported");
-                return;
-            }
-
-            // These fields are required and/or always hold a spot on the UI, so should be set to
-            // INVISIBLE so they keep their position
-            mTitleText.setVisibility(View.INVISIBLE);
-            mErrorText.setVisibility(View.INVISIBLE);
-            mNegativeButton.setVisibility(View.INVISIBLE);
-
-            // These fields are optional, so set them to gone or invisible depending on their
-            // usage. If they're empty, they're already set to GONE in BiometricDialogView.
-            if (!TextUtils.isEmpty(mSubtitleText.getText())) {
-                mSubtitleText.setVisibility(View.INVISIBLE);
-            }
-            if (!TextUtils.isEmpty(mDescriptionText.getText())) {
-                mDescriptionText.setVisibility(View.INVISIBLE);
-            }
-
-            // Move the biometric icon to the small spot
-            mBiometricIcon.setY(iconSmallPositionY);
-
-            // Clip the dialog to the small size
-            mDialog.setOutlineProvider(mOutlineProvider);
-            mOutlineProvider.setOutlineY(mOutlineProvider.calculateSmall());
-
-            mDialog.setClipToOutline(true);
-            mDialog.invalidateOutline();
-
-            mSize = newSize;
-            announceAccessibilityEvent();
-        } else if (mSize == SIZE_SMALL && newSize == SIZE_BIG) {
-            mSize = SIZE_GROWING;
-
-            // Animate the outline
-            final ValueAnimator outlineAnimator =
-                    ValueAnimator.ofFloat(mOutlineProvider.calculateSmall(), 0);
-            outlineAnimator.addUpdateListener((animation) -> {
-                final float y = (float) animation.getAnimatedValue();
-                mOutlineProvider.setOutlineY(y);
-                mDialog.invalidateOutline();
-            });
-
-            // Animate the icon back to original big position
-            final ValueAnimator iconAnimator =
-                    ValueAnimator.ofFloat(iconSmallPositionY, mIconOriginalY);
-            iconAnimator.addUpdateListener((animation) -> {
-                final float y = (float) animation.getAnimatedValue();
-                mBiometricIcon.setY(y);
-            });
-
-            // Animate the error text so it slides up with the icon
-            final ValueAnimator textSlideAnimator =
-                    ValueAnimator.ofFloat(Utils.dpToPixels(mContext, TEXT_ANIMATE_DISTANCE), 0);
-            textSlideAnimator.addUpdateListener((animation) -> {
-                final float y = (float) animation.getAnimatedValue();
-                mErrorText.setTranslationY(y);
-            });
-
-            // Opacity animator for things that should fade in (title, subtitle, details, negative
-            // button)
-            final ValueAnimator opacityAnimator = ValueAnimator.ofFloat(0, 1);
-            opacityAnimator.addUpdateListener((animation) -> {
-                final float opacity = (float) animation.getAnimatedValue();
-
-                // These fields are required and/or always hold a spot on the UI
-                mTitleText.setAlpha(opacity);
-                mErrorText.setAlpha(opacity);
-                mNegativeButton.setAlpha(opacity);
-                mTryAgainButton.setAlpha(opacity);
-
-                // These fields are optional, so only animate them if they're supposed to be showing
-                if (!TextUtils.isEmpty(mSubtitleText.getText())) {
-                    mSubtitleText.setAlpha(opacity);
-                }
-                if (!TextUtils.isEmpty(mDescriptionText.getText())) {
-                    mDescriptionText.setAlpha(opacity);
-                }
-            });
-
-            // Choreograph together
-            final AnimatorSet as = new AnimatorSet();
-            as.setDuration(GROW_DURATION);
-            as.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    super.onAnimationStart(animation);
-                    // Set the visibility of opacity-animating views back to VISIBLE
-                    mTitleText.setVisibility(View.VISIBLE);
-                    mErrorText.setVisibility(View.VISIBLE);
-                    mNegativeButton.setVisibility(View.VISIBLE);
-                    mTryAgainButton.setVisibility(View.VISIBLE);
-
-                    if (!TextUtils.isEmpty(mSubtitleText.getText())) {
-                        mSubtitleText.setVisibility(View.VISIBLE);
-                    }
-                    if (!TextUtils.isEmpty(mDescriptionText.getText())) {
-                        mDescriptionText.setVisibility(View.VISIBLE);
-                    }
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    super.onAnimationEnd(animation);
-                    mSize = SIZE_BIG;
-                }
-            });
-            as.play(outlineAnimator).with(iconAnimator).with(opacityAnimator)
-                    .with(textSlideAnimator);
-            as.start();
-        } else if (mSize == SIZE_BIG) {
-            mDialog.setClipToOutline(false);
-            mDialog.invalidateOutline();
-
-            mBiometricIcon.setY(mIconOriginalY);
-
-            mSize = newSize;
-        }
-    }
-
-    private void setDismissesDialog(View v) {
-        v.setClickable(true);
-        v.setOnClickListener(v1 -> {
-            if (mState != STATE_AUTHENTICATED && shouldGrayAreaDismissDialog()) {
-                animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
-            }
-        });
-    }
-
-    private void animateAway(@AuthDialogCallback.DismissedReason int reason) {
-        animateAway(true /* sendReason */, reason);
-    }
-
-    /**
-     * Animate the dialog away
-     * @param reason one of the {@link AuthDialogCallback} codes
-     */
-    private void animateAway(boolean sendReason, @AuthDialogCallback.DismissedReason int reason) {
-        if (!mCompletedAnimatingIn) {
-            Log.w(TAG, "startDismiss(): waiting for onDialogAnimatedIn");
-            mPendingDismissDialog = true;
-            return;
-        }
-
-        // This is where final cleanup should occur.
-        final Runnable endActionRunnable = new Runnable() {
-            @Override
-            public void run() {
-                mWindowManager.removeView(BiometricDialogView.this);
-                // Set the icons / text back to normal state
-                handleResetMessage();
-                showTryAgainButton(false /* show */);
-                updateState(STATE_IDLE);
-                if (sendReason) {
-                    mCallback.onDismissed(reason);
-                }
-            }
-        };
-
-        postOnAnimation(new Runnable() {
-            @Override
-            public void run() {
-                mLayout.animate()
-                        .alpha(0f)
-                        .setDuration(ANIMATION_DURATION_AWAY)
-                        .setInterpolator(mLinearOutSlowIn)
-                        .withLayer()
-                        .start();
-                mDialog.animate()
-                        .translationY(mAnimationTranslationOffset)
-                        .setDuration(ANIMATION_DURATION_AWAY)
-                        .setInterpolator(mLinearOutSlowIn)
-                        .withLayer()
-                        .withEndAction(endActionRunnable)
-                        .start();
-            }
-        });
-    }
-
-    /**
-     * Skip the intro animation
-     */
-    private void setSkipIntro(boolean skip) {
-        mSkipIntro = skip;
-    }
-
-    private void setBundle(Bundle bundle) {
-        mBundle = bundle;
-    }
-
-    private void setRequireConfirmation(boolean requireConfirmation) {
-        mRequireConfirmation = requireConfirmation;
-    }
-
-    protected boolean requiresConfirmation() {
-        return mRequireConfirmation;
-    }
-
-    private void setUserId(int userId) {
-        mUserId = userId;
-    }
-
-    private void setOpPackageName(String opPackageName) {
-        mOpPackageName = opPackageName;
-    }
-
-    // Shows an error/help message
-    protected void showTemporaryMessage(String message) {
-        mHandler.removeMessages(MSG_RESET_MESSAGE);
-        mErrorText.setText(message);
-        mErrorText.setTextColor(mErrorColor);
-        mErrorText.setContentDescription(message);
-        mErrorText.setVisibility(View.VISIBLE);
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
-                BiometricPrompt.HIDE_DIALOG_DELAY);
-    }
-
-    @Override
-    public void show(WindowManager wm, @Nullable Bundle savedState) {
-        if (savedState != null) {
-            restoreState(savedState);
-        }
-        wm.addView(this, getLayoutParams(mWindowToken));
-    }
-
-    /**
-     * Force remove the window, cancelling any animation that's happening. This should only be
-     * called if we want to quickly show the dialog again (e.g. on rotation). Calling this method
-     * will cause the dialog to show without an animation the next time it's attached.
-     */
-    @Override
-    public void dismissWithoutCallback(boolean animate) {
-        if (animate) {
-            animateAway(false /* sendReason */, 0 /* reason */);
-        } else {
-            mLayout.animate().cancel();
-            mDialog.animate().cancel();
-            mWindowManager.removeView(BiometricDialogView.this);
-            mWasForceRemoved = true;
-        }
-    }
-
-    @Override
-    public void dismissFromSystemServer() {
-        animateAway(AuthDialogCallback.DISMISSED_BY_SYSTEM_SERVER);
-    }
-
-    @Override
-    public void onAuthenticationSucceeded() {
-        announceForAccessibility(getResources().getText(getAuthenticatedAccessibilityResourceId()));
-
-        if (requiresConfirmation()) {
-            updateState(STATE_PENDING_CONFIRMATION);
-        } else {
-            mHandler.postDelayed(() -> {
-                animateAway(AuthDialogCallback.DISMISSED_AUTHENTICATED);
-            }, getDelayAfterAuthenticatedDurationMs());
-
-            updateState(STATE_AUTHENTICATED);
-        }
-    }
-
-
-    @Override
-    public void onAuthenticationFailed(String message) {
-        updateState(STATE_ERROR);
-        showTemporaryMessage(message);
-    }
-
-    /**
-     * Transient help message (acquire) is received, dialog stays showing. Sensor stays in
-     * "authenticating" state.
-     * @param message
-     */
-    @Override
-    public void onHelp(String message) {
-        updateState(STATE_ERROR);
-        showTemporaryMessage(message);
-    }
-
-    /**
-     * Hard error is received, dialog will be dismissed soon.
-     * @param error
-     */
-    @Override
-    public void onError(String error) {
-        // All error messages will cause the dialog to go from small -> big. Error messages
-        // are messages such as lockout, auth failed, etc.
-        if (mSize == SIZE_SMALL) {
-            updateSize(SIZE_BIG);
-        }
-
-        updateState(STATE_ERROR);
-        showTemporaryMessage(error);
-        showTryAgainButton(false /* show */);
-
-        mHandler.postDelayed(() -> {
-            animateAway(AuthDialogCallback.DISMISSED_ERROR);
-        }, BiometricPrompt.HIDE_DIALOG_DELAY);
-    }
-
-
-    @Override
-    public void onSaveState(Bundle bundle) {
-        bundle.putInt(KEY_TRY_AGAIN_VISIBILITY, mTryAgainButton.getVisibility());
-        bundle.putInt(KEY_CONFIRM_VISIBILITY, mPositiveButton.getVisibility());
-        bundle.putBoolean(KEY_CONFIRM_ENABLED, mPositiveButton.isEnabled());
-        bundle.putInt(KEY_STATE, mState);
-        bundle.putInt(KEY_ERROR_TEXT_VISIBILITY, mErrorText.getVisibility());
-        bundle.putCharSequence(KEY_ERROR_TEXT_STRING, mErrorText.getText());
-        bundle.putBoolean(KEY_ERROR_TEXT_IS_TEMPORARY, mHandler.hasMessages(MSG_RESET_MESSAGE));
-        bundle.putInt(KEY_ERROR_TEXT_COLOR, mErrorText.getCurrentTextColor());
-        bundle.putInt(KEY_DIALOG_SIZE, mSize);
-    }
-
-    public void restoreState(Bundle bundle) {
-        mRestoredState = bundle;
-
-        // Keep in mind that this happens before onAttachedToWindow()
-        mSize = bundle.getInt(KEY_DIALOG_SIZE);
-
-        final int tryAgainVisibility = bundle.getInt(KEY_TRY_AGAIN_VISIBILITY);
-        mTryAgainButton.setVisibility(tryAgainVisibility);
-        final int confirmVisibility = bundle.getInt(KEY_CONFIRM_VISIBILITY);
-        mPositiveButton.setVisibility(confirmVisibility);
-        final boolean confirmEnabled = bundle.getBoolean(KEY_CONFIRM_ENABLED);
-        mPositiveButton.setEnabled(confirmEnabled);
-        mState = bundle.getInt(KEY_STATE);
-        mErrorText.setText(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
-        mErrorText.setContentDescription(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
-        final int errorTextVisibility = bundle.getInt(KEY_ERROR_TEXT_VISIBILITY);
-        mErrorText.setVisibility(errorTextVisibility);
-        if (errorTextVisibility == View.INVISIBLE || tryAgainVisibility == View.INVISIBLE
-                || confirmVisibility == View.INVISIBLE) {
-            announceAccessibilityEvent();
-        }
-        mErrorText.setTextColor(bundle.getInt(KEY_ERROR_TEXT_COLOR));
-        if (bundle.getBoolean(KEY_ERROR_TEXT_IS_TEMPORARY)) {
-            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
-                    BiometricPrompt.HIDE_DIALOG_DELAY);
-        }
-    }
-
-    @Override
-    public String getOpPackageName() {
-        return mOpPackageName;
-    }
-
-    protected void updateState(int newState) {
-        if (newState == STATE_PENDING_CONFIRMATION) {
-            mHandler.removeMessages(MSG_RESET_MESSAGE);
-            mErrorText.setTextColor(mTextColor);
-            mErrorText.setText(R.string.biometric_dialog_tap_confirm);
-            mErrorText.setContentDescription(
-                    getResources().getString(R.string.biometric_dialog_tap_confirm));
-            mErrorText.setVisibility(View.VISIBLE);
-            announceAccessibilityEvent();
-            mPositiveButton.setVisibility(View.VISIBLE);
-            mPositiveButton.setEnabled(true);
-        } else if (newState == STATE_AUTHENTICATED) {
-            mPositiveButton.setVisibility(View.GONE);
-            mNegativeButton.setVisibility(View.GONE);
-            mErrorText.setVisibility(View.INVISIBLE);
-            announceAccessibilityEvent();
-        }
-
-        if (newState == STATE_PENDING_CONFIRMATION || newState == STATE_AUTHENTICATED) {
-            mNegativeButton.setText(R.string.cancel);
-            mNegativeButton.setContentDescription(getResources().getString(R.string.cancel));
-        }
-
-        updateIcon(mState, newState);
-        mState = newState;
-    }
-
-    protected @DialogSize int getSize() {
-        return mSize;
-    }
-
-    protected void showTryAgainButton(boolean show) {
-        if (show && getSize() == SIZE_SMALL) {
-            // Do not call super, we will nicely animate the alpha together with the rest
-            // of the elements in here.
-            updateSize(SIZE_BIG);
-        } else {
-            if (show) {
-                mTryAgainButton.setVisibility(View.VISIBLE);
-            } else {
-                mTryAgainButton.setVisibility(View.GONE);
-                announceAccessibilityEvent();
-            }
-        }
-
-        if (show) {
-            mPositiveButton.setVisibility(View.GONE);
-            announceAccessibilityEvent();
-        }
-    }
-
-    protected void onDialogAnimatedIn() {
-        mCompletedAnimatingIn = true;
-
-        if (mPendingDismissDialog) {
-            Log.d(TAG, "onDialogAnimatedIn(): mPendingDismissDialog=true, dismissing now");
-            animateAway(false /* sendReason */, 0);
-            mPendingDismissDialog = false;
-        }
-    }
-
-    /**
-     * @param windowToken token for the window
-     * @return
-     */
-    public static WindowManager.LayoutParams getLayoutParams(IBinder windowToken) {
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                ViewGroup.LayoutParams.MATCH_PARENT,
-                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
-                PixelFormat.TRANSLUCENT);
-        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-        lp.setTitle("BiometricDialogView");
-        lp.token = windowToken;
-        return lp;
-    }
-
-    // Every time a view becomes invisible we need to announce an accessibility event.
-    // This is due to an issue in the framework, b/132298701 recommended this workaround.
-    protected void announceAccessibilityEvent() {
-        if (!mAccessibilityManager.isEnabled()) {
-            return;
-        }
-        AccessibilityEvent event = AccessibilityEvent.obtain();
-        event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
-        event.setContentChangeTypes(CONTENT_CHANGE_TYPE_SUBTREE);
-        mDialog.sendAccessibilityEventUnchecked(event);
-        mDialog.notifySubtreeAccessibilityStateChanged(mDialog, mDialog,
-                CONTENT_CHANGE_TYPE_SUBTREE);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
deleted file mode 100644
index d5dcbf1..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.content.Context;
-import android.graphics.drawable.Animatable2;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
-import android.hardware.biometrics.BiometricPrompt;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-
-import com.android.systemui.R;
-
-/**
- * This class loads the view for the system-provided dialog. The view consists of:
- * Application Icon, Title, Subtitle, Description, Biometric Icon, Error/Help message area,
- * and positive/negative buttons.
- */
-public class FaceDialogView extends BiometricDialogView {
-
-    private static final String TAG = "BiometricPrompt/FaceDialogView";
-
-    private static final String KEY_DIALOG_ANIMATED_IN = "key_dialog_animated_in";
-
-    private static final int HIDE_DIALOG_DELAY = 500; // ms
-
-    private IconController mIconController;
-    private boolean mDialogAnimatedIn;
-
-    /**
-     * Class that handles the biometric icon animations.
-     */
-    private final class IconController extends Animatable2.AnimationCallback {
-
-        private boolean mLastPulseDirection; // false = dark to light, true = light to dark
-
-        int mState;
-
-        IconController() {
-            mState = STATE_IDLE;
-        }
-
-        public void animateOnce(int iconRes) {
-            animateIcon(iconRes, false);
-        }
-
-        public void showStatic(int iconRes) {
-            mBiometricIcon.setImageDrawable(mContext.getDrawable(iconRes));
-        }
-
-        public void startPulsing() {
-            mLastPulseDirection = false;
-            animateIcon(R.drawable.face_dialog_pulse_dark_to_light, true);
-        }
-
-        public void showIcon(int iconRes) {
-            final Drawable drawable = mContext.getDrawable(iconRes);
-            mBiometricIcon.setImageDrawable(drawable);
-        }
-
-        private void animateIcon(int iconRes, boolean repeat) {
-            final AnimatedVectorDrawable icon =
-                    (AnimatedVectorDrawable) mContext.getDrawable(iconRes);
-            mBiometricIcon.setImageDrawable(icon);
-            icon.forceAnimationOnUI();
-            if (repeat) {
-                icon.registerAnimationCallback(this);
-            }
-            icon.start();
-        }
-
-        private void pulseInNextDirection() {
-            int iconRes = mLastPulseDirection ? R.drawable.face_dialog_pulse_dark_to_light
-                    : R.drawable.face_dialog_pulse_light_to_dark;
-            animateIcon(iconRes, true /* repeat */);
-            mLastPulseDirection = !mLastPulseDirection;
-        }
-
-        @Override
-        public void onAnimationEnd(Drawable drawable) {
-            super.onAnimationEnd(drawable);
-
-            if (mState == STATE_AUTHENTICATING) {
-                // Still authenticating, pulse the icon
-                pulseInNextDirection();
-            }
-        }
-    }
-
-    private final Runnable mErrorToIdleAnimationRunnable = () -> {
-        updateState(STATE_IDLE);
-        mErrorText.setVisibility(View.INVISIBLE);
-        announceAccessibilityEvent();
-    };
-
-    protected FaceDialogView(Context context, AuthDialogCallback callback, Injector injector) {
-        super(context, callback, injector);
-        mIconController = new IconController();
-    }
-
-    @Override
-    public void onSaveState(Bundle bundle) {
-        super.onSaveState(bundle);
-        bundle.putBoolean(KEY_DIALOG_ANIMATED_IN, mDialogAnimatedIn);
-    }
-
-
-    @Override
-    protected void handleResetMessage() {
-        mErrorText.setTextColor(mTextColor);
-        mErrorText.setVisibility(View.INVISIBLE);
-        announceAccessibilityEvent();
-    }
-
-    @Override
-    public void restoreState(Bundle bundle) {
-        super.restoreState(bundle);
-        mDialogAnimatedIn = bundle.getBoolean(KEY_DIALOG_ANIMATED_IN);
-    }
-
-    @Override
-    public void onAuthenticationFailed(String message) {
-        super.onAuthenticationFailed(message);
-        showTryAgainButton(true);
-    }
-
-    @Override
-    protected int getHintStringResourceId() {
-        return 0;
-    }
-
-    @Override
-    protected int getAuthenticatedAccessibilityResourceId() {
-        if (mRequireConfirmation) {
-            return com.android.internal.R.string.face_authenticated_confirmation_required;
-        } else {
-            return com.android.internal.R.string.face_authenticated_no_confirmation_required;
-        }
-    }
-
-    @Override
-    protected int getIconDescriptionResourceId() {
-        return R.string.accessibility_face_dialog_face_icon;
-    }
-
-    @Override
-    protected void updateIcon(int oldState, int newState) {
-        mIconController.mState = newState;
-
-        if (newState == STATE_AUTHENTICATING) {
-            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
-            if (mDialogAnimatedIn) {
-                mIconController.startPulsing();
-            } else {
-                mIconController.showIcon(R.drawable.face_dialog_pulse_dark_to_light);
-            }
-            mBiometricIcon.setContentDescription(mContext.getString(
-                    R.string.biometric_dialog_face_icon_description_authenticating));
-        } else if (oldState == STATE_PENDING_CONFIRMATION && newState == STATE_AUTHENTICATED) {
-            mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
-            mBiometricIcon.setContentDescription(mContext.getString(
-                    R.string.biometric_dialog_face_icon_description_confirmed));
-        } else if (oldState == STATE_ERROR && newState == STATE_IDLE) {
-            mIconController.animateOnce(R.drawable.face_dialog_error_to_idle);
-            mBiometricIcon.setContentDescription(mContext.getString(
-                    R.string.biometric_dialog_face_icon_description_idle));
-        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
-            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
-            mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
-            mBiometricIcon.setContentDescription(mContext.getString(
-                    R.string.biometric_dialog_face_icon_description_authenticated));
-        } else if (newState == STATE_ERROR) {
-            // It's easier to only check newState and gate showing the animation on the
-            // mErrorToIdleAnimationRunnable as a proxy, than add a ton of extra state. For example,
-            // we may go from error -> error due to configuration change which is valid and we
-            // should show the animation, or we can go from error -> error by receiving repeated
-            // acquire messages in which case we do not want to repeatedly start the animation.
-            if (!mHandler.hasCallbacks(mErrorToIdleAnimationRunnable)) {
-                mIconController.animateOnce(R.drawable.face_dialog_dark_to_error);
-                mHandler.postDelayed(mErrorToIdleAnimationRunnable,
-                        BiometricPrompt.HIDE_DIALOG_DELAY);
-            }
-        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
-            mIconController.animateOnce(R.drawable.face_dialog_dark_to_checkmark);
-            mBiometricIcon.setContentDescription(mContext.getString(
-                    R.string.biometric_dialog_face_icon_description_authenticated));
-        } else if (newState == STATE_PENDING_CONFIRMATION) {
-            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
-            mIconController.animateOnce(R.drawable.face_dialog_wink_from_dark);
-            mBiometricIcon.setContentDescription(mContext.getString(
-                    R.string.biometric_dialog_face_icon_description_authenticated));
-        } else if (newState == STATE_IDLE) {
-            mIconController.showStatic(R.drawable.face_dialog_idle_static);
-            mBiometricIcon.setContentDescription(mContext.getString(
-                    R.string.biometric_dialog_face_icon_description_idle));
-        } else {
-            Log.w(TAG, "Unknown animation from " + oldState + " -> " + newState);
-        }
-
-        // Note that this must be after the newState == STATE_ERROR check above since this affects
-        // the logic.
-        if (oldState == STATE_ERROR && newState == STATE_ERROR) {
-            // Keep the error icon and text around for a while longer if we keep receiving
-            // STATE_ERROR
-            mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
-            mHandler.postDelayed(mErrorToIdleAnimationRunnable, BiometricPrompt.HIDE_DIALOG_DELAY);
-        }
-    }
-
-    @Override
-    protected boolean supportsSmallDialog() {
-        return true;
-    }
-
-    @Override
-    public void onDialogAnimatedIn() {
-        super.onDialogAnimatedIn();
-        mDialogAnimatedIn = true;
-        mIconController.startPulsing();
-    }
-
-    @Override
-    protected int getDelayAfterAuthenticatedDurationMs() {
-        return HIDE_DIALOG_DELAY;
-    }
-
-    @Override
-    protected boolean shouldGrayAreaDismissDialog() {
-        if (getSize() == SIZE_SMALL) {
-            return false;
-        }
-        return true;
-    }
-
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
deleted file mode 100644
index cda2176..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.content.Context;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-
-import com.android.systemui.R;
-
-/**
- * This class loads the view for the system-provided dialog. The view consists of:
- * Application Icon, Title, Subtitle, Description, Biometric Icon, Error/Help message area,
- * and positive/negative buttons.
- */
-public class FingerprintDialogView extends BiometricDialogView {
-
-    private static final String TAG = "BiometricPrompt/FingerprintDialogView";
-
-    protected FingerprintDialogView(Context context, AuthDialogCallback callback,
-            Injector injector) {
-        super(context, callback, injector);
-    }
-
-    @Override
-    protected void handleResetMessage() {
-        updateState(STATE_AUTHENTICATING);
-        mErrorText.setText(getHintStringResourceId());
-        mErrorText.setTextColor(mTextColor);
-    }
-
-    @Override
-    protected int getHintStringResourceId() {
-        return R.string.fingerprint_dialog_touch_sensor;
-    }
-
-    @Override
-    protected int getAuthenticatedAccessibilityResourceId() {
-        return com.android.internal.R.string.fingerprint_authenticated;
-    }
-
-    @Override
-    protected int getIconDescriptionResourceId() {
-        return R.string.accessibility_fingerprint_dialog_fingerprint_icon;
-    }
-
-    @Override
-    protected void updateIcon(int lastState, int newState) {
-        final Drawable icon = getAnimationForTransition(lastState, newState);
-        if (icon == null) {
-            Log.e(TAG, "Animation not found, " + lastState + " -> " + newState);
-            return;
-        }
-
-        final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
-                ? (AnimatedVectorDrawable) icon
-                : null;
-
-        mBiometricIcon.setImageDrawable(icon);
-
-        if (animation != null && shouldAnimateForTransition(lastState, newState)) {
-            animation.forceAnimationOnUI();
-            animation.start();
-        }
-    }
-
-    @Override
-    protected boolean supportsSmallDialog() {
-        return false;
-    }
-
-    protected boolean shouldAnimateForTransition(int oldState, int newState) {
-        if (newState == STATE_ERROR) {
-            return true;
-        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
-            return true;
-        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
-            // TODO(b/77328470): add animation when fingerprint is authenticated
-            return false;
-        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
-            // TODO(b/77328470): add animation when fingerprint is authenticated
-            return false;
-        } else if (newState == STATE_AUTHENTICATING) {
-            return false;
-        }
-        return false;
-    }
-
-    @Override
-    protected int getDelayAfterAuthenticatedDurationMs() {
-        return 0;
-    }
-
-    @Override
-    protected boolean shouldGrayAreaDismissDialog() {
-        // Fingerprint dialog always dismisses when region outside the dialog is tapped
-        return true;
-    }
-
-    protected Drawable getAnimationForTransition(int oldState, int newState) {
-        int iconRes;
-        if (newState == STATE_ERROR) {
-            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATING) {
-            iconRes = R.drawable.fingerprint_dialog_error_to_fp;
-        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
-            // TODO(b/77328470): add animation when fingerprint is authenticated
-            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else if (oldState == STATE_ERROR && newState == STATE_AUTHENTICATED) {
-            // TODO(b/77328470): add animation when fingerprint is authenticated
-            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else if (newState == STATE_AUTHENTICATING) {
-            iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-        } else {
-            return null;
-        }
-        return mContext.getDrawable(iconRes);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDialogViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDialogViewTest.java
deleted file mode 100644
index 3ff1f38..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDialogViewTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2019 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 junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotSame;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Mockito.spy;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.hardware.biometrics.BiometricPrompt;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableContext;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.View;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-@SmallTest
-public class BiometricDialogViewTest extends SysuiTestCase {
-
-    FaceDialogView mFaceDialogView;
-
-    private static final String TITLE = "Title";
-    private static final String SUBTITLE = "Subtitle";
-    private static final String DESCRIPTION = "Description";
-    private static final String NEGATIVE_BUTTON = "Negative Button";
-
-    private static final String TEST_HELP = "Help";
-
-    TestableContext mTestableContext;
-    @Mock
-    private AuthDialogCallback mCallback;
-    @Mock
-    private UserManager mUserManager;
-    @Mock
-    private DevicePolicyManager mDpm;
-
-    private static class Injector extends BiometricDialogView.Injector {
-        @Override
-        public WakefulnessLifecycle getWakefulnessLifecycle() {
-            final WakefulnessLifecycle lifecycle = new WakefulnessLifecycle();
-            lifecycle.dispatchFinishedWakingUp();
-            return lifecycle;
-        }
-    }
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mTestableContext = spy(mContext);
-        mTestableContext.addMockSystemService(UserManager.class, mUserManager);
-        mTestableContext.addMockSystemService(DevicePolicyManager.class, mDpm);
-    }
-
-    @Test
-    public void testContentStates_confirmationRequired_authenticated() {
-        mFaceDialogView = buildFaceDialogView(mTestableContext, mCallback,
-                true /* requireConfirmation */);
-        mFaceDialogView.onAttachedToWindow();
-
-        // When starting authentication
-        assertEquals(View.VISIBLE, mFaceDialogView.mTitleText.getVisibility());
-        assertEquals(View.VISIBLE, mFaceDialogView.mSubtitleText.getVisibility());
-        assertEquals(View.VISIBLE, mFaceDialogView.mDescriptionText.getVisibility());
-        assertEquals(View.INVISIBLE, mFaceDialogView.mErrorText.getVisibility());
-        assertEquals(View.VISIBLE, mFaceDialogView.mPositiveButton.getVisibility());
-        assertEquals(View.VISIBLE, mFaceDialogView.mNegativeButton.getVisibility());
-        assertEquals(View.GONE, mFaceDialogView.mTryAgainButton.getVisibility());
-
-        // Contents are as expected
-        assertTrue(TITLE.contentEquals(mFaceDialogView.mTitleText.getText()));
-        assertTrue(SUBTITLE.contentEquals(mFaceDialogView.mSubtitleText.getText()));
-        assertTrue(DESCRIPTION.contentEquals(mFaceDialogView.mDescriptionText.getText()));
-        assertTrue(mFaceDialogView.mPositiveButton.getText().toString()
-                .contentEquals(mContext.getString(R.string.biometric_dialog_confirm)));
-        assertTrue(NEGATIVE_BUTTON.contentEquals(mFaceDialogView.mNegativeButton.getText()));
-        assertTrue(mFaceDialogView.mTryAgainButton.getText().toString()
-                .contentEquals(mContext.getString(R.string.biometric_dialog_try_again)));
-
-        // When help message is received
-        mFaceDialogView.onHelp(TEST_HELP);
-        assertEquals(mFaceDialogView.mErrorText.getVisibility(), View.VISIBLE);
-        assertTrue(TEST_HELP.contentEquals(mFaceDialogView.mErrorText.getText()));
-
-        // When authenticated, confirm button comes out
-        mFaceDialogView.onAuthenticationSucceeded();
-        assertEquals(View.VISIBLE, mFaceDialogView.mPositiveButton.getVisibility());
-        assertEquals(true, mFaceDialogView.mPositiveButton.isEnabled());
-    }
-
-    @Test
-    public void testContentStates_confirmationNotRequired_authenticated() {
-        mFaceDialogView = buildFaceDialogView(mTestableContext, mCallback,
-                false /* requireConfirmation */);
-        mFaceDialogView.onAttachedToWindow();
-        mFaceDialogView.updateSize(FaceDialogView.SIZE_SMALL);
-
-        assertEquals(View.INVISIBLE, mFaceDialogView.mTitleText.getVisibility());
-        assertNotSame(View.VISIBLE, mFaceDialogView.mSubtitleText.getVisibility());
-        assertNotSame(View.VISIBLE, mFaceDialogView.mDescriptionText.getVisibility());
-        assertEquals(View.INVISIBLE, mFaceDialogView.mErrorText.getVisibility());
-        assertEquals(View.GONE, mFaceDialogView.mPositiveButton.getVisibility());
-        assertEquals(View.GONE, mFaceDialogView.mTryAgainButton.getVisibility());
-        assertEquals(View.GONE, mFaceDialogView.mTryAgainButton.getVisibility());
-    }
-
-    @Test
-    public void testContentStates_confirmationNotRequired_help() {
-        mFaceDialogView = buildFaceDialogView(mTestableContext, mCallback,
-                false /* requireConfirmation */);
-        mFaceDialogView.onAttachedToWindow();
-
-        mFaceDialogView.onHelp(TEST_HELP);
-        assertEquals(mFaceDialogView.mErrorText.getVisibility(), View.VISIBLE);
-        assertTrue(TEST_HELP.contentEquals(mFaceDialogView.mErrorText.getText()));
-    }
-
-    @Test
-    public void testBack_sendsUserCanceled() {
-        // TODO: Need robolectric framework to wait for handler to complete
-    }
-
-    @Test
-    public void testScreenOff_sendsUserCanceled() {
-        // TODO: Need robolectric framework to wait for handler to complete
-    }
-
-    @Test
-    public void testRestoreState_contentStatesCorrect() {
-        mFaceDialogView = buildFaceDialogView(mTestableContext, mCallback,
-                false /* requireConfirmation */);
-        mFaceDialogView.onAttachedToWindow();
-        mFaceDialogView.onAuthenticationFailed(TEST_HELP);
-
-        final Bundle bundle = new Bundle();
-        mFaceDialogView.onSaveState(bundle);
-
-        mFaceDialogView = buildFaceDialogView(mTestableContext, mCallback,
-                false /* requireConfirmation */);
-        mFaceDialogView.restoreState(bundle);
-        mFaceDialogView.onAttachedToWindow();
-
-        assertEquals(View.VISIBLE, mFaceDialogView.mTryAgainButton.getVisibility());
-    }
-
-    private FaceDialogView buildFaceDialogView(Context context, AuthDialogCallback callback,
-            boolean requireConfirmation) {
-        return (FaceDialogView) new BiometricDialogView.Builder(context)
-                .setCallback(callback)
-                .setBiometricPromptBundle(createTestDialogBundle())
-                .setRequireConfirmation(requireConfirmation)
-                .setUserId(0)
-                .setOpPackageName("test_package")
-                .build(BiometricDialogView.Builder.TYPE_FACE, new Injector());
-    }
-
-    private Bundle createTestDialogBundle() {
-        Bundle bundle = new Bundle();
-
-        bundle.putCharSequence(BiometricPrompt.KEY_TITLE, TITLE);
-        bundle.putCharSequence(BiometricPrompt.KEY_SUBTITLE, SUBTITLE);
-        bundle.putCharSequence(BiometricPrompt.KEY_DESCRIPTION, DESCRIPTION);
-        bundle.putCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT, NEGATIVE_BUTTON);
-
-        // RequireConfirmation is a hint to BiometricService. This can be forced to be required
-        // by user settings, and should be tested in BiometricService.
-        bundle.putBoolean(BiometricPrompt.KEY_REQUIRE_CONFIRMATION, true);
-
-        return bundle;
-    }
-}
