/*
 * 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() {
            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);
        }
    }
}
