Merge "Show bg color during ActivityEmbedding change anim with Shell transition" into tm-qpr-dev
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 490975c..921861a 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 @@
// 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 @@
}
}
+ // 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 @@
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 @@
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 58b2366..2bb7369 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 @@
// 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 46253c1..32f6197 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 @@
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 @@
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 @@
} 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 9fd0850..66e46a2 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.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 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 @@
}
@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);