diff options
2 files changed, 81 insertions, 6 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java index a0d6fce4c39b..6793fa549ef0 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java @@ -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) )); } } @@ -242,6 +248,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) diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java index 8aca92e89e6b..ad913c98482c 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java @@ -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); |