/*
 * Copyright (C) 2017 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;

import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;

import static com.android.systemui.tuner.TunablePadding.FLAG_END;
import static com.android.systemui.tuner.TunablePadding.FLAG_START;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.Dimension;
import android.app.ActivityManager;
import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemProperties;
import android.provider.Settings.Secure;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;

import androidx.annotation.VisibleForTesting;

import com.android.internal.util.Preconditions;
import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.SecureSetting;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.NavigationBarTransitions;
import com.android.systemui.statusbar.phone.NavigationModeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.tuner.TunablePadding;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.leak.RotationUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * An overlay that draws screen decorations in software (e.g for rounded corners or display cutout)
 * for antialiasing and emulation purposes.
 */
public class ScreenDecorations extends SystemUI implements Tunable,
        NavigationBarTransitions.DarkIntensityListener {
    private static final boolean DEBUG = false;
    private static final String TAG = "ScreenDecorations";

    public static final String SIZE = "sysui_rounded_size";
    public static final String PADDING = "sysui_rounded_content_padding";
    private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS =
            SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
    private static final boolean VERBOSE = false;

    private DisplayManager mDisplayManager;
    private DisplayManager.DisplayListener mDisplayListener;

    @VisibleForTesting
    protected int mRoundedDefault;
    @VisibleForTesting
    protected int mRoundedDefaultTop;
    @VisibleForTesting
    protected int mRoundedDefaultBottom;
    private View mOverlay;
    private View mBottomOverlay;
    private float mDensity;
    private WindowManager mWindowManager;
    private int mRotation;
    private boolean mAssistHintVisible;
    private DisplayCutoutView mCutoutTop;
    private DisplayCutoutView mCutoutBottom;
    private SecureSetting mColorInversionSetting;
    private boolean mPendingRotationChange;
    private Handler mHandler;
    private boolean mAssistHintBlocked = false;
    private boolean mIsReceivingNavBarColor = false;
    private boolean mInGesturalMode;

    /**
     * Converts a set of {@link Rect}s into a {@link Region}
     *
     * @hide
     */
    public static Region rectsToRegion(List<Rect> rects) {
        Region result = Region.obtain();
        if (rects != null) {
            for (Rect r : rects) {
                if (r != null && !r.isEmpty()) {
                    result.op(r, Region.Op.UNION);
                }
            }
        }
        return result;
    }

    @Override
    public void start() {
        mHandler = startHandlerThread();
        mHandler.post(this::startOnScreenDecorationsThread);
        setupStatusBarPaddingIfNeeded();
        putComponent(ScreenDecorations.class, this);
        mInGesturalMode = QuickStepContract.isGesturalMode(
                Dependency.get(NavigationModeController.class)
                        .addListener(this::handleNavigationModeChange));
    }

    @VisibleForTesting
    void handleNavigationModeChange(int navigationMode) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> handleNavigationModeChange(navigationMode));
            return;
        }
        boolean inGesturalMode = QuickStepContract.isGesturalMode(navigationMode);
        if (mInGesturalMode != inGesturalMode) {
            mInGesturalMode = inGesturalMode;

            if (mInGesturalMode && mOverlay == null) {
                setupDecorations();
                if (mOverlay != null) {
                    updateLayoutParams();
                }
            }
        }
    }

    /**
     * Returns an animator that animates the given view from start to end over durationMs. Start and
     * end represent total animation progress: 0 is the start, 1 is the end, 1.1 would be an
     * overshoot.
     */
    Animator getHandleAnimator(View view, float start, float end, boolean isLeft, long durationMs,
            Interpolator interpolator) {
        // Note that lerp does allow overshoot, in cases where start and end are outside of [0,1].
        float scaleStart = MathUtils.lerp(2f, 1f, start);
        float scaleEnd = MathUtils.lerp(2f, 1f, end);
        Animator scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, scaleStart, scaleEnd);
        Animator scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, scaleStart, scaleEnd);
        float translationStart = MathUtils.lerp(0.2f, 0f, start);
        float translationEnd = MathUtils.lerp(0.2f, 0f, end);
        int xDirection = isLeft ? -1 : 1;
        Animator translateX = ObjectAnimator.ofFloat(view, View.TRANSLATION_X,
                xDirection * translationStart * view.getWidth(),
                xDirection * translationEnd * view.getWidth());
        Animator translateY = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y,
                translationStart * view.getHeight(), translationEnd * view.getHeight());

        AnimatorSet set = new AnimatorSet();
        set.play(scaleX).with(scaleY);
        set.play(scaleX).with(translateX);
        set.play(scaleX).with(translateY);
        set.setDuration(durationMs);
        set.setInterpolator(interpolator);
        return set;
    }

    private void fade(View view, boolean fadeIn, boolean isLeft) {
        if (fadeIn) {
            view.animate().cancel();
            view.setAlpha(1f);
            view.setVisibility(View.VISIBLE);

            // A piecewise spring-like interpolation.
            // End value in one animator call must match the start value in the next, otherwise
            // there will be a discontinuity.
            AnimatorSet anim = new AnimatorSet();
            Animator first = getHandleAnimator(view, 0, 1.1f, isLeft, 750,
                    new PathInterpolator(0, 0.45f, .67f, 1f));
            Interpolator secondInterpolator = new PathInterpolator(0.33f, 0, 0.67f, 1f);
            Animator second = getHandleAnimator(view, 1.1f, 0.97f, isLeft, 400,
                    secondInterpolator);
            Animator third = getHandleAnimator(view, 0.97f, 1.02f, isLeft, 400,
                    secondInterpolator);
            Animator fourth = getHandleAnimator(view, 1.02f, 1f, isLeft, 400,
                    secondInterpolator);
            anim.play(first).before(second);
            anim.play(second).before(third);
            anim.play(third).before(fourth);
            anim.start();
        } else {
            view.animate().cancel();
            view.animate()
                    .setInterpolator(new AccelerateInterpolator(1.5f))
                    .setDuration(250)
                    .alpha(0f);
        }

    }

    /**
     * Controls the visibility of the assist gesture handles.
     *
     * @param visible whether the handles should be shown
     */
    public void setAssistHintVisible(boolean visible) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> setAssistHintVisible(visible));
            return;
        }

        if (mAssistHintBlocked && visible) {
            if (VERBOSE) {
                Log.v(TAG, "Assist hint blocked, cannot make it visible");
            }
            return;
        }

        if (mOverlay == null || mBottomOverlay == null) {
            return;
        }

        if (mAssistHintVisible != visible) {
            mAssistHintVisible = visible;

            CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
            CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
            CornerHandleView assistHintBottomLeft = mBottomOverlay.findViewById(
                    R.id.assist_hint_left);
            CornerHandleView assistHintBottomRight = mBottomOverlay.findViewById(
                    R.id.assist_hint_right);

            switch (mRotation) {
                case RotationUtils.ROTATION_NONE:
                    fade(assistHintBottomLeft, mAssistHintVisible, /* isLeft = */ true);
                    fade(assistHintBottomRight, mAssistHintVisible, /* isLeft = */ false);
                    break;
                case RotationUtils.ROTATION_LANDSCAPE:
                    fade(assistHintTopRight, mAssistHintVisible, /* isLeft = */ true);
                    fade(assistHintBottomRight, mAssistHintVisible, /* isLeft = */ false);
                    break;
                case RotationUtils.ROTATION_SEASCAPE:
                    fade(assistHintTopLeft, mAssistHintVisible, /* isLeft = */ false);
                    fade(assistHintBottomLeft, mAssistHintVisible,  /* isLeft = */ true);
                    break;
                case RotationUtils.ROTATION_UPSIDE_DOWN:
                    fade(assistHintTopLeft, mAssistHintVisible, /* isLeft = */ false);
                    fade(assistHintTopRight, mAssistHintVisible, /* isLeft = */ true);
                    break;
            }
        }
        updateWindowVisibilities();
    }

    /**
     * Prevents the assist hint from becoming visible even if `mAssistHintVisible` is true.
     */
    public void setAssistHintBlocked(boolean blocked) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> setAssistHintBlocked(blocked));
            return;
        }

        mAssistHintBlocked = blocked;
        if (mAssistHintVisible && mAssistHintBlocked) {
            hideAssistHandles();
        }
    }

    @VisibleForTesting
    Handler startHandlerThread() {
        HandlerThread thread = new HandlerThread("ScreenDecorations");
        thread.start();
        return thread.getThreadHandler();
    }

    private boolean shouldHostHandles() {
        return mInGesturalMode;
    }

    private void startOnScreenDecorationsThread() {
        mRotation = RotationUtils.getExactRotation(mContext);
        mWindowManager = mContext.getSystemService(WindowManager.class);
        updateRoundedCornerRadii();
        if (hasRoundedCorners() || shouldDrawCutout() || shouldHostHandles()) {
            setupDecorations();
        }

        mDisplayListener = new DisplayManager.DisplayListener() {
            @Override
            public void onDisplayAdded(int displayId) {
                // do nothing
            }

            @Override
            public void onDisplayRemoved(int displayId) {
                // do nothing
            }

            @Override
            public void onDisplayChanged(int displayId) {
                final int newRotation = RotationUtils.getExactRotation(mContext);
                if (mOverlay != null && mBottomOverlay != null && mRotation != newRotation) {
                    // We cannot immediately update the orientation. Otherwise
                    // WindowManager is still deferring layout until it has finished dispatching
                    // the config changes, which may cause divergence between what we draw
                    // (new orientation), and where we are placed on the screen (old orientation).
                    // Instead we wait until either:
                    // - we are trying to redraw. This because WM resized our window and told us to.
                    // - the config change has been dispatched, so WM is no longer deferring layout.
                    mPendingRotationChange = true;
                    if (DEBUG) {
                        Log.i(TAG, "Rotation changed, deferring " + newRotation + ", staying at "
                                + mRotation);
                    }

                    mOverlay.getViewTreeObserver().addOnPreDrawListener(
                            new RestartingPreDrawListener(mOverlay, newRotation));
                    mBottomOverlay.getViewTreeObserver().addOnPreDrawListener(
                            new RestartingPreDrawListener(mBottomOverlay, newRotation));
                }
                updateOrientation();
            }
        };

        mDisplayManager = (DisplayManager) mContext.getSystemService(
                Context.DISPLAY_SERVICE);
        mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
        updateOrientation();
    }

    private void setupDecorations() {
        mOverlay = LayoutInflater.from(mContext)
                .inflate(R.layout.rounded_corners, null);
        mCutoutTop = new DisplayCutoutView(mContext, true,
                this::updateWindowVisibilities, this);
        ((ViewGroup) mOverlay).addView(mCutoutTop);
        mBottomOverlay = LayoutInflater.from(mContext)
                .inflate(R.layout.rounded_corners, null);
        mCutoutBottom = new DisplayCutoutView(mContext, false,
                this::updateWindowVisibilities, this);
        ((ViewGroup) mBottomOverlay).addView(mCutoutBottom);

        mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        mOverlay.setAlpha(0);
        mOverlay.setForceDarkAllowed(false);

        mBottomOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        mBottomOverlay.setAlpha(0);
        mBottomOverlay.setForceDarkAllowed(false);

        updateViews();

        mWindowManager.addView(mOverlay, getWindowLayoutParams());
        mWindowManager.addView(mBottomOverlay, getBottomLayoutParams());

        DisplayMetrics metrics = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(metrics);
        mDensity = metrics.density;

        Dependency.get(Dependency.MAIN_HANDLER).post(
                () -> Dependency.get(TunerService.class).addTunable(this, SIZE));

        // Watch color inversion and invert the overlay as needed.
        mColorInversionSetting = new SecureSetting(mContext, mHandler,
                Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
            @Override
            protected void handleValueChanged(int value, boolean observedChange) {
                updateColorInversion(value);
            }
        };
        mColorInversionSetting.setListening(true);
        mColorInversionSetting.onChange(false);

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        mContext.registerReceiver(mIntentReceiver, filter, null /* permission */, mHandler);

        mOverlay.addOnLayoutChangeListener(new OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom,
                    int oldLeft,
                    int oldTop, int oldRight, int oldBottom) {
                mOverlay.removeOnLayoutChangeListener(this);
                mOverlay.animate()
                        .alpha(1)
                        .setDuration(1000)
                        .start();
                mBottomOverlay.animate()
                        .alpha(1)
                        .setDuration(1000)
                        .start();
            }
        });

        mOverlay.getViewTreeObserver().addOnPreDrawListener(
                new ValidatingPreDrawListener(mOverlay));
        mBottomOverlay.getViewTreeObserver().addOnPreDrawListener(
                new ValidatingPreDrawListener(mBottomOverlay));
    }

    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                int newUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                        ActivityManager.getCurrentUser());
                // update color inversion setting to the new user
                mColorInversionSetting.setUserId(newUserId);
                updateColorInversion(mColorInversionSetting.getValue());
            }
        }
    };

    private void updateColorInversion(int colorsInvertedValue) {
        int tint = colorsInvertedValue != 0 ? Color.WHITE : Color.BLACK;
        ColorStateList tintList = ColorStateList.valueOf(tint);
        ((ImageView) mOverlay.findViewById(R.id.left)).setImageTintList(tintList);
        ((ImageView) mOverlay.findViewById(R.id.right)).setImageTintList(tintList);
        ((ImageView) mBottomOverlay.findViewById(R.id.left)).setImageTintList(tintList);
        ((ImageView) mBottomOverlay.findViewById(R.id.right)).setImageTintList(tintList);
        mCutoutTop.setColor(tint);
        mCutoutBottom.setColor(tint);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        mHandler.post(() -> {
            int oldRotation = mRotation;
            mPendingRotationChange = false;
            updateOrientation();
            updateRoundedCornerRadii();
            if (DEBUG) Log.i(TAG, "onConfigChanged from rot " + oldRotation + " to " + mRotation);
            if (shouldDrawCutout() && mOverlay == null) {
                setupDecorations();
            }
            if (mOverlay != null) {
                // Updating the layout params ensures that ViewRootImpl will call relayoutWindow(),
                // which ensures that the forced seamless rotation will end, even if we updated
                // the rotation before window manager was ready (and was still waiting for sending
                // the updated rotation).
                updateLayoutParams();
            }
        });
    }

    private void updateOrientation() {
        Preconditions.checkState(mHandler.getLooper().getThread() == Thread.currentThread(),
                "must call on " + mHandler.getLooper().getThread()
                        + ", but was " + Thread.currentThread());
        if (mPendingRotationChange) {
            return;
        }
        int newRotation = RotationUtils.getExactRotation(mContext);
        if (newRotation != mRotation) {
            mRotation = newRotation;

            if (mOverlay != null) {
                updateLayoutParams();
                updateViews();
                if (mAssistHintVisible) {
                    // If assist handles are visible, hide them without animation and then make them
                    // show once again (with corrected rotation).
                    hideAssistHandles();
                    setAssistHintVisible(true);
                }
            }
        }
    }

    private void hideAssistHandles() {
        if (mOverlay != null && mBottomOverlay != null) {
            mOverlay.findViewById(R.id.assist_hint_left).setVisibility(View.GONE);
            mOverlay.findViewById(R.id.assist_hint_right).setVisibility(View.GONE);
            mBottomOverlay.findViewById(R.id.assist_hint_left).setVisibility(View.GONE);
            mBottomOverlay.findViewById(R.id.assist_hint_right).setVisibility(View.GONE);
            mAssistHintVisible = false;
        }
    }

    private void updateRoundedCornerRadii() {
        final int newRoundedDefault = mContext.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.rounded_corner_radius);
        final int newRoundedDefaultTop = mContext.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.rounded_corner_radius_top);
        final int newRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.rounded_corner_radius_bottom);

        final boolean roundedCornersChanged = mRoundedDefault != newRoundedDefault
                || mRoundedDefaultBottom != newRoundedDefaultBottom
                || mRoundedDefaultTop != newRoundedDefaultTop;

        if (roundedCornersChanged) {
            mRoundedDefault = newRoundedDefault;
            mRoundedDefaultTop = newRoundedDefaultTop;
            mRoundedDefaultBottom = newRoundedDefaultBottom;
            onTuningChanged(SIZE, null);
        }
    }

    private void updateViews() {
        View topLeft = mOverlay.findViewById(R.id.left);
        View topRight = mOverlay.findViewById(R.id.right);
        View bottomLeft = mBottomOverlay.findViewById(R.id.left);
        View bottomRight = mBottomOverlay.findViewById(R.id.right);

        if (mRotation == RotationUtils.ROTATION_NONE) {
            updateView(topLeft, Gravity.TOP | Gravity.LEFT, 0);
            updateView(topRight, Gravity.TOP | Gravity.RIGHT, 90);
            updateView(bottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(bottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_LANDSCAPE) {
            updateView(topLeft, Gravity.TOP | Gravity.LEFT, 0);
            updateView(topRight, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(bottomLeft, Gravity.TOP | Gravity.RIGHT, 90);
            updateView(bottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_UPSIDE_DOWN) {
            updateView(topLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(topRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
            updateView(bottomLeft, Gravity.TOP | Gravity.LEFT, 0);
            updateView(bottomRight, Gravity.TOP | Gravity.RIGHT, 90);
        } else if (mRotation == RotationUtils.ROTATION_SEASCAPE) {
            updateView(topLeft, Gravity.BOTTOM | Gravity.RIGHT, 180);
            updateView(topRight, Gravity.TOP | Gravity.RIGHT, 90);
            updateView(bottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(bottomRight, Gravity.TOP | Gravity.LEFT, 0);
        }

        updateAssistantHandleViews();
        mCutoutTop.setRotation(mRotation);
        mCutoutBottom.setRotation(mRotation);

        updateWindowVisibilities();
    }

    private void updateAssistantHandleViews() {
        View assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
        View assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
        View assistHintBottomLeft = mBottomOverlay.findViewById(R.id.assist_hint_left);
        View assistHintBottomRight = mBottomOverlay.findViewById(R.id.assist_hint_right);

        final int assistHintVisibility = mAssistHintVisible ? View.VISIBLE : View.INVISIBLE;

        if (mRotation == RotationUtils.ROTATION_NONE) {
            assistHintTopLeft.setVisibility(View.GONE);
            assistHintTopRight.setVisibility(View.GONE);
            assistHintBottomLeft.setVisibility(assistHintVisibility);
            assistHintBottomRight.setVisibility(assistHintVisibility);
            updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_LANDSCAPE) {
            assistHintTopLeft.setVisibility(View.GONE);
            assistHintTopRight.setVisibility(assistHintVisibility);
            assistHintBottomLeft.setVisibility(View.GONE);
            assistHintBottomRight.setVisibility(assistHintVisibility);
            updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_UPSIDE_DOWN) {
            assistHintTopLeft.setVisibility(assistHintVisibility);
            assistHintTopRight.setVisibility(assistHintVisibility);
            assistHintBottomLeft.setVisibility(View.GONE);
            assistHintBottomRight.setVisibility(View.GONE);
            updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
            updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
        } else if (mRotation == RotationUtils.ROTATION_SEASCAPE) {
            assistHintTopLeft.setVisibility(assistHintVisibility);
            assistHintTopRight.setVisibility(View.GONE);
            assistHintBottomLeft.setVisibility(assistHintVisibility);
            assistHintBottomRight.setVisibility(View.GONE);
            updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.RIGHT, 180);
            updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
        }
    }

    private void updateView(View v, int gravity, int rotation) {
        ((FrameLayout.LayoutParams) v.getLayoutParams()).gravity = gravity;
        v.setRotation(rotation);
    }

    private void updateWindowVisibilities() {
        updateWindowVisibility(mOverlay);
        updateWindowVisibility(mBottomOverlay);
    }

    private void updateWindowVisibility(View overlay) {
        boolean visibleForCutout = shouldDrawCutout()
                && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE;
        boolean visibleForRoundedCorners = hasRoundedCorners();
        boolean visibleForHandles = overlay.findViewById(R.id.assist_hint_left).getVisibility()
                == View.VISIBLE || overlay.findViewById(R.id.assist_hint_right).getVisibility()
                == View.VISIBLE;
        overlay.setVisibility(visibleForCutout || visibleForRoundedCorners || visibleForHandles
                ? View.VISIBLE : View.GONE);
    }

    private boolean hasRoundedCorners() {
        return mRoundedDefault > 0 || mRoundedDefaultBottom > 0 || mRoundedDefaultTop > 0;
    }

    private boolean shouldDrawCutout() {
        return shouldDrawCutout(mContext);
    }

    static boolean shouldDrawCutout(Context context) {
        return context.getResources().getBoolean(
                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout);
    }


    private void setupStatusBarPaddingIfNeeded() {
        // TODO: This should be moved to a more appropriate place, as it is not related to the
        // screen decorations overlay.
        int padding = mContext.getResources().getDimensionPixelSize(
                R.dimen.rounded_corner_content_padding);
        if (padding != 0) {
            setupStatusBarPadding(padding);
        }

    }

    private void setupStatusBarPadding(int padding) {
        // Add some padding to all the content near the edge of the screen.
        StatusBar sb = getComponent(StatusBar.class);
        View statusBar = (sb != null ? sb.getStatusBarWindow() : null);
        if (statusBar != null) {
            TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
                    padding, FLAG_END);

            FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
            fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
                    new TunablePaddingTagListener(padding, R.id.status_bar));
            fragmentHostManager.addTagListener(QS.TAG,
                    new TunablePaddingTagListener(padding, R.id.header));
        }
    }

    @VisibleForTesting
    WindowManager.LayoutParams getWindowLayoutParams() {
        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                        | WindowManager.LayoutParams.FLAG_SLIPPERY
                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.TRANSLUCENT);
        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS
                | WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;

        if (!DEBUG_SCREENSHOT_ROUNDED_CORNERS) {
            lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
        }

        lp.setTitle("ScreenDecorOverlay");
        if (mRotation == RotationUtils.ROTATION_SEASCAPE
                || mRotation == RotationUtils.ROTATION_UPSIDE_DOWN) {
            lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
        } else {
            lp.gravity = Gravity.TOP | Gravity.LEFT;
        }
        lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
        if (isLandscape(mRotation)) {
            lp.width = WRAP_CONTENT;
            lp.height = MATCH_PARENT;
        }
        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
        return lp;
    }

    private WindowManager.LayoutParams getBottomLayoutParams() {
        WindowManager.LayoutParams lp = getWindowLayoutParams();
        lp.setTitle("ScreenDecorOverlayBottom");
        if (mRotation == RotationUtils.ROTATION_SEASCAPE
                || mRotation == RotationUtils.ROTATION_UPSIDE_DOWN) {
            lp.gravity = Gravity.TOP | Gravity.LEFT;
        } else {
            lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
        }
        return lp;
    }

    private void updateLayoutParams() {
        mWindowManager.updateViewLayout(mOverlay, getWindowLayoutParams());
        mWindowManager.updateViewLayout(mBottomOverlay, getBottomLayoutParams());
    }

    @Override
    public void onTuningChanged(String key, String newValue) {
        mHandler.post(() -> {
            if (mOverlay == null) return;
            if (SIZE.equals(key)) {
                int size = mRoundedDefault;
                int sizeTop = mRoundedDefaultTop;
                int sizeBottom = mRoundedDefaultBottom;
                if (newValue != null) {
                    try {
                        size = (int) (Integer.parseInt(newValue) * mDensity);
                    } catch (Exception e) {
                    }
                }

                if (sizeTop == 0) {
                    sizeTop = size;
                }
                if (sizeBottom == 0) {
                    sizeBottom = size;
                }

                setSize(mOverlay.findViewById(R.id.left), sizeTop);
                setSize(mOverlay.findViewById(R.id.right), sizeTop);
                setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
                setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
            }
        });
    }

    private void setSize(View view, int pixelSize) {
        LayoutParams params = view.getLayoutParams();
        params.width = pixelSize;
        params.height = pixelSize;
        view.setLayoutParams(params);
    }

    @Override
    public void onDarkIntensity(float darkIntensity) {
        if (!mHandler.getLooper().isCurrentThread()) {
            mHandler.post(() -> onDarkIntensity(darkIntensity));
            return;
        }
        if (mOverlay != null) {
            CornerHandleView assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
            CornerHandleView assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);

            assistHintTopLeft.updateDarkness(darkIntensity);
            assistHintTopRight.updateDarkness(darkIntensity);
        }

        if (mBottomOverlay != null) {
            CornerHandleView assistHintBottomLeft = mBottomOverlay.findViewById(
                    R.id.assist_hint_left);
            CornerHandleView assistHintBottomRight = mBottomOverlay.findViewById(
                    R.id.assist_hint_right);

            assistHintBottomLeft.updateDarkness(darkIntensity);
            assistHintBottomRight.updateDarkness(darkIntensity);
        }
    }

    @VisibleForTesting
    static class TunablePaddingTagListener implements FragmentListener {

        private final int mPadding;
        private final int mId;
        private TunablePadding mTunablePadding;

        public TunablePaddingTagListener(int padding, int id) {
            mPadding = padding;
            mId = id;
        }

        @Override
        public void onFragmentViewCreated(String tag, Fragment fragment) {
            if (mTunablePadding != null) {
                mTunablePadding.destroy();
            }
            View view = fragment.getView();
            if (mId != 0) {
                view = view.findViewById(mId);
            }
            mTunablePadding = TunablePadding.addTunablePadding(view, PADDING, mPadding,
                    FLAG_START | FLAG_END);
        }
    }

    public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener,
            RegionInterceptableView {

        private final DisplayInfo mInfo = new DisplayInfo();
        private final Paint mPaint = new Paint();
        private final List<Rect> mBounds = new ArrayList();
        private final Rect mBoundingRect = new Rect();
        private final Path mBoundingPath = new Path();
        private final int[] mLocation = new int[2];
        private final boolean mInitialStart;
        private final Runnable mVisibilityChangedListener;
        private final ScreenDecorations mDecorations;
        private int mColor = Color.BLACK;
        private boolean mStart;
        private int mRotation;

        public DisplayCutoutView(Context context, boolean start,
                Runnable visibilityChangedListener, ScreenDecorations decorations) {
            super(context);
            mInitialStart = start;
            mVisibilityChangedListener = visibilityChangedListener;
            mDecorations = decorations;
            setId(R.id.display_cutout);
            if (DEBUG) {
                getViewTreeObserver().addOnDrawListener(() -> Log.i(TAG,
                        (mInitialStart ? "OverlayTop" : "OverlayBottom")
                                + " drawn in rot " + mRotation));
            }
        }

        public void setColor(int color) {
            mColor = color;
            invalidate();
        }

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();
            mContext.getSystemService(DisplayManager.class).registerDisplayListener(this,
                    getHandler());
            update();
        }

        @Override
        protected void onDetachedFromWindow() {
            super.onDetachedFromWindow();
            mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            getLocationOnScreen(mLocation);
            canvas.translate(-mLocation[0], -mLocation[1]);
            if (!mBoundingPath.isEmpty()) {
                mPaint.setColor(mColor);
                mPaint.setStyle(Paint.Style.FILL);
                mPaint.setAntiAlias(true);
                canvas.drawPath(mBoundingPath, mPaint);
            }
        }

        @Override
        public void onDisplayAdded(int displayId) {
        }

        @Override
        public void onDisplayRemoved(int displayId) {
        }

        @Override
        public void onDisplayChanged(int displayId) {
            if (displayId == getDisplay().getDisplayId()) {
                update();
            }
        }

        public void setRotation(int rotation) {
            mRotation = rotation;
            update();
        }

        private boolean isStart() {
            final boolean flipped = (mRotation == RotationUtils.ROTATION_SEASCAPE
                    || mRotation == RotationUtils.ROTATION_UPSIDE_DOWN);
            return flipped ? !mInitialStart : mInitialStart;
        }

        private void update() {
            if (!isAttachedToWindow() || mDecorations.mPendingRotationChange) {
                return;
            }
            mStart = isStart();
            requestLayout();
            getDisplay().getDisplayInfo(mInfo);
            mBounds.clear();
            mBoundingRect.setEmpty();
            mBoundingPath.reset();
            int newVisible;
            if (shouldDrawCutout(getContext()) && hasCutout()) {
                mBounds.addAll(mInfo.displayCutout.getBoundingRects());
                localBounds(mBoundingRect);
                updateGravity();
                updateBoundingPath();
                invalidate();
                newVisible = VISIBLE;
            } else {
                newVisible = GONE;
            }
            if (newVisible != getVisibility()) {
                setVisibility(newVisible);
                mVisibilityChangedListener.run();
            }
        }

        private void updateBoundingPath() {
            int lw = mInfo.logicalWidth;
            int lh = mInfo.logicalHeight;

            boolean flipped = mInfo.rotation == ROTATION_90 || mInfo.rotation == ROTATION_270;

            int dw = flipped ? lh : lw;
            int dh = flipped ? lw : lh;

            mBoundingPath.set(DisplayCutout.pathFromResources(getResources(), dw, dh));
            Matrix m = new Matrix();
            transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m);
            mBoundingPath.transform(m);
        }

        private static void transformPhysicalToLogicalCoordinates(@Surface.Rotation int rotation,
                @Dimension int physicalWidth, @Dimension int physicalHeight, Matrix out) {
            switch (rotation) {
                case ROTATION_0:
                    out.reset();
                    break;
                case ROTATION_90:
                    out.setRotate(270);
                    out.postTranslate(0, physicalWidth);
                    break;
                case ROTATION_180:
                    out.setRotate(180);
                    out.postTranslate(physicalWidth, physicalHeight);
                    break;
                case ROTATION_270:
                    out.setRotate(90);
                    out.postTranslate(physicalHeight, 0);
                    break;
                default:
                    throw new IllegalArgumentException("Unknown rotation: " + rotation);
            }
        }

        private void updateGravity() {
            LayoutParams lp = getLayoutParams();
            if (lp instanceof FrameLayout.LayoutParams) {
                FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) lp;
                int newGravity = getGravity(mInfo.displayCutout);
                if (flp.gravity != newGravity) {
                    flp.gravity = newGravity;
                    setLayoutParams(flp);
                }
            }
        }

        private boolean hasCutout() {
            final DisplayCutout displayCutout = mInfo.displayCutout;
            if (displayCutout == null) {
                return false;
            }
            if (mStart) {
                return displayCutout.getSafeInsetLeft() > 0
                        || displayCutout.getSafeInsetTop() > 0;
            } else {
                return displayCutout.getSafeInsetRight() > 0
                        || displayCutout.getSafeInsetBottom() > 0;
            }
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            if (mBounds.isEmpty()) {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                return;
            }
            setMeasuredDimension(
                    resolveSizeAndState(mBoundingRect.width(), widthMeasureSpec, 0),
                    resolveSizeAndState(mBoundingRect.height(), heightMeasureSpec, 0));
        }

        public static void boundsFromDirection(DisplayCutout displayCutout, int gravity,
                Rect out) {
            switch (gravity) {
                case Gravity.TOP:
                    out.set(displayCutout.getBoundingRectTop());
                    break;
                case Gravity.LEFT:
                    out.set(displayCutout.getBoundingRectLeft());
                    break;
                case Gravity.BOTTOM:
                    out.set(displayCutout.getBoundingRectBottom());
                    break;
                case Gravity.RIGHT:
                    out.set(displayCutout.getBoundingRectRight());
                    break;
                default:
                    out.setEmpty();
            }
        }

        private void localBounds(Rect out) {
            DisplayCutout displayCutout = mInfo.displayCutout;
            boundsFromDirection(displayCutout, getGravity(displayCutout), out);
        }

        private int getGravity(DisplayCutout displayCutout) {
            if (mStart) {
                if (displayCutout.getSafeInsetLeft() > 0) {
                    return Gravity.LEFT;
                } else if (displayCutout.getSafeInsetTop() > 0) {
                    return Gravity.TOP;
                }
            } else {
                if (displayCutout.getSafeInsetRight() > 0) {
                    return Gravity.RIGHT;
                } else if (displayCutout.getSafeInsetBottom() > 0) {
                    return Gravity.BOTTOM;
                }
            }
            return Gravity.NO_GRAVITY;
        }

        @Override
        public boolean shouldInterceptTouch() {
            return mInfo.displayCutout != null && getVisibility() == VISIBLE;
        }

        @Override
        public Region getInterceptRegion() {
            if (mInfo.displayCutout == null) {
                return null;
            }

            View rootView = getRootView();
            Region cutoutBounds = rectsToRegion(
                    mInfo.displayCutout.getBoundingRects());

            // Transform to window's coordinate space
            rootView.getLocationOnScreen(mLocation);
            cutoutBounds.translate(-mLocation[0], -mLocation[1]);

            // Intersect with window's frame
            cutoutBounds.op(rootView.getLeft(), rootView.getTop(), rootView.getRight(),
                    rootView.getBottom(), Region.Op.INTERSECT);

            return cutoutBounds;
        }
    }

    private boolean isLandscape(int rotation) {
        return rotation == RotationUtils.ROTATION_LANDSCAPE || rotation ==
                RotationUtils.ROTATION_SEASCAPE;
    }

    /**
     * A pre-draw listener, that cancels the draw and restarts the traversal with the updated
     * window attributes.
     */
    private class RestartingPreDrawListener implements ViewTreeObserver.OnPreDrawListener {

        private final View mView;
        private final int mTargetRotation;

        private RestartingPreDrawListener(View view, int targetRotation) {
            mView = view;
            mTargetRotation = targetRotation;
        }

        @Override
        public boolean onPreDraw() {
            mView.getViewTreeObserver().removeOnPreDrawListener(this);

            if (mTargetRotation == mRotation) {
                if (DEBUG) {
                    Log.i(TAG, (mView == mOverlay ? "OverlayTop" : "OverlayBottom")
                            + " already in target rot "
                            + mTargetRotation + ", allow draw without restarting it");
                }
                return true;
            }

            mPendingRotationChange = false;
            // This changes the window attributes - we need to restart the traversal for them to
            // take effect.
            updateOrientation();
            if (DEBUG) {
                Log.i(TAG, (mView == mOverlay ? "OverlayTop" : "OverlayBottom")
                        + " restarting listener fired, restarting draw for rot " + mRotation);
            }
            mView.invalidate();
            return false;
        }
    }

    /**
     * A pre-draw listener, that validates that the rotation we draw in matches the displays
     * rotation before continuing the draw.
     *
     * This is to prevent a race condition, where we have not received the display changed event
     * yet, and would thus draw in an old orientation.
     */
    private class ValidatingPreDrawListener implements ViewTreeObserver.OnPreDrawListener {

        private final View mView;

        public ValidatingPreDrawListener(View view) {
            mView = view;
        }

        @Override
        public boolean onPreDraw() {
            final int displayRotation = RotationUtils.getExactRotation(mContext);
            if (displayRotation != mRotation && !mPendingRotationChange) {
                if (DEBUG) {
                    Log.i(TAG, "Drawing rot " + mRotation + ", but display is at rot "
                            + displayRotation + ". Restarting draw");
                }
                mView.invalidate();
                return false;
            }
            return true;
        }
    }
}
