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

Commit d7583de7 authored by Jiaming Liu's avatar Jiaming Liu
Browse files

[Divider] Use window background color for veils while dragging

Use the window background color as the veil color while dragging.
Default color is used only when such info is unavailable, i.e.
cross-process embedding.

Bug: 327067596
Test: atest DividerPresenterTest
Change-Id: I5df34ec754cf5c86240df8d037a0052bb792180d
parent 6c9cdef7
Loading
Loading
Loading
Loading
+40 −5
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSI

import android.annotation.DimenRes;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityThread;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -42,6 +43,7 @@ import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RotateDrawable;
import android.hardware.display.DisplayManager;
@@ -213,7 +215,11 @@ class DividerPresenter implements View.OnTouchListener {
                            isVerticalSplit,
                            isReversedLayout,
                            parentInfo.getDisplayId(),
                            isDraggableExpandType
                            isDraggableExpandType,
                            getContainerBackgroundColor(topSplitContainer.getPrimaryContainer(),
                                    DEFAULT_PRIMARY_VEIL_COLOR),
                            getContainerBackgroundColor(topSplitContainer.getSecondaryContainer(),
                                    DEFAULT_SECONDARY_VEIL_COLOR)
                    ));
        }
    }
@@ -241,6 +247,27 @@ class DividerPresenter implements View.OnTouchListener {
        }
    }

    /**
     * Returns the window background color of the top activity in the container if set, or the
     * default color if the background color of the top activity is unavailable.
     */
    @VisibleForTesting
    @NonNull
    static Color getContainerBackgroundColor(
            @NonNull TaskFragmentContainer container, @NonNull Color defaultColor) {
        final Activity activity = container.getTopNonFinishingActivity();
        if (activity == null || !activity.isResumed()) {
            // This can happen when the top activity in the container is from a different process.
            return defaultColor;
        }

        final Drawable drawable = activity.getWindow().getDecorView().getBackground();
        if (drawable instanceof ColorDrawable colorDrawable) {
            return Color.valueOf(colorDrawable.getColor());
        }
        return defaultColor;
    }

    /**
     * Creates a decor surface for the TaskFragment if no decor surface exists, or changes the owner
     * of the existing decor surface to be the specified TaskFragment.
@@ -800,6 +827,8 @@ class DividerPresenter implements View.OnTouchListener {
        private final int mDisplayId;
        private final boolean mIsReversedLayout;
        private final boolean mIsDraggableExpandType;
        private final Color mPrimaryVeilColor;
        private final Color mSecondaryVeilColor;

        @VisibleForTesting
        Properties(
@@ -810,7 +839,9 @@ class DividerPresenter implements View.OnTouchListener {
                boolean isVerticalSplit,
                boolean isReversedLayout,
                int displayId,
                boolean isDraggableExpandType) {
                boolean isDraggableExpandType,
                @NonNull Color primaryVeilColor,
                @NonNull Color secondaryVeilColor) {
            mConfiguration = configuration;
            mDividerAttributes = dividerAttributes;
            mDecorSurface = decorSurface;
@@ -819,6 +850,8 @@ class DividerPresenter implements View.OnTouchListener {
            mIsReversedLayout = isReversedLayout;
            mDisplayId = displayId;
            mIsDraggableExpandType = isDraggableExpandType;
            mPrimaryVeilColor = primaryVeilColor;
            mSecondaryVeilColor = secondaryVeilColor;
        }

        /**
@@ -840,7 +873,9 @@ class DividerPresenter implements View.OnTouchListener {
                    && a.mIsVerticalSplit == b.mIsVerticalSplit
                    && a.mDisplayId == b.mDisplayId
                    && a.mIsReversedLayout == b.mIsReversedLayout
                    && a.mIsDraggableExpandType == b.mIsDraggableExpandType;
                    && a.mIsDraggableExpandType == b.mIsDraggableExpandType
                    && a.mPrimaryVeilColor.equals(b.mPrimaryVeilColor)
                    && a.mSecondaryVeilColor.equals(b.mSecondaryVeilColor);
        }

        private static boolean areSameSurfaces(
@@ -1087,8 +1122,8 @@ class DividerPresenter implements View.OnTouchListener {
        }

        private void showVeils(@NonNull SurfaceControl.Transaction t) {
            t.setColor(mPrimaryVeil, colorToFloatArray(DEFAULT_PRIMARY_VEIL_COLOR))
                    .setColor(mSecondaryVeil, colorToFloatArray(DEFAULT_SECONDARY_VEIL_COLOR))
            t.setColor(mPrimaryVeil, colorToFloatArray(mProperties.mPrimaryVeilColor))
                    .setColor(mSecondaryVeil, colorToFloatArray(mProperties.mSecondaryVeilColor))
                    .setLayer(mDividerSurface, DIVIDER_LAYER)
                    .setLayer(mPrimaryVeil, VEIL_LAYER)
                    .setLayer(mSecondaryVeil, VEIL_LAYER)
+41 −1
Original line number Diff line number Diff line
@@ -35,8 +35,11 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.os.Binder;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
@@ -44,6 +47,8 @@ import android.platform.test.flag.junit.SetFlagsRule;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
import android.view.Window;
import android.window.TaskFragmentOperation;
import android.window.TaskFragmentParentInfo;
import android.window.WindowContainerTransaction;
@@ -152,7 +157,10 @@ public class DividerPresenterTest {
                true /* isVerticalSplit */,
                false /* isReversedLayout */,
                Display.DEFAULT_DISPLAY,
                false /* isDraggableExpandType */);
                false /* isDraggableExpandType */,
                Color.valueOf(Color.BLACK), /* primaryVeilColor */
                Color.valueOf(Color.GRAY) /* secondaryVeilColor */
        );

        mDividerPresenter = new DividerPresenter(
                MOCK_TASK_ID, mDragEventCallback, mock(Executor.class));
@@ -604,6 +612,38 @@ public class DividerPresenterTest {
                0.0001 /* delta */);
    }

    @Test
    public void testGetContainerBackgroundColor() {
        final Color defaultColor = Color.valueOf(Color.RED);
        final Color activityBackgroundColor = Color.valueOf(Color.BLUE);
        final TaskFragmentContainer container = mock(TaskFragmentContainer.class);
        final Activity activity = mock(Activity.class);
        final Window window = mock(Window.class);
        final View decorView = mock(View.class);
        final ColorDrawable backgroundDrawable =
                new ColorDrawable(activityBackgroundColor.toArgb());
        when(activity.getWindow()).thenReturn(window);
        when(window.getDecorView()).thenReturn(decorView);
        when(decorView.getBackground()).thenReturn(backgroundDrawable);

        // When the top non-finishing activity returns null, the default color should be returned.
        when(container.getTopNonFinishingActivity()).thenReturn(null);
        assertEquals(defaultColor,
                DividerPresenter.getContainerBackgroundColor(container, defaultColor));

        // When the top non-finishing activity is not resumed, the default color should be returned.
        when(container.getTopNonFinishingActivity()).thenReturn(activity);
        when(activity.isResumed()).thenReturn(false);
        assertEquals(defaultColor,
                DividerPresenter.getContainerBackgroundColor(container, defaultColor));

        // When the top non-finishing activity is resumed, its background color should be returned.
        when(container.getTopNonFinishingActivity()).thenReturn(activity);
        when(activity.isResumed()).thenReturn(true);
        assertEquals(activityBackgroundColor,
                DividerPresenter.getContainerBackgroundColor(container, defaultColor));
    }

    private TaskFragmentContainer createMockTaskFragmentContainer(
            @NonNull IBinder token, @NonNull Rect bounds) {
        final TaskFragmentContainer container = mock(TaskFragmentContainer.class);