diff options
| author | 2022-10-20 16:55:45 +0800 | |
|---|---|---|
| committer | 2022-10-25 09:55:54 +0000 | |
| commit | 4659d8a49c5dbe38db13cae26a9f4bd47f30c33b (patch) | |
| tree | f06d5c9132469ad87350b1ad1fbdd5af6dfa806f | |
| parent | fe8b17d49d118e3a466b01c8d20919c7a8a58b5b (diff) | |
Show bg color during ActivityEmbedding change anim with Shell transition
When switching between horizontal split and vertical split, it will
leave part of the screen empty. Show background color to cover that.
Also fix the leash start position.
Bug: 241043533
Bug: 254090083
Test: atest WmTests:TransitionTests#testChangeSetBackgroundColor
Test: verify with horizontal demo app
Change-Id: I125db07a631b19bd33bcff9935fe39f263cbb263
4 files changed, 84 insertions, 6 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java index 490975cce956..921861ae0913 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java @@ -303,6 +303,7 @@ class ActivityEmbeddingAnimationRunner { // 3. Animate the TaskFragment using Activity Change info (start/end bounds). // This is because the TaskFragment surface/change won't contain the Activity's before its // reparent. + Animation changeAnimation = null; for (TransitionInfo.Change change : info.getChanges()) { if (change.getMode() != TRANSIT_CHANGE || change.getStartAbsBounds().equals(change.getEndAbsBounds())) { @@ -325,8 +326,14 @@ class ActivityEmbeddingAnimationRunner { } } + // There are two animations in the array. The first one is for the start leash + // (snapshot), and the second one is for the end leash (TaskFragment). final Animation[] animations = mAnimationSpec.createChangeBoundsChangeAnimations(change, boundsAnimationChange.getEndAbsBounds()); + // Keep track as we might need to add background color for the animation. + // Although there may be multiple change animation, record one of them is sufficient + // because the background color will be added to the root leash for the whole animation. + changeAnimation = animations[1]; // Create a screenshot based on change, but attach it to the top of the // boundsAnimationChange. @@ -345,6 +352,9 @@ class ActivityEmbeddingAnimationRunner { animations[1], boundsAnimationChange)); } + // If there is no corresponding open/close window with the change, we should show background + // color to cover the empty part of the screen. + boolean shouldShouldBackgroundColor = true; // Handle the other windows that don't have bounds change in the same transition. for (TransitionInfo.Change change : info.getChanges()) { if (handledChanges.contains(change)) { @@ -359,11 +369,20 @@ class ActivityEmbeddingAnimationRunner { animation = ActivityEmbeddingAnimationSpec.createNoopAnimation(change); } else if (Transitions.isClosingType(change.getMode())) { animation = mAnimationSpec.createChangeBoundsCloseAnimation(change); + shouldShouldBackgroundColor = false; } else { animation = mAnimationSpec.createChangeBoundsOpenAnimation(change); + shouldShouldBackgroundColor = false; } adapters.add(new ActivityEmbeddingAnimationAdapter(animation, change)); } + + if (shouldShouldBackgroundColor && changeAnimation != null) { + // Change animation may leave part of the screen empty. Show background color to cover + // that. + changeAnimation.setShowBackdrop(true); + } + return adapters; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java index 58b23667dc18..2bb73692b457 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java @@ -158,7 +158,7 @@ class ActivityEmbeddingAnimationSpec { // The position should be 0-based as we will post translate in // ActivityEmbeddingAnimationAdapter#onAnimationUpdate final Animation endTranslate = new TranslateAnimation(startBounds.left - endBounds.left, 0, - 0, 0); + startBounds.top - endBounds.top, 0); endTranslate.setDuration(CHANGE_ANIMATION_DURATION); endSet.addAnimation(endTranslate); // The end leash is resizing, we should update the window crop based on the clip rect. diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 46253c1933b6..32f61978d730 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -1602,7 +1602,11 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe change.setMode(info.getTransitMode(target)); change.setStartAbsBounds(info.mAbsoluteBounds); change.setFlags(info.getChangeFlags(target)); + final Task task = target.asTask(); + final TaskFragment taskFragment = target.asTaskFragment(); + final ActivityRecord activityRecord = target.asActivityRecord(); + if (task != null) { final ActivityManager.RunningTaskInfo tinfo = new ActivityManager.RunningTaskInfo(); task.fillTaskInfo(tinfo); @@ -1636,12 +1640,7 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe change.setEndRelOffset(bounds.left - parentBounds.left, bounds.top - parentBounds.top); int endRotation = target.getWindowConfiguration().getRotation(); - final ActivityRecord activityRecord = target.asActivityRecord(); if (activityRecord != null) { - final Task arTask = activityRecord.getTask(); - final int backgroundColor = ColorUtils.setAlphaComponent( - arTask.getTaskDescription().getBackgroundColor(), 255); - change.setBackgroundColor(backgroundColor); // TODO(b/227427984): Shell needs to aware letterbox. // Always use parent bounds of activity because letterbox area (e.g. fixed aspect // ratio or size compat mode) should be included in the animation. @@ -1654,6 +1653,18 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe } else { change.setEndAbsBounds(bounds); } + + if (activityRecord != null || (taskFragment != null && taskFragment.isEmbedded())) { + // Set background color to Task theme color for activity and embedded TaskFragment + // in case we want to show background during the animation. + final Task parentTask = activityRecord != null + ? activityRecord.getTask() + : taskFragment.getTask(); + final int backgroundColor = ColorUtils.setAlphaComponent( + parentTask.getTaskDescription().getBackgroundColor(), 255); + change.setBackgroundColor(backgroundColor); + } + change.setRotation(info.mRotation, endRotation); if (info.mSnapshot != null) { change.setSnapshot(info.mSnapshot, info.mSnapshotLuma); diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java index 9fd085021d66..66e46a2bb187 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java @@ -59,7 +59,9 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import android.app.ActivityManager; import android.content.res.Configuration; +import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; import android.os.IBinder; @@ -79,6 +81,8 @@ import android.window.TransitionInfo; import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; +import com.android.internal.graphics.ColorUtils; + import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -1384,6 +1388,50 @@ public class TransitionTests extends WindowTestsBase { } @Test + public void testChangeSetBackgroundColor() { + final Transition transition = createTestTransition(TRANSIT_CHANGE); + final ArrayMap<WindowContainer, Transition.ChangeInfo> changes = transition.mChanges; + final ArraySet<WindowContainer> participants = transition.mParticipants; + + // Test background color for Activity and embedded TaskFragment. + final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); + mAtm.mTaskFragmentOrganizerController.registerOrganizer( + ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder())); + final Task task = createTask(mDisplayContent); + final TaskFragment embeddedTf = createTaskFragmentWithEmbeddedActivity(task, organizer); + final ActivityRecord embeddedActivity = embeddedTf.getTopMostActivity(); + final ActivityRecord nonEmbeddedActivity = createActivityRecord(task); + final ActivityManager.TaskDescription taskDescription = + new ActivityManager.TaskDescription.Builder() + .setBackgroundColor(Color.YELLOW) + .build(); + task.setTaskDescription(taskDescription); + + // Start states: + embeddedActivity.mVisibleRequested = true; + nonEmbeddedActivity.mVisibleRequested = false; + changes.put(embeddedTf, new Transition.ChangeInfo(embeddedTf)); + changes.put(nonEmbeddedActivity, new Transition.ChangeInfo(nonEmbeddedActivity)); + // End states: + embeddedActivity.mVisibleRequested = false; + nonEmbeddedActivity.mVisibleRequested = true; + + participants.add(embeddedTf); + participants.add(nonEmbeddedActivity); + final ArrayList<WindowContainer> targets = Transition.calculateTargets( + participants, changes); + final TransitionInfo info = Transition.calculateTransitionInfo(transition.mType, + 0 /* flags */, targets, changes, mMockT); + + // Background color should be set on both Activity and embedded TaskFragment. + final int expectedBackgroundColor = ColorUtils.setAlphaComponent( + taskDescription.getBackgroundColor(), 255); + assertEquals(2, info.getChanges().size()); + assertEquals(expectedBackgroundColor, info.getChanges().get(0).getBackgroundColor()); + assertEquals(expectedBackgroundColor, info.getChanges().get(1).getBackgroundColor()); + } + + @Test public void testTransitionVisibleChange() { registerTestTransitionPlayer(); final ActivityRecord app = createActivityRecord(mDisplayContent); |