Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10c1a6d6 authored by Jeremy Sim's avatar Jeremy Sim Committed by Android (Google) Code Review
Browse files

Merge changes I3158a1da,I43dadb7d into 24D1-dev

* changes:
  When resizing split and both sides are veiled, make sure both sides are veiled with the same color
  Show veil over main app when splitting from fullscreen
parents 6d4a1b39 4fe73353
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -347,7 +347,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
                if (mMoving) {
                    final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos;
                    mLastDraggingPosition = position;
                    mSplitLayout.updateDivideBounds(position);
                    mSplitLayout.updateDivideBounds(position, true /* shouldUseParallaxEffect */);
                }
                break;
            case MotionEvent.ACTION_UP:
+40 −26
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -56,7 +55,13 @@ import com.android.wm.shell.common.SurfaceUtils;
import java.util.function.Consumer;

/**
 * Handles split decor like showing resizing hint for a specific split.
 * Handles additional layers over a running task in a split pair, for example showing a veil with an
 * app icon when the task is being resized (usually to hide weird layouts while the app is being
 * stretched). One SplitDecorManager is initialized on each window.
 * <br>
 * Currently, we show a veil when:
 *  a) Task is resizing down from a fullscreen window.
 *  b) Task is being stretched past its original bounds.
 */
public class SplitDecorManager extends WindowlessWindowManager {
    private static final String TAG = SplitDecorManager.class.getSimpleName();
@@ -77,7 +82,11 @@ public class SplitDecorManager extends WindowlessWindowManager {

    private boolean mShown;
    private boolean mIsResizing;
    private final Rect mOldBounds = new Rect();
    /** The original bounds of the main task, captured at the beginning of a resize transition. */
    private final Rect mOldMainBounds = new Rect();
    /** The original bounds of the side task, captured at the beginning of a resize transition. */
    private final Rect mOldSideBounds = new Rect();
    /** The current bounds of the main task, mid-resize. */
    private final Rect mResizingBounds = new Rect();
    private final Rect mTempRect = new Rect();
    private ValueAnimator mFadeAnimator;
@@ -184,29 +193,38 @@ public class SplitDecorManager extends WindowlessWindowManager {
        mResizingIconView = null;
        mIsResizing = false;
        mShown = false;
        mOldBounds.setEmpty();
        mOldMainBounds.setEmpty();
        mOldSideBounds.setEmpty();
        mResizingBounds.setEmpty();
    }

    /** Showing resizing hint. */
    public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds,
            Rect sideBounds, SurfaceControl.Transaction t, int offsetX, int offsetY,
            boolean immediately) {
            boolean immediately, float[] veilColor) {
        if (mResizingIconView == null) {
            return;
        }

        if (!mIsResizing) {
            mIsResizing = true;
            mOldBounds.set(newBounds);
            mOldMainBounds.set(newBounds);
            mOldSideBounds.set(sideBounds);
        }
        mResizingBounds.set(newBounds);
        mOffsetX = offsetX;
        mOffsetY = offsetY;

        final boolean show =
                newBounds.width() > mOldBounds.width() || newBounds.height() > mOldBounds.height();
        final boolean update = show != mShown;
        // Show a veil when:
        //  a) Task is resizing down from a fullscreen window.
        //  b) Task is being stretched past its original bounds.
        final boolean isResizingDownFromFullscreen =
                mOldSideBounds.width() <= 1 || mOldSideBounds.height() <= 1;
        final boolean isStretchingPastOriginalBounds =
                newBounds.width() > mOldMainBounds.width()
                        || newBounds.height() > mOldMainBounds.height();
        final boolean showVeil = isResizingDownFromFullscreen || isStretchingPastOriginalBounds;
        final boolean update = showVeil != mShown;
        if (update && mFadeAnimator != null && mFadeAnimator.isRunning()) {
            // If we need to animate and animator still running, cancel it before we ensure both
            // background and icon surfaces are non null for next animation.
@@ -216,18 +234,18 @@ public class SplitDecorManager extends WindowlessWindowManager {
        if (mBackgroundLeash == null) {
            mBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
                    RESIZING_BACKGROUND_SURFACE_NAME, mSurfaceSession);
            t.setColor(mBackgroundLeash, getResizingBackgroundColor(resizingTask))
            t.setColor(mBackgroundLeash, veilColor)
                    .setLayer(mBackgroundLeash, Integer.MAX_VALUE - 1);
        }

        if (mGapBackgroundLeash == null && !immediately) {
            final boolean isLandscape = newBounds.height() == sideBounds.height();
            final int left = isLandscape ? mOldBounds.width() : 0;
            final int top = isLandscape ? 0 : mOldBounds.height();
            final int left = isLandscape ? mOldMainBounds.width() : 0;
            final int top = isLandscape ? 0 : mOldMainBounds.height();
            mGapBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
                    GAP_BACKGROUND_SURFACE_NAME, mSurfaceSession);
            // Fill up another side bounds area.
            t.setColor(mGapBackgroundLeash, getResizingBackgroundColor(resizingTask))
            t.setColor(mGapBackgroundLeash, veilColor)
                    .setLayer(mGapBackgroundLeash, Integer.MAX_VALUE - 2)
                    .setPosition(mGapBackgroundLeash, left, top)
                    .setWindowCrop(mGapBackgroundLeash, sideBounds.width(), sideBounds.height());
@@ -251,12 +269,12 @@ public class SplitDecorManager extends WindowlessWindowManager {

        if (update) {
            if (immediately) {
                t.setVisibility(mBackgroundLeash, show);
                t.setVisibility(mIconLeash, show);
                t.setVisibility(mBackgroundLeash, showVeil);
                t.setVisibility(mIconLeash, showVeil);
            } else {
                startFadeAnimation(show, false, null);
                startFadeAnimation(showVeil, false, null);
            }
            mShown = show;
            mShown = showVeil;
        }
    }

@@ -309,7 +327,8 @@ public class SplitDecorManager extends WindowlessWindowManager {
        mIsResizing = false;
        mOffsetX = 0;
        mOffsetY = 0;
        mOldBounds.setEmpty();
        mOldMainBounds.setEmpty();
        mOldSideBounds.setEmpty();
        mResizingBounds.setEmpty();
        if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
            if (!mShown) {
@@ -346,14 +365,14 @@ public class SplitDecorManager extends WindowlessWindowManager {

    /** Screenshot host leash and attach on it if meet some conditions */
    public void screenshotIfNeeded(SurfaceControl.Transaction t) {
        if (!mShown && mIsResizing && !mOldBounds.equals(mResizingBounds)) {
        if (!mShown && mIsResizing && !mOldMainBounds.equals(mResizingBounds)) {
            if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) {
                mScreenshotAnimator.cancel();
            } else if (mScreenshot != null) {
                t.remove(mScreenshot);
            }

            mTempRect.set(mOldBounds);
            mTempRect.set(mOldMainBounds);
            mTempRect.offsetTo(0, 0);
            mScreenshot = ScreenshotUtils.takeScreenshot(t, mHostLeash, mTempRect,
                    Integer.MAX_VALUE - 1);
@@ -364,7 +383,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
    public void setScreenshotIfNeeded(SurfaceControl screenshot, SurfaceControl.Transaction t) {
        if (screenshot == null || !screenshot.isValid()) return;

        if (!mShown && mIsResizing && !mOldBounds.equals(mResizingBounds)) {
        if (!mShown && mIsResizing && !mOldMainBounds.equals(mResizingBounds)) {
            if (mScreenshotAnimator != null && mScreenshotAnimator.isRunning()) {
                mScreenshotAnimator.cancel();
            } else if (mScreenshot != null) {
@@ -465,9 +484,4 @@ public class SplitDecorManager extends WindowlessWindowManager {
            mIcon = null;
        }
    }

    private static float[] getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
        final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
        return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).getComponents();
    }
}
+7 −4
Original line number Diff line number Diff line
@@ -496,10 +496,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
     * Updates bounds with the passing position. Usually used to update recording bounds while
     * performing animation or dragging divider bar to resize the splits.
     */
    void updateDivideBounds(int position) {
    void updateDivideBounds(int position, boolean shouldUseParallaxEffect) {
        updateBounds(position);
        mSplitLayoutHandler.onLayoutSizeChanging(this, mSurfaceEffectPolicy.mParallaxOffset.x,
                mSurfaceEffectPolicy.mParallaxOffset.y);
                mSurfaceEffectPolicy.mParallaxOffset.y, shouldUseParallaxEffect);
    }

    void setDividePosition(int position, boolean applyLayoutChange) {
@@ -647,7 +647,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                .setDuration(duration);
        mDividerFlingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
        mDividerFlingAnimator.addUpdateListener(
                animation -> updateDivideBounds((int) animation.getAnimatedValue()));
                animation -> updateDivideBounds(
                        (int) animation.getAnimatedValue(), false /* shouldUseParallaxEffect */)
        );
        mDividerFlingAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
@@ -897,7 +899,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
         * @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl,
         * SurfaceControl, SurfaceControl, boolean)
         */
        void onLayoutSizeChanging(SplitLayout layout, int offsetX, int offsetY);
        void onLayoutSizeChanging(SplitLayout layout, int offsetX, int offsetY,
                boolean shouldUseParallaxEffect);

        /**
         * Calls when finish resizing the split bounds.
+7 −10
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.wm.shell.common.split;

import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_ALL_KINDS_WITH_ALL_PINNED;

import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.common.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
@@ -26,25 +24,18 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT

import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.UserHandle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.util.ArrayUtils;
import com.android.wm.shell.Flags;
import com.android.wm.shell.ShellTaskOrganizer;

import java.util.Arrays;
import java.util.List;

/** Helper utility class for split screen components to use. */
public class SplitScreenUtils {
    /** Reverse the split position. */
@@ -137,4 +128,10 @@ public class SplitScreenUtils {
            return isLandscape;
        }
    }

    /** Returns the specified background color that matches a RunningTaskInfo. */
    public static Color getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
        final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
        return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor);
    }
}
+4 −10
Original line number Diff line number Diff line
@@ -22,11 +22,11 @@ import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;

import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenUtils.getResizingBackgroundColor;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT;
import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT;
@@ -41,7 +41,6 @@ import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Region;
@@ -278,7 +277,7 @@ public class DragLayout extends LinearLayout
                final int activityType = taskInfo1.getActivityType();
                if (activityType == ACTIVITY_TYPE_STANDARD) {
                    Drawable icon1 = mIconProvider.getIcon(taskInfo1.topActivityInfo);
                    int bgColor1 = getResizingBackgroundColor(taskInfo1);
                    int bgColor1 = getResizingBackgroundColor(taskInfo1).toArgb();
                    mDropZoneView1.setAppInfo(bgColor1, icon1);
                    mDropZoneView2.setAppInfo(bgColor1, icon1);
                    updateDropZoneSizes(null, null); // passing null splits the views evenly
@@ -298,10 +297,10 @@ public class DragLayout extends LinearLayout
                    mSplitScreenController.getTaskInfo(SPLIT_POSITION_BOTTOM_OR_RIGHT);
            if (topOrLeftTask != null && bottomOrRightTask != null) {
                Drawable topOrLeftIcon = mIconProvider.getIcon(topOrLeftTask.topActivityInfo);
                int topOrLeftColor = getResizingBackgroundColor(topOrLeftTask);
                int topOrLeftColor = getResizingBackgroundColor(topOrLeftTask).toArgb();
                Drawable bottomOrRightIcon = mIconProvider.getIcon(
                        bottomOrRightTask.topActivityInfo);
                int bottomOrRightColor = getResizingBackgroundColor(bottomOrRightTask);
                int bottomOrRightColor = getResizingBackgroundColor(bottomOrRightTask).toArgb();
                mDropZoneView1.setAppInfo(topOrLeftColor, topOrLeftIcon);
                mDropZoneView2.setAppInfo(bottomOrRightColor, bottomOrRightIcon);
            }
@@ -556,11 +555,6 @@ public class DragLayout extends LinearLayout
        }
    }

    private static int getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
        final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
        return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).toArgb();
    }

    /**
     * Dumps information about this drag layout.
     */
Loading