/*
 * Copyright (C) 2020 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.hardware.fingerprint.IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD;

import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.RectF;
import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
import android.media.AudioAttributes;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;

import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.Execution;

import java.util.Optional;

import javax.inject.Inject;

import kotlin.Unit;

/**
 * Shows and hides the under-display fingerprint sensor (UDFPS) overlay, handles UDFPS touch events,
 * and coordinates triggering of the high-brightness mode (HBM).
 *
 * Note that the current architecture is designed so that a single {@link UdfpsController}
 * controls/manages all UDFPS sensors. In other words, a single controller is registered with
 * {@link com.android.server.biometrics.sensors.fingerprint.FingerprintService}, and interfaces such
 * as {@link FingerprintManager#onPointerDown(int, int, int, float, float)} or
 * {@link IUdfpsOverlayController#showUdfpsOverlay(int)}should all have
 * {@code sensorId} parameters.
 */
@SuppressWarnings("deprecation")
@SysUISingleton
public class UdfpsController implements DozeReceiver {
    private static final String TAG = "UdfpsController";
    private static final long AOD_INTERRUPT_TIMEOUT_MILLIS = 1000;

    // Minimum required delay between consecutive touch logs in milliseconds.
    private static final long MIN_TOUCH_LOG_INTERVAL = 50;

    private final Context mContext;
    private final Execution mExecution;
    private final FingerprintManager mFingerprintManager;
    @NonNull private final LayoutInflater mInflater;
    private final WindowManager mWindowManager;
    private final DelayableExecutor mFgExecutor;
    @NonNull private final StatusBar mStatusBar;
    @NonNull private final StatusBarStateController mStatusBarStateController;
    @NonNull private final KeyguardStateController mKeyguardStateController;
    @NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
    @NonNull private final DumpManager mDumpManager;
    @NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    @NonNull private final KeyguardViewMediator mKeyguardViewMediator;
    @Nullable private final Vibrator mVibrator;
    @NonNull private final Handler mMainHandler;
    @NonNull private final FalsingManager mFalsingManager;
    @NonNull private final PowerManager mPowerManager;
    @NonNull private final AccessibilityManager mAccessibilityManager;
    @NonNull private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
    @Nullable private final UdfpsHbmProvider mHbmProvider;
    @NonNull private final KeyguardBypassController mKeyguardBypassController;
    @NonNull private final ConfigurationController mConfigurationController;
    @VisibleForTesting @NonNull final BiometricOrientationEventListener mOrientationListener;
    // Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
    // sensors, this, in addition to a lot of the code here, will be updated.
    @VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
    private final WindowManager.LayoutParams mCoreLayoutParams;

    // Tracks the velocity of a touch to help filter out the touches that move too fast.
    @Nullable private VelocityTracker mVelocityTracker;
    // The ID of the pointer for which ACTION_DOWN has occurred. -1 means no pointer is active.
    private int mActivePointerId = -1;
    // The timestamp of the most recent touch log.
    private long mTouchLogTime;
    // Sensor has a good capture for this touch. Do not need to illuminate for this particular
    // touch event anymore. In other words, do not illuminate until user lifts and touches the
    // sensor area again.
    // TODO: We should probably try to make touch/illumination things more of a FSM
    private boolean mGoodCaptureReceived;

    @Nullable private UdfpsView mView;
    // The current request from FingerprintService. Null if no current request.
    @Nullable ServerRequest mServerRequest;

    // The fingerprint AOD trigger doesn't provide an ACTION_UP/ACTION_CANCEL event to tell us when
    // to turn off high brightness mode. To get around this limitation, the state of the AOD
    // interrupt is being tracked and a timeout is used as a last resort to turn off high brightness
    // mode.
    private boolean mIsAodInterruptActive;
    @Nullable private Runnable mCancelAodTimeoutAction;
    private boolean mScreenOn;
    private Runnable mAodInterruptRunnable;
    private boolean mOnFingerDown;
    private boolean mAttemptedToDismissKeyguard;

    @VisibleForTesting
    public static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
            new AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                    .build();

    public static final VibrationEffect EFFECT_CLICK =
            VibrationEffect.get(VibrationEffect.EFFECT_CLICK);

    private final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
        @Override
        public void onScreenTurnedOn() {
            mScreenOn = true;
            if (mAodInterruptRunnable != null) {
                mAodInterruptRunnable.run();
                mAodInterruptRunnable = null;
            }
        }

        @Override
        public void onScreenTurnedOff() {
            mScreenOn = false;
        }
    };

    /**
     * Keeps track of state within a single FingerprintService request. Note that this state
     * persists across configuration changes, etc, since it is considered a single request.
     *
     * TODO: Perhaps we can move more global variables into here
     */
    private static class ServerRequest {
        // Reason the overlay has been requested. See IUdfpsOverlayController for definitions.
        final int mRequestReason;
        @NonNull final IUdfpsOverlayControllerCallback mCallback;
        @Nullable final UdfpsEnrollHelper mEnrollHelper;

        ServerRequest(int requestReason, @NonNull IUdfpsOverlayControllerCallback callback,
                @Nullable UdfpsEnrollHelper enrollHelper) {
            mRequestReason = requestReason;
            mCallback = callback;
            mEnrollHelper = enrollHelper;
        }

        void onEnrollmentProgress(int remaining) {
            if (mEnrollHelper != null) {
                mEnrollHelper.onEnrollmentProgress(remaining);
            }
        }

        void onAcquiredGood() {
            Log.d(TAG, "onAcquiredGood");
            if (mEnrollHelper != null) {
                mEnrollHelper.animateIfLastStep();
            }
        }

        void onEnrollmentHelp() {
            Log.d(TAG, "onEnrollmentHelp");
            if (mEnrollHelper != null) {
                mEnrollHelper.onEnrollmentHelp();
            }
        }

        void onUserCanceled() {
            try {
                mCallback.onUserCanceled();
            } catch (RemoteException e) {
                Log.e(TAG, "Remote exception", e);
            }
        }
    }

    public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
        @Override
        public void showUdfpsOverlay(int sensorId, int reason,
                @NonNull IUdfpsOverlayControllerCallback callback) {
            mFgExecutor.execute(() -> {
                final UdfpsEnrollHelper enrollHelper;
                if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
                        || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING) {
                    enrollHelper = new UdfpsEnrollHelper(mContext, reason);
                } else {
                    enrollHelper = null;
                }
                mServerRequest = new ServerRequest(reason, callback, enrollHelper);
                updateOverlay();
            });
        }

        @Override
        public void hideUdfpsOverlay(int sensorId) {
            mFgExecutor.execute(() -> {
                mServerRequest = null;
                updateOverlay();
            });
        }

        @Override
        public void onAcquiredGood(int sensorId) {
            mFgExecutor.execute(() -> {
                if (mView == null) {
                    Log.e(TAG, "Null view when onAcquiredGood for sensorId: " + sensorId);
                    return;
                }
                mGoodCaptureReceived = true;
                mView.stopIllumination();
                if (mServerRequest != null) {
                    mServerRequest.onAcquiredGood();
                } else {
                    Log.e(TAG, "Null serverRequest when onAcquiredGood");
                }
            });
        }

        @Override
        public void onEnrollmentProgress(int sensorId, int remaining) {
            mFgExecutor.execute(() -> {
                if (mServerRequest == null) {
                    Log.e(TAG, "onEnrollProgress received but serverRequest is null");
                    return;
                }
                mServerRequest.onEnrollmentProgress(remaining);
            });
        }

        @Override
        public void onEnrollmentHelp(int sensorId) {
            mFgExecutor.execute(() -> {
                if (mServerRequest == null) {
                    Log.e(TAG, "onEnrollmentHelp received but serverRequest is null");
                    return;
                }
                mServerRequest.onEnrollmentHelp();
            });
        }

        @Override
        public void setDebugMessage(int sensorId, String message) {
            mFgExecutor.execute(() -> {
                if (mView == null) {
                    return;
                }
                mView.setDebugMessage(message);
            });
        }
    }

    private static float computePointerSpeed(@NonNull VelocityTracker tracker, int pointerId) {
        final float vx = tracker.getXVelocity(pointerId);
        final float vy = tracker.getYVelocity(pointerId);
        return (float) Math.sqrt(Math.pow(vx, 2.0) + Math.pow(vy, 2.0));
    }

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (mServerRequest != null
                    && mServerRequest.mRequestReason != REASON_AUTH_FPM_KEYGUARD
                    && Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
                Log.d(TAG, "ACTION_CLOSE_SYSTEM_DIALOGS received, mRequestReason: "
                        + mServerRequest.mRequestReason);
                mServerRequest.onUserCanceled();
                mServerRequest = null;
                updateOverlay();
            }
        }
    };

    /**
     * Forwards touches to the udfps controller / view
     */
    public boolean onTouch(MotionEvent event) {
        if (mView == null) {
            return false;
        }
        return onTouch(mView, event, false);
    }

    @SuppressLint("ClickableViewAccessibility")
    private final UdfpsView.OnTouchListener mOnTouchListener = (view, event) ->
            onTouch(view, event, true);

    @SuppressLint("ClickableViewAccessibility")
    private final UdfpsView.OnHoverListener mOnHoverListener = (view, event) ->
            onTouch(view, event, true);

    private final AccessibilityManager.TouchExplorationStateChangeListener
            mTouchExplorationStateChangeListener = enabled -> updateTouchListener();

    /**
     * @param x coordinate
     * @param y coordinate
     * @param relativeToUdfpsView true if the coordinates are relative to the udfps view; else,
     *                            calculate from the display dimensions in portrait orientation
     */
    private boolean isWithinSensorArea(UdfpsView udfpsView, float x, float y,
            boolean relativeToUdfpsView) {
        if (relativeToUdfpsView) {
            // TODO: move isWithinSensorArea to UdfpsController.
            return udfpsView.isWithinSensorArea(x, y);
        }

        if (mView == null || mView.getAnimationViewController() == null) {
            return false;
        }

        return !mView.getAnimationViewController().shouldPauseAuth()
                && getSensorLocation().contains(x, y);
    }

    private boolean onTouch(View view, MotionEvent event, boolean fromUdfpsView) {
        UdfpsView udfpsView = (UdfpsView) view;
        final boolean isIlluminationRequested = udfpsView.isIlluminationRequested();
        boolean handled = false;
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_OUTSIDE:
                udfpsView.onTouchOutsideView();
                return true;
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_HOVER_ENTER:
                Trace.beginSection("UdfpsController.onTouch.ACTION_DOWN");
                // To simplify the lifecycle of the velocity tracker, make sure it's never null
                // after ACTION_DOWN, and always null after ACTION_CANCEL or ACTION_UP.
                if (mVelocityTracker == null) {
                    mVelocityTracker = VelocityTracker.obtain();
                } else {
                    // ACTION_UP or ACTION_CANCEL is not guaranteed to be called before a new
                    // ACTION_DOWN, in that case we should just reuse the old instance.
                    mVelocityTracker.clear();
                }

                boolean withinSensorArea =
                        isWithinSensorArea(udfpsView, event.getX(), event.getY(), fromUdfpsView);
                if (withinSensorArea) {
                    Trace.beginAsyncSection("UdfpsController.e2e.onPointerDown", 0);
                    Log.v(TAG, "onTouch | action down");
                    // The pointer that causes ACTION_DOWN is always at index 0.
                    // We need to persist its ID to track it during ACTION_MOVE that could include
                    // data for many other pointers because of multi-touch support.
                    mActivePointerId = event.getPointerId(0);
                    mVelocityTracker.addMovement(event);
                    handled = true;
                }
                if ((withinSensorArea || fromUdfpsView) && shouldTryToDismissKeyguard()) {
                    Log.v(TAG, "onTouch | dismiss keyguard ACTION_DOWN");
                    if (!mOnFingerDown) {
                        playStartHaptic();
                    }
                    mKeyguardViewManager.notifyKeyguardAuthenticated(false /* strongAuth */);
                    mAttemptedToDismissKeyguard = true;
                }
                Trace.endSection();
                break;

            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_HOVER_MOVE:
                Trace.beginSection("UdfpsController.onTouch.ACTION_MOVE");
                final int idx = mActivePointerId == -1
                        ? event.getPointerId(0)
                        : event.findPointerIndex(mActivePointerId);
                if (idx == event.getActionIndex()) {
                    boolean actionMoveWithinSensorArea =
                            isWithinSensorArea(udfpsView, event.getX(idx), event.getY(idx),
                                fromUdfpsView);
                    if ((fromUdfpsView || actionMoveWithinSensorArea)
                            && shouldTryToDismissKeyguard()) {
                        Log.v(TAG, "onTouch | dismiss keyguard ACTION_MOVE");
                        if (!mOnFingerDown) {
                            playStartHaptic();
                        }
                        mKeyguardViewManager.notifyKeyguardAuthenticated(false /* strongAuth */);
                        mAttemptedToDismissKeyguard = true;
                        break;
                    }
                    if (actionMoveWithinSensorArea) {
                        if (mVelocityTracker == null) {
                            // touches could be injected, so the velocity tracker may not have
                            // been initialized (via ACTION_DOWN).
                            mVelocityTracker = VelocityTracker.obtain();
                        }
                        mVelocityTracker.addMovement(event);
                        // Compute pointer velocity in pixels per second.
                        mVelocityTracker.computeCurrentVelocity(1000);
                        // Compute pointer speed from X and Y velocities.
                        final float v = computePointerSpeed(mVelocityTracker, mActivePointerId);
                        final float minor = event.getTouchMinor(idx);
                        final float major = event.getTouchMajor(idx);
                        final boolean exceedsVelocityThreshold = v > 750f;
                        final String touchInfo = String.format(
                                "minor: %.1f, major: %.1f, v: %.1f, exceedsVelocityThreshold: %b",
                                minor, major, v, exceedsVelocityThreshold);
                        final long sinceLastLog = SystemClock.elapsedRealtime() - mTouchLogTime;
                        if (!isIlluminationRequested && !mGoodCaptureReceived &&
                                !exceedsVelocityThreshold) {
                            onFingerDown((int) event.getRawX(), (int) event.getRawY(), minor,
                                    major);
                            Log.v(TAG, "onTouch | finger down: " + touchInfo);
                            mTouchLogTime = SystemClock.elapsedRealtime();
                            mPowerManager.userActivity(SystemClock.uptimeMillis(),
                                    PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
                            handled = true;
                        } else if (sinceLastLog >= MIN_TOUCH_LOG_INTERVAL) {
                            Log.v(TAG, "onTouch | finger move: " + touchInfo);
                            mTouchLogTime = SystemClock.elapsedRealtime();
                        }
                    } else {
                        Log.v(TAG, "onTouch | finger outside");
                        onFingerUp();
                    }
                }
                Trace.endSection();
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_HOVER_EXIT:
                Trace.beginSection("UdfpsController.onTouch.ACTION_UP");
                mActivePointerId = -1;
                if (mVelocityTracker != null) {
                    mVelocityTracker.recycle();
                    mVelocityTracker = null;
                }
                Log.v(TAG, "onTouch | finger up");
                mAttemptedToDismissKeyguard = false;
                onFingerUp();
                mFalsingManager.isFalseTouch(UDFPS_AUTHENTICATION);
                Trace.endSection();
                break;

            default:
                // Do nothing.
        }
        return handled;
    }

    private boolean shouldTryToDismissKeyguard() {
        return mView.getAnimationViewController() != null
            && mView.getAnimationViewController() instanceof UdfpsKeyguardViewController
            && mKeyguardStateController.canDismissLockScreen()
            && !mAttemptedToDismissKeyguard;
    }

    @Inject
    public UdfpsController(@NonNull Context context,
            @NonNull Execution execution,
            @NonNull LayoutInflater inflater,
            @Nullable FingerprintManager fingerprintManager,
            @NonNull WindowManager windowManager,
            @NonNull StatusBarStateController statusBarStateController,
            @Main DelayableExecutor fgExecutor,
            @NonNull StatusBar statusBar,
            @NonNull StatusBarKeyguardViewManager statusBarKeyguardViewManager,
            @NonNull DumpManager dumpManager,
            @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
            @NonNull KeyguardViewMediator keyguardViewMediator,
            @NonNull FalsingManager falsingManager,
            @NonNull PowerManager powerManager,
            @NonNull AccessibilityManager accessibilityManager,
            @NonNull LockscreenShadeTransitionController lockscreenShadeTransitionController,
            @NonNull ScreenLifecycle screenLifecycle,
            @Nullable Vibrator vibrator,
            @NonNull UdfpsHapticsSimulator udfpsHapticsSimulator,
            @NonNull Optional<UdfpsHbmProvider> hbmProvider,
            @NonNull KeyguardStateController keyguardStateController,
            @NonNull KeyguardBypassController keyguardBypassController,
            @NonNull DisplayManager displayManager,
            @Main Handler mainHandler,
            @NonNull ConfigurationController configurationController) {
        mContext = context;
        mExecution = execution;
        // TODO (b/185124905): inject main handler and vibrator once done prototyping
        mMainHandler = new Handler(Looper.getMainLooper());
        mVibrator = vibrator;
        mInflater = inflater;
        // The fingerprint manager is queried for UDFPS before this class is constructed, so the
        // fingerprint manager should never be null.
        mFingerprintManager = checkNotNull(fingerprintManager);
        mWindowManager = windowManager;
        mFgExecutor = fgExecutor;
        mStatusBar = statusBar;
        mStatusBarStateController = statusBarStateController;
        mKeyguardStateController = keyguardStateController;
        mKeyguardViewManager = statusBarKeyguardViewManager;
        mDumpManager = dumpManager;
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mKeyguardViewMediator = keyguardViewMediator;
        mFalsingManager = falsingManager;
        mPowerManager = powerManager;
        mAccessibilityManager = accessibilityManager;
        mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
        mHbmProvider = hbmProvider.orElse(null);
        screenLifecycle.addObserver(mScreenObserver);
        mScreenOn = screenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_ON;
        mOrientationListener = new BiometricOrientationEventListener(
                context,
                () -> {
                    onOrientationChanged();
                    return Unit.INSTANCE;
                },
                displayManager,
                mainHandler);
        mKeyguardBypassController = keyguardBypassController;
        mConfigurationController = configurationController;

        mSensorProps = findFirstUdfps();
        // At least one UDFPS sensor exists
        checkArgument(mSensorProps != null);

        mCoreLayoutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
                getCoreLayoutParamFlags(),
                PixelFormat.TRANSLUCENT);
        mCoreLayoutParams.setTitle(TAG);
        mCoreLayoutParams.setFitInsetsTypes(0);
        mCoreLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
        mCoreLayoutParams.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
        mCoreLayoutParams.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;

        mFingerprintManager.setUdfpsOverlayController(new UdfpsOverlayController());

        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        context.registerReceiver(mBroadcastReceiver, filter);

        udfpsHapticsSimulator.setUdfpsController(this);
    }

    /**
     * Play haptic to signal udfps scanning started.
     */
    @VisibleForTesting
    public void playStartHaptic() {
        if (mVibrator != null) {
            mVibrator.vibrate(
                    Process.myUid(),
                    mContext.getOpPackageName(),
                    EFFECT_CLICK,
                    "udfps-onStart",
                    VIBRATION_SONIFICATION_ATTRIBUTES);
        }
    }

    private int getCoreLayoutParamFlags() {
        return WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
    }

    @Nullable
    private FingerprintSensorPropertiesInternal findFirstUdfps() {
        for (FingerprintSensorPropertiesInternal props :
                mFingerprintManager.getSensorPropertiesInternal()) {
            if (props.isAnyUdfpsType()) {
                return props;
            }
        }
        return null;
    }

    @Override
    public void dozeTimeTick() {
        if (mView != null) {
            mView.dozeTimeTick();
        }
    }

    /**
     * @return where the UDFPS exists on the screen in pixels.
     */
    public RectF getSensorLocation() {
        // This is currently used to calculate the amount of space available for notifications
        // on lockscreen and for the udfps light reveal animation on keyguard.
        // Keyguard is only shown in portrait mode for now, so this will need to
        // be updated if that ever changes.
        return new RectF(mSensorProps.sensorLocationX - mSensorProps.sensorRadius,
                mSensorProps.sensorLocationY - mSensorProps.sensorRadius,
                mSensorProps.sensorLocationX + mSensorProps.sensorRadius,
                mSensorProps.sensorLocationY + mSensorProps.sensorRadius);
    }

    private void updateOverlay() {
        mExecution.assertIsMainThread();

        if (mServerRequest != null) {
            showUdfpsOverlay(mServerRequest);
        } else {
            hideUdfpsOverlay();
        }
    }

    private WindowManager.LayoutParams computeLayoutParams(
            @Nullable UdfpsAnimationViewController animation) {
        final int paddingX = animation != null ? animation.getPaddingX() : 0;
        final int paddingY = animation != null ? animation.getPaddingY() : 0;

        mCoreLayoutParams.flags = getCoreLayoutParamFlags();
        if (animation != null && animation.listenForTouchesOutsideView()) {
            mCoreLayoutParams.flags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
        }

        // Default dimensions assume portrait mode.
        mCoreLayoutParams.x = mSensorProps.sensorLocationX - mSensorProps.sensorRadius - paddingX;
        mCoreLayoutParams.y = mSensorProps.sensorLocationY - mSensorProps.sensorRadius - paddingY;
        mCoreLayoutParams.height = 2 * mSensorProps.sensorRadius + 2 * paddingX;
        mCoreLayoutParams.width = 2 * mSensorProps.sensorRadius + 2 * paddingY;

        Point p = new Point();
        // Gets the size based on the current rotation of the display.
        mContext.getDisplay().getRealSize(p);

        // Transform dimensions if the device is in landscape mode
        switch (mContext.getDisplay().getRotation()) {
            case Surface.ROTATION_90:
                if (animation instanceof UdfpsKeyguardViewController
                        && mKeyguardUpdateMonitor.isGoingToSleep()) {
                    break;
                }
                mCoreLayoutParams.x = mSensorProps.sensorLocationY - mSensorProps.sensorRadius
                        - paddingX;
                mCoreLayoutParams.y = p.y - mSensorProps.sensorLocationX - mSensorProps.sensorRadius
                        - paddingY;
                break;

            case Surface.ROTATION_270:
                if (animation instanceof UdfpsKeyguardViewController
                        && mKeyguardUpdateMonitor.isGoingToSleep()) {
                    break;
                }
                mCoreLayoutParams.x = p.x - mSensorProps.sensorLocationY - mSensorProps.sensorRadius
                        - paddingX;
                mCoreLayoutParams.y = mSensorProps.sensorLocationX - mSensorProps.sensorRadius
                        - paddingY;
                break;

            default:
                // Do nothing to stay in portrait mode.
                // Keyguard is always in portrait mode.
        }
        // avoid announcing window title
        mCoreLayoutParams.accessibilityTitle = " ";
        return mCoreLayoutParams;
    }

    private void onOrientationChanged() {
        // When the configuration changes it's almost always necessary to destroy and re-create
        // the overlay's window to pass it the new LayoutParams.
        // Hiding the overlay will destroy its window. It's safe to hide the overlay regardless
        // of whether it is already hidden.
        hideUdfpsOverlay();
        // If the overlay needs to be shown, this will re-create and show the overlay with the
        // updated LayoutParams. Otherwise, the overlay will remain hidden.
        updateOverlay();
    }

    private void showUdfpsOverlay(@NonNull ServerRequest request) {
        mExecution.assertIsMainThread();

        final int reason = request.mRequestReason;
        if (mView == null) {
            try {
                Log.v(TAG, "showUdfpsOverlay | adding window reason=" + reason);

                mView = (UdfpsView) mInflater.inflate(R.layout.udfps_view, null, false);
                mOnFingerDown = false;
                mView.setSensorProperties(mSensorProps);
                mView.setHbmProvider(mHbmProvider);
                UdfpsAnimationViewController animation = inflateUdfpsAnimation(reason);
                mAttemptedToDismissKeyguard = false;
                animation.init();
                mView.setAnimationViewController(animation);
                mOrientationListener.enable();

                // This view overlaps the sensor area, so prevent it from being selectable
                // during a11y.
                if (reason == IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR
                        || reason == IUdfpsOverlayController.REASON_ENROLL_ENROLLING
                        || reason == IUdfpsOverlayController.REASON_AUTH_BP) {
                    mView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
                }

                mWindowManager.addView(mView, computeLayoutParams(animation));
                mAccessibilityManager.addTouchExplorationStateChangeListener(
                        mTouchExplorationStateChangeListener);
                updateTouchListener();
            } catch (RuntimeException e) {
                Log.e(TAG, "showUdfpsOverlay | failed to add window", e);
            }
        } else {
            Log.v(TAG, "showUdfpsOverlay | the overlay is already showing");
        }
    }

    private UdfpsAnimationViewController inflateUdfpsAnimation(int reason) {
        switch (reason) {
            case IUdfpsOverlayController.REASON_ENROLL_FIND_SENSOR:
            case IUdfpsOverlayController.REASON_ENROLL_ENROLLING:
                UdfpsEnrollView enrollView = (UdfpsEnrollView) mInflater.inflate(
                        R.layout.udfps_enroll_view, null);
                mView.addView(enrollView);
                enrollView.updateSensorLocation(mSensorProps);
                return new UdfpsEnrollViewController(
                        enrollView,
                        mServerRequest.mEnrollHelper,
                        mStatusBarStateController,
                        mStatusBar,
                        mDumpManager
                );
            case IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD:
                UdfpsKeyguardView keyguardView = (UdfpsKeyguardView)
                        mInflater.inflate(R.layout.udfps_keyguard_view, null);
                mView.addView(keyguardView);
                return new UdfpsKeyguardViewController(
                        keyguardView,
                        mStatusBarStateController,
                        mStatusBar,
                        mKeyguardViewManager,
                        mKeyguardUpdateMonitor,
                        mFgExecutor,
                        mDumpManager,
                        mKeyguardViewMediator,
                        mLockscreenShadeTransitionController,
                        mConfigurationController,
                        mKeyguardStateController,
                        this
                );
            case IUdfpsOverlayController.REASON_AUTH_BP:
                // note: empty controller, currently shows no visual affordance
                UdfpsBpView bpView = (UdfpsBpView) mInflater.inflate(R.layout.udfps_bp_view, null);
                mView.addView(bpView);
                return new UdfpsBpViewController(
                        bpView,
                        mStatusBarStateController,
                        mStatusBar,
                        mDumpManager
                );
            case IUdfpsOverlayController.REASON_AUTH_FPM_OTHER:
                UdfpsFpmOtherView authOtherView = (UdfpsFpmOtherView)
                        mInflater.inflate(R.layout.udfps_fpm_other_view, null);
                mView.addView(authOtherView);
                return new UdfpsFpmOtherViewController(
                        authOtherView,
                        mStatusBarStateController,
                        mStatusBar,
                        mDumpManager
                );
            default:
                Log.d(TAG, "Animation for reason " + reason + " not supported yet");
                return null;
        }
    }

    private void hideUdfpsOverlay() {
        mExecution.assertIsMainThread();

        if (mView != null) {
            Log.v(TAG, "hideUdfpsOverlay | removing window");
            // Reset the controller back to its starting state.
            onFingerUp();
            mWindowManager.removeView(mView);
            mView.setOnTouchListener(null);
            mView.setOnHoverListener(null);
            mView.setAnimationViewController(null);
            mAccessibilityManager.removeTouchExplorationStateChangeListener(
                    mTouchExplorationStateChangeListener);
            mView = null;
        } else {
            Log.v(TAG, "hideUdfpsOverlay | the overlay is already hidden");
        }

        mOrientationListener.disable();
    }

    /**
     * Request fingerprint scan.
     *
     * This is intended to be called in response to a sensor that triggers an AOD interrupt for the
     * fingerprint sensor.
     */
    void onAodInterrupt(int screenX, int screenY, float major, float minor) {
        if (mIsAodInterruptActive) {
            return;
        }

        mAodInterruptRunnable = () -> {
            mIsAodInterruptActive = true;
            // Since the sensor that triggers the AOD interrupt doesn't provide
            // ACTION_UP/ACTION_CANCEL,  we need to be careful about not letting the screen
            // accidentally remain in high brightness mode. As a mitigation, queue a call to
            // cancel the fingerprint scan.
            mCancelAodTimeoutAction = mFgExecutor.executeDelayed(this::onCancelUdfps,
                    AOD_INTERRUPT_TIMEOUT_MILLIS);
            // using a hard-coded value for major and minor until it is available from the sensor
            onFingerDown(screenX, screenY, minor, major);
        };

        if (mScreenOn && mAodInterruptRunnable != null) {
            mAodInterruptRunnable.run();
            mAodInterruptRunnable = null;
        }
    }

    /**
     * Cancel updfs scan affordances - ability to hide the HbmSurfaceView (white circle) before
     * user explicitly lifts their finger. Generally, this should be called whenever udfps fails
     * or errors.
     *
     * The sensor that triggers an AOD fingerprint interrupt (see onAodInterrupt) doesn't give
     * ACTION_UP/ACTION_CANCEL events, so and AOD interrupt scan needs to be cancelled manually.
     * This should be called when authentication either succeeds or fails. Failing to cancel the
     * scan will leave the screen in high brightness mode and will show the HbmSurfaceView until
     * the user lifts their finger.
     */
    void onCancelUdfps() {
        onFingerUp();
        if (!mIsAodInterruptActive) {
            return;
        }
        if (mCancelAodTimeoutAction != null) {
            mCancelAodTimeoutAction.run();
            mCancelAodTimeoutAction = null;
        }
        mIsAodInterruptActive = false;
    }

    public boolean isFingerDown() {
        return mOnFingerDown;
    }

    private void onFingerDown(int x, int y, float minor, float major) {
        mExecution.assertIsMainThread();
        if (mView == null) {
            Log.w(TAG, "Null view in onFingerDown");
            return;
        }

        if (mView.getAnimationViewController() instanceof UdfpsKeyguardViewController
                && !mStatusBarStateController.isDozing()) {
            mKeyguardBypassController.setUserHasDeviceEntryIntent(true);
        }

        if (!mOnFingerDown) {
            playStartHaptic();

            if (!mKeyguardUpdateMonitor.isFaceDetectionRunning()) {
                mKeyguardUpdateMonitor.requestFaceAuth(/* userInitiatedRequest */ false);
            }
        }
        mOnFingerDown = true;
        mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
        Trace.endAsyncSection("UdfpsController.e2e.onPointerDown", 0);
        Trace.beginAsyncSection("UdfpsController.e2e.startIllumination", 0);
        mView.startIllumination(() -> {
            mFingerprintManager.onUiReady(mSensorProps.sensorId);
            Trace.endAsyncSection("UdfpsController.e2e.startIllumination", 0);
        });
    }

    private void onFingerUp() {
        mExecution.assertIsMainThread();
        mActivePointerId = -1;
        mGoodCaptureReceived = false;
        if (mView == null) {
            Log.w(TAG, "Null view in onFingerUp");
            return;
        }
        if (mOnFingerDown) {
            mFingerprintManager.onPointerUp(mSensorProps.sensorId);
        }
        mOnFingerDown = false;
        if (mView.isIlluminationRequested()) {
            mView.stopIllumination();
        }
    }

    private void updateTouchListener() {
        if (mView == null) {
            return;
        }

        if (mAccessibilityManager.isTouchExplorationEnabled()) {
            mView.setOnHoverListener(mOnHoverListener);
            mView.setOnTouchListener(null);
        } else {
            mView.setOnHoverListener(null);
            mView.setOnTouchListener(mOnTouchListener);
        }
    }
}
