/*
 * Copyright (C) 2016 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.server.wm;

import static android.graphics.Color.WHITE;
import static android.graphics.Color.alpha;
import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
import static android.view.WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES;
import static android.view.WindowManager.LayoutParams.FLAG_LOCAL_FOCUS_MODE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;

import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES;
import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;
import static com.android.internal.policy.DecorView.getColorViewLeftInset;
import static com.android.internal.policy.DecorView.getColorViewTopInset;
import static com.android.internal.policy.DecorView.getNavigationBarRect;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.annotation.Nullable;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityThread;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.GraphicBuffer;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.MergedConfiguration;
import android.util.Slog;
import android.view.DisplayCutout;
import android.view.IWindowSession;
import android.view.InsetsState;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.DecorView;
import com.android.internal.view.BaseIWindow;
import com.android.server.policy.WindowManagerPolicy.StartingSurface;
import com.android.server.protolog.common.ProtoLog;

/**
 * This class represents a starting window that shows a snapshot.
 * <p>
 * DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING METHODS OF THIS CLASS!
 */
class TaskSnapshotSurface implements StartingSurface {

    private static final long SIZE_MISMATCH_MINIMUM_TIME_MS = 450;

    /**
     * When creating the starting window, we use the exact same layout flags such that we end up
     * with a window with the exact same dimensions etc. However, these flags are not used in layout
     * and might cause other side effects so we exclude them.
     */
    private static final int FLAG_INHERIT_EXCLUDES = FLAG_NOT_FOCUSABLE
            | FLAG_NOT_TOUCHABLE
            | FLAG_NOT_TOUCH_MODAL
            | FLAG_ALT_FOCUSABLE_IM
            | FLAG_NOT_FOCUSABLE
            | FLAG_HARDWARE_ACCELERATED
            | FLAG_IGNORE_CHEEK_PRESSES
            | FLAG_LOCAL_FOCUS_MODE
            | FLAG_SLIPPERY
            | FLAG_WATCH_OUTSIDE_TOUCH
            | FLAG_SPLIT_TOUCH
            | FLAG_SCALED
            | FLAG_SECURE;

    private static final int PRIVATE_FLAG_INHERITS = PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;

    private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotStartingWindow" : TAG_WM;
    private static final int MSG_REPORT_DRAW = 0;
    private static final String TITLE_FORMAT = "SnapshotStartingWindow for taskId=%s";
    private static final Point sSurfaceSize = new Point(); //tmp var for unused relayout param
    private final Window mWindow;
    private final Surface mSurface;
    private SurfaceControl mSurfaceControl;
    private SurfaceControl mChildSurfaceControl;
    private final IWindowSession mSession;
    private final WindowManagerService mService;
    private final Rect mTaskBounds;
    private final Rect mStableInsets = new Rect();
    private final Rect mContentInsets = new Rect();
    private final Rect mFrame = new Rect();
    private TaskSnapshot mSnapshot;
    private final CharSequence mTitle;
    private boolean mHasDrawn;
    private long mShownTime;
    private final Handler mHandler;
    private boolean mSizeMismatch;
    private final Paint mBackgroundPaint = new Paint();
    private final int mStatusBarColor;
    @VisibleForTesting final SystemBarBackgroundPainter mSystemBarBackgroundPainter;
    private final int mOrientationOnCreation;
    private final SurfaceControl.Transaction mTransaction;

    static TaskSnapshotSurface create(WindowManagerService service, ActivityRecord activity,
            TaskSnapshot snapshot) {

        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
        final Window window = new Window();
        final IWindowSession session = WindowManagerGlobal.getWindowSession();
        window.setSession(session);
        final SurfaceControl surfaceControl = new SurfaceControl();
        final Rect tmpRect = new Rect();
        final DisplayCutout.ParcelableWrapper tmpCutout = new DisplayCutout.ParcelableWrapper();
        final Rect tmpFrame = new Rect();
        final Rect taskBounds;
        final Rect tmpContentInsets = new Rect();
        final Rect tmpStableInsets = new Rect();
        final InsetsState mTmpInsetsState = new InsetsState();
        final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration();
        final TaskDescription taskDescription = new TaskDescription();
        taskDescription.setBackgroundColor(WHITE);
        final WindowState topFullscreenOpaqueWindow;
        final int sysUiVis;
        final int windowFlags;
        final int windowPrivateFlags;
        final int currentOrientation;
        synchronized (service.mGlobalLock) {
            final WindowState mainWindow = activity.findMainWindow();
            final Task task = activity.getTask();
            if (task == null) {
                Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find task for activity="
                        + activity);
                return null;
            }
            final ActivityRecord topFullscreenActivity =
                    activity.getTask().getTopFullscreenActivity();
            if (topFullscreenActivity == null) {
                Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find top fullscreen for task="
                        + task);
                return null;
            }
            topFullscreenOpaqueWindow = topFullscreenActivity.getTopFullscreenOpaqueWindow();
            if (mainWindow == null || topFullscreenOpaqueWindow == null) {
                Slog.w(TAG, "TaskSnapshotSurface.create: Failed to find main window for activity="
                        + activity);
                return null;
            }
            sysUiVis = topFullscreenOpaqueWindow.getSystemUiVisibility();
            windowFlags = topFullscreenOpaqueWindow.getAttrs().flags;
            windowPrivateFlags = topFullscreenOpaqueWindow.getAttrs().privateFlags;

            layoutParams.packageName = mainWindow.getAttrs().packageName;
            layoutParams.windowAnimations = mainWindow.getAttrs().windowAnimations;
            layoutParams.dimAmount = mainWindow.getAttrs().dimAmount;
            layoutParams.type = TYPE_APPLICATION_STARTING;
            layoutParams.format = snapshot.getSnapshot().getFormat();
            layoutParams.flags = (windowFlags & ~FLAG_INHERIT_EXCLUDES)
                    | FLAG_NOT_FOCUSABLE
                    | FLAG_NOT_TOUCHABLE;
            layoutParams.privateFlags = windowPrivateFlags & PRIVATE_FLAG_INHERITS;
            layoutParams.token = activity.token;
            layoutParams.width = LayoutParams.MATCH_PARENT;
            layoutParams.height = LayoutParams.MATCH_PARENT;
            layoutParams.systemUiVisibility = sysUiVis;
            layoutParams.setTitle(String.format(TITLE_FORMAT, task.mTaskId));

            final TaskDescription td = task.getTaskDescription();
            if (td != null) {
                taskDescription.copyFromPreserveHiddenFields(td);
            }
            taskBounds = new Rect();
            task.getBounds(taskBounds);
            currentOrientation = topFullscreenOpaqueWindow.getConfiguration().orientation;
        }
        try {
            final int res = session.addToDisplay(window, window.mSeq, layoutParams,
                    View.GONE, activity.getDisplayContent().getDisplayId(), tmpFrame, tmpRect, tmpRect,
                    tmpCutout, null, mTmpInsetsState);
            if (res < 0) {
                Slog.w(TAG, "Failed to add snapshot starting window res=" + res);
                return null;
            }
        } catch (RemoteException e) {
            // Local call.
        }
        final TaskSnapshotSurface snapshotSurface = new TaskSnapshotSurface(service, window,
                surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, sysUiVis,
                windowFlags, windowPrivateFlags, taskBounds,
                currentOrientation, topFullscreenOpaqueWindow.getRequestedInsetsState());
        window.setOuter(snapshotSurface);
        try {
            session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, -1,
                    tmpFrame, tmpContentInsets, tmpRect, tmpStableInsets, tmpRect,
                    tmpCutout, tmpMergedConfiguration, surfaceControl, mTmpInsetsState,
                    sSurfaceSize);
        } catch (RemoteException e) {
            // Local call.
        }
        snapshotSurface.setFrames(tmpFrame, tmpContentInsets, tmpStableInsets);
        snapshotSurface.drawSnapshot();
        return snapshotSurface;
    }

    @VisibleForTesting
    TaskSnapshotSurface(WindowManagerService service, Window window, SurfaceControl surfaceControl,
            TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription,
            int sysUiVis, int windowFlags, int windowPrivateFlags, Rect taskBounds,
            int currentOrientation, InsetsState insetsState) {
        mService = service;
        mSurface = service.mSurfaceFactory.get();
        mHandler = new Handler(mService.mH.getLooper());
        mSession = WindowManagerGlobal.getWindowSession();
        mWindow = window;
        mSurfaceControl = surfaceControl;
        mSnapshot = snapshot;
        mTitle = title;
        int backgroundColor = taskDescription.getBackgroundColor();
        mBackgroundPaint.setColor(backgroundColor != 0 ? backgroundColor : WHITE);
        mTaskBounds = taskBounds;
        mSystemBarBackgroundPainter = new SystemBarBackgroundPainter(windowFlags,
                windowPrivateFlags, sysUiVis, taskDescription, 1f, insetsState);
        mStatusBarColor = taskDescription.getStatusBarColor();
        mOrientationOnCreation = currentOrientation;
        mTransaction = mService.mTransactionFactory.get();
    }

    @Override
    public void remove() {
        synchronized (mService.mGlobalLock) {
            final long now = SystemClock.uptimeMillis();
            if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS) {
                mHandler.postAtTime(this::remove, mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS);
                ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
                        "Defer removing snapshot surface in %dms", (now - mShownTime));

                return;
            }
        }
        try {
            ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Removing snapshot surface");
            mSession.remove(mWindow);
        } catch (RemoteException e) {
            // Local call.
        }
    }

    @VisibleForTesting
    void setFrames(Rect frame, Rect contentInsets, Rect stableInsets) {
        mFrame.set(frame);
        mContentInsets.set(contentInsets);
        mStableInsets.set(stableInsets);
        mSizeMismatch = (mFrame.width() != mSnapshot.getSnapshot().getWidth()
                || mFrame.height() != mSnapshot.getSnapshot().getHeight());
        mSystemBarBackgroundPainter.setInsets(contentInsets, stableInsets);
    }

    private void drawSnapshot() {
        mSurface.copyFrom(mSurfaceControl);

        ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Drawing snapshot surface sizeMismatch=%b",
                mSizeMismatch);
        if (mSizeMismatch) {
            // The dimensions of the buffer and the window don't match, so attaching the buffer
            // will fail. Better create a child window with the exact dimensions and fill the parent
            // window with the background color!
            drawSizeMismatchSnapshot();
        } else {
            drawSizeMatchSnapshot();
        }
        synchronized (mService.mGlobalLock) {
            mShownTime = SystemClock.uptimeMillis();
            mHasDrawn = true;
        }
        reportDrawn();

        // In case window manager leaks us, make sure we don't retain the snapshot.
        mSnapshot = null;
    }

    private void drawSizeMatchSnapshot() {
        mSurface.attachAndQueueBufferWithColorSpace(mSnapshot.getSnapshot(),
                mSnapshot.getColorSpace());
        mSurface.release();
    }

    private void drawSizeMismatchSnapshot() {
        if (!mSurface.isValid()) {
            throw new IllegalStateException("mSurface does not hold a valid surface.");
        }
        final GraphicBuffer buffer = mSnapshot.getSnapshot();
        final SurfaceSession session = new SurfaceSession();
        // We consider nearly matched dimensions as there can be rounding errors and the user won't
        // notice very minute differences from scaling one dimension more than the other
        final boolean aspectRatioMismatch = Math.abs(
                ((float) buffer.getWidth() / buffer.getHeight())
                - ((float) mFrame.width() / mFrame.height())) > 0.01f;

        // Keep a reference to it such that it doesn't get destroyed when finalized.
        mChildSurfaceControl = mService.mSurfaceControlFactory.apply(session)
                .setName(mTitle + " - task-snapshot-surface")
                .setBufferSize(buffer.getWidth(), buffer.getHeight())
                .setFormat(buffer.getFormat())
                .setParent(mSurfaceControl)
                .build();
        Surface surface = mService.mSurfaceFactory.get();
        surface.copyFrom(mChildSurfaceControl);

        final Rect frame;
        // We can just show the surface here as it will still be hidden as the parent is
        // still hidden.
        mTransaction.show(mChildSurfaceControl);
        if (aspectRatioMismatch) {
            // Clip off ugly navigation bar.
            final Rect crop = calculateSnapshotCrop();
            frame = calculateSnapshotFrame(crop);
            mTransaction.setWindowCrop(mChildSurfaceControl, crop);
            mTransaction.setPosition(mChildSurfaceControl, frame.left, frame.top);
        } else {
            frame = null;
        }

        // Scale the mismatch dimensions to fill the task bounds
        final float scale = 1 / mSnapshot.getScale();
        mTransaction.setMatrix(mChildSurfaceControl, scale, 0, 0, scale);
        mTransaction.apply();
        surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace());
        surface.release();

        if (aspectRatioMismatch) {
            final Canvas c = mSurface.lockCanvas(null);
            drawBackgroundAndBars(c, frame);
            mSurface.unlockCanvasAndPost(c);
            mSurface.release();
        }
    }

    /**
     * Calculates the snapshot crop in snapshot coordinate space.
     *
     * @return crop rect in snapshot coordinate space.
     */
    @VisibleForTesting
    Rect calculateSnapshotCrop() {
        final Rect rect = new Rect();
        rect.set(0, 0, mSnapshot.getSnapshot().getWidth(), mSnapshot.getSnapshot().getHeight());
        final Rect insets = mSnapshot.getContentInsets();

        // Let's remove all system decorations except the status bar, but only if the task is at the
        // very top of the screen.
        final boolean isTop = mTaskBounds.top == 0 && mFrame.top == 0;
        rect.inset((int) (insets.left * mSnapshot.getScale()),
                isTop ? 0 : (int) (insets.top * mSnapshot.getScale()),
                (int) (insets.right * mSnapshot.getScale()),
                (int) (insets.bottom * mSnapshot.getScale()));
        return rect;
    }

    /**
     * Calculates the snapshot frame in window coordinate space from crop.
     *
     * @param crop rect that is in snapshot coordinate space.
     */
    @VisibleForTesting
    Rect calculateSnapshotFrame(Rect crop) {
        final Rect frame = new Rect(crop);
        final float scale = mSnapshot.getScale();

        // Rescale the frame from snapshot to window coordinate space
        frame.scale(1 / scale);

        // By default, offset it to to top/left corner
        frame.offsetTo((int) (-crop.left / scale), (int) (-crop.top / scale));

        // However, we also need to make space for the navigation bar on the left side.
        final int colorViewLeftInset = getColorViewLeftInset(mStableInsets.left,
                mContentInsets.left);
        frame.offset(colorViewLeftInset, 0);
        return frame;
    }

    @VisibleForTesting
    void drawBackgroundAndBars(Canvas c, Rect frame) {
        final int statusBarHeight = mSystemBarBackgroundPainter.getStatusBarColorViewHeight();
        final boolean fillHorizontally = c.getWidth() > frame.right;
        final boolean fillVertically = c.getHeight() > frame.bottom;
        if (fillHorizontally) {
            c.drawRect(frame.right, alpha(mStatusBarColor) == 0xFF ? statusBarHeight : 0,
                    c.getWidth(), fillVertically
                            ? frame.bottom
                            : c.getHeight(),
                    mBackgroundPaint);
        }
        if (fillVertically) {
            c.drawRect(0, frame.bottom, c.getWidth(), c.getHeight(), mBackgroundPaint);
        }
        mSystemBarBackgroundPainter.drawDecors(c, frame);
    }

    private void reportDrawn() {
        try {
            mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
        } catch (RemoteException e) {
            // Local call.
        }
    }

    private static Handler sHandler = new Handler(Looper.getMainLooper()) {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_REPORT_DRAW:
                    final boolean hasDrawn;
                    final TaskSnapshotSurface surface = (TaskSnapshotSurface) msg.obj;
                    synchronized (surface.mService.mGlobalLock) {
                        hasDrawn = surface.mHasDrawn;
                    }
                    if (hasDrawn) {
                        surface.reportDrawn();
                    }
                    break;
            }
        }
    };

    @VisibleForTesting
    static class Window extends BaseIWindow {

        private TaskSnapshotSurface mOuter;

        public void setOuter(TaskSnapshotSurface outer) {
            mOuter = outer;
        }

        @Override
        public void resized(Rect frame, Rect contentInsets, Rect visibleInsets,
                Rect stableInsets, boolean reportDraw,
                MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout,
                boolean alwaysConsumeSystemBars, int displayId,
                DisplayCutout.ParcelableWrapper displayCutout) {
            if (mergedConfiguration != null && mOuter != null
                    && mOuter.mOrientationOnCreation
                            != mergedConfiguration.getMergedConfiguration().orientation) {

                // The orientation of the screen is changing. We better remove the snapshot ASAP as
                // we are going to wait on the new window in any case to unfreeze the screen, and
                // the starting window is not needed anymore.
                sHandler.post(mOuter::remove);
            }
            if (reportDraw) {
                sHandler.obtainMessage(MSG_REPORT_DRAW, mOuter).sendToTarget();
            }
        }
    }

    /**
     * Helper class to draw the background of the system bars in regions the task snapshot isn't
     * filling the window.
     */
    static class SystemBarBackgroundPainter {

        private final Rect mContentInsets = new Rect();
        private final Rect mStableInsets = new Rect();
        private final Paint mStatusBarPaint = new Paint();
        private final Paint mNavigationBarPaint = new Paint();
        private final int mStatusBarColor;
        private final int mNavigationBarColor;
        private final int mWindowFlags;
        private final int mWindowPrivateFlags;
        private final int mSysUiVis;
        private final float mScale;
        private final InsetsState mInsetsState;

        SystemBarBackgroundPainter(int windowFlags, int windowPrivateFlags, int sysUiVis,
                TaskDescription taskDescription, float scale, InsetsState insetsState) {
            mWindowFlags = windowFlags;
            mWindowPrivateFlags = windowPrivateFlags;
            mSysUiVis = sysUiVis;
            mScale = scale;
            final Context context = ActivityThread.currentActivityThread().getSystemUiContext();
            final int semiTransparent = context.getColor(
                    R.color.system_bar_background_semi_transparent);
            mStatusBarColor = DecorView.calculateBarColor(windowFlags, FLAG_TRANSLUCENT_STATUS,
                    semiTransparent, taskDescription.getStatusBarColor(), sysUiVis,
                    SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
                    taskDescription.getEnsureStatusBarContrastWhenTransparent());
            mNavigationBarColor = DecorView.calculateBarColor(windowFlags,
                    FLAG_TRANSLUCENT_NAVIGATION, semiTransparent,
                    taskDescription.getNavigationBarColor(), sysUiVis,
                    SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
                    taskDescription.getEnsureNavigationBarContrastWhenTransparent()
                            && context.getResources().getBoolean(R.bool.config_navBarNeedsScrim));
            mStatusBarPaint.setColor(mStatusBarColor);
            mNavigationBarPaint.setColor(mNavigationBarColor);
            mInsetsState = insetsState;
        }

        void setInsets(Rect contentInsets, Rect stableInsets) {
            mContentInsets.set(contentInsets);
            mStableInsets.set(stableInsets);
        }

        int getStatusBarColorViewHeight() {
            final boolean forceBarBackground =
                    (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
            if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL
                    ? STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
                            mSysUiVis, mStatusBarColor, mWindowFlags, forceBarBackground)
                    : STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
                            mInsetsState, mStatusBarColor, mWindowFlags, forceBarBackground)) {
                return (int) (getColorViewTopInset(mStableInsets.top, mContentInsets.top) * mScale);
            } else {
                return 0;
            }
        }

        private boolean isNavigationBarColorViewVisible() {
            final boolean forceBarBackground =
                    (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) != 0;
            return ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL
                    ? NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
                            mSysUiVis, mNavigationBarColor, mWindowFlags, forceBarBackground)
                    : NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
                            mInsetsState, mNavigationBarColor, mWindowFlags, forceBarBackground);
        }

        void drawDecors(Canvas c, @Nullable Rect alreadyDrawnFrame) {
            drawStatusBarBackground(c, alreadyDrawnFrame, getStatusBarColorViewHeight());
            drawNavigationBarBackground(c);
        }

        @VisibleForTesting
        void drawStatusBarBackground(Canvas c, @Nullable Rect alreadyDrawnFrame,
                int statusBarHeight) {
            if (statusBarHeight > 0 && Color.alpha(mStatusBarColor) != 0
                    && (alreadyDrawnFrame == null || c.getWidth() > alreadyDrawnFrame.right)) {
                final int rightInset = (int) (DecorView.getColorViewRightInset(mStableInsets.right,
                        mContentInsets.right) * mScale);
                final int left = alreadyDrawnFrame != null ? alreadyDrawnFrame.right : 0;
                c.drawRect(left, 0, c.getWidth() - rightInset, statusBarHeight, mStatusBarPaint);
            }
        }

        @VisibleForTesting
        void drawNavigationBarBackground(Canvas c) {
            final Rect navigationBarRect = new Rect();
            getNavigationBarRect(c.getWidth(), c.getHeight(), mStableInsets, mContentInsets,
                    navigationBarRect, mScale);
            final boolean visible = isNavigationBarColorViewVisible();
            if (visible && Color.alpha(mNavigationBarColor) != 0 && !navigationBarRect.isEmpty()) {
                c.drawRect(navigationBarRect, mNavigationBarPaint);
            }
        }
    }
}
