Merge "Unrotate going-away apps during a launch-into-orientation transition" into sc-v2-dev

This commit is contained in:
Evan Rosky
2021-10-07 17:08:20 +00:00
committed by Android (Google) Code Review
5 changed files with 152 additions and 64 deletions

View File

@@ -38,6 +38,14 @@ filegroup {
path: "src",
}
filegroup {
name: "wm_shell_util-sources",
srcs: [
"src/com/android/wm/shell/util/**/*.java",
],
path: "src",
}
filegroup {
name: "wm_shell-aidls",
srcs: [

View File

@@ -41,6 +41,7 @@ import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
import static android.window.TransitionInfo.isIndependent;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CLOSE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_CLOSE;
@@ -70,6 +71,7 @@ import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.window.TransitionInfo;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.internal.R;
@@ -82,6 +84,7 @@ import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.util.CounterRotator;
import java.util.ArrayList;
@@ -269,9 +272,16 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final ArrayList<Animator> animations = new ArrayList<>();
mAnimations.put(transition, animations);
final ArrayMap<WindowContainerToken, CounterRotator> counterRotators = new ArrayMap<>();
final Runnable onAnimFinish = () -> {
if (!animations.isEmpty()) return;
for (int i = 0; i < counterRotators.size(); ++i) {
counterRotators.valueAt(i).cleanUp(info.getRootLeash());
}
counterRotators.clear();
if (mRotationAnimation != null) {
mRotationAnimation.kill();
mRotationAnimation = null;
@@ -285,16 +295,44 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
if (info.getType() == TRANSIT_CHANGE && change.getMode() == TRANSIT_CHANGE
&& (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
boolean isSeamless = isRotationSeamless(info, mDisplayController);
final int anim = getRotationAnimation(info);
if (!(isSeamless || anim == ROTATION_ANIMATION_JUMPCUT)) {
mRotationAnimation = new ScreenRotationAnimation(mContext, mSurfaceSession,
mTransactionPool, startTransaction, change, info.getRootLeash());
mRotationAnimation.startAnimation(animations, onAnimFinish,
mTransitionAnimationScaleSetting, mMainExecutor, mAnimExecutor);
continue;
if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
int rotateDelta = change.getEndRotation() - change.getStartRotation();
int displayW = change.getEndAbsBounds().width();
int displayH = change.getEndAbsBounds().height();
if (info.getType() == TRANSIT_CHANGE) {
boolean isSeamless = isRotationSeamless(info, mDisplayController);
final int anim = getRotationAnimation(info);
if (!(isSeamless || anim == ROTATION_ANIMATION_JUMPCUT)) {
mRotationAnimation = new ScreenRotationAnimation(mContext, mSurfaceSession,
mTransactionPool, startTransaction, change, info.getRootLeash());
mRotationAnimation.startAnimation(animations, onAnimFinish,
mTransitionAnimationScaleSetting, mMainExecutor, mAnimExecutor);
continue;
}
} else {
// opening/closing an app into a new orientation. Counter-rotate all
// "going-away" things since they are still in the old orientation.
for (int j = info.getChanges().size() - 1; j >= 0; --j) {
final TransitionInfo.Change innerChange = info.getChanges().get(j);
if (!Transitions.isClosingType(innerChange.getMode())
|| !isIndependent(innerChange, info)
|| innerChange.getParent() == null) {
continue;
}
CounterRotator crot = counterRotators.get(innerChange.getParent());
if (crot == null) {
crot = new CounterRotator();
crot.setup(startTransaction,
info.getChange(innerChange.getParent()).getLeash(),
rotateDelta, displayW, displayH);
if (crot.getSurface() != null) {
int layer = info.getChanges().size() - j;
startTransaction.setLayer(crot.getSurface(), layer);
}
counterRotators.put(innerChange.getParent(), crot);
}
crot.addChild(startTransaction, innerChange.getLeash());
}
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell.util;
import android.view.SurfaceControl;
import java.util.ArrayList;
/**
* Utility class that takes care of counter-rotating surfaces during a transition animation.
*/
public class CounterRotator {
SurfaceControl mSurface = null;
ArrayList<SurfaceControl> mRotateChildren = null;
/** Gets the surface with the counter-rotation. */
public SurfaceControl getSurface() {
return mSurface;
}
/**
* Sets up this rotator.
*
* @param rotateDelta is the forward rotation change (the rotation the display is making).
* @param displayW (and H) Is the size of the rotating display.
*/
public void setup(SurfaceControl.Transaction t, SurfaceControl parent, int rotateDelta,
float displayW, float displayH) {
if (rotateDelta == 0) return;
mRotateChildren = new ArrayList<>();
// We want to counter-rotate, so subtract from 4
rotateDelta = 4 - (rotateDelta + 4) % 4;
mSurface = new SurfaceControl.Builder()
.setName("Transition Unrotate")
.setContainerLayer()
.setParent(parent)
.build();
// column-major
if (rotateDelta == 1) {
t.setMatrix(mSurface, 0, 1, -1, 0);
t.setPosition(mSurface, displayW, 0);
} else if (rotateDelta == 2) {
t.setMatrix(mSurface, -1, 0, 0, -1);
t.setPosition(mSurface, displayW, displayH);
} else if (rotateDelta == 3) {
t.setMatrix(mSurface, 0, -1, 1, 0);
t.setPosition(mSurface, 0, displayH);
}
t.show(mSurface);
}
/**
* Add a surface that needs to be counter-rotate.
*/
public void addChild(SurfaceControl.Transaction t, SurfaceControl child) {
if (mSurface == null) return;
t.reparent(child, mSurface);
mRotateChildren.add(child);
}
/**
* Clean-up. This undoes any reparenting and effectively stops the counter-rotation.
*/
public void cleanUp(SurfaceControl rootLeash) {
if (mSurface == null) return;
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
for (int i = mRotateChildren.size() - 1; i >= 0; --i) {
t.reparent(mRotateChildren.get(i), rootLeash);
}
t.remove(mSurface);
t.apply();
}
}

View File

@@ -43,6 +43,7 @@ android_library {
"src/**/*.kt",
"src/**/*.aidl",
":wm_shell-aidls",
":wm_shell_util-sources",
],
static_libs: [
@@ -50,5 +51,5 @@ android_library {
"androidx.dynamicanimation_dynamicanimation",
],
java_version: "1.8",
min_sdk_version: "26",
min_sdk_version: "current",
}

View File

@@ -40,7 +40,7 @@ import android.window.IRemoteTransitionFinishedCallback;
import android.window.RemoteTransition;
import android.window.TransitionInfo;
import java.util.ArrayList;
import com.android.wm.shell.util.CounterRotator;
/**
* @see RemoteAnimationAdapter
@@ -109,52 +109,6 @@ public class RemoteAnimationAdapterCompat {
};
}
private static class CounterRotator {
SurfaceControl mSurface = null;
ArrayList<SurfaceControl> mRotateChildren = null;
void setup(SurfaceControl.Transaction t, SurfaceControl parent, int rotateDelta,
float displayW, float displayH) {
if (rotateDelta == 0) return;
mRotateChildren = new ArrayList<>();
// We want to counter-rotate, so subtract from 4
rotateDelta = 4 - (rotateDelta + 4) % 4;
mSurface = new SurfaceControl.Builder()
.setName("Transition Unrotate")
.setContainerLayer()
.setParent(parent)
.build();
// column-major
if (rotateDelta == 1) {
t.setMatrix(mSurface, 0, 1, -1, 0);
t.setPosition(mSurface, displayW, 0);
} else if (rotateDelta == 2) {
t.setMatrix(mSurface, -1, 0, 0, -1);
t.setPosition(mSurface, displayW, displayH);
} else if (rotateDelta == 3) {
t.setMatrix(mSurface, 0, -1, 1, 0);
t.setPosition(mSurface, 0, displayH);
}
t.show(mSurface);
}
void addChild(SurfaceControl.Transaction t, SurfaceControl child) {
if (mSurface == null) return;
t.reparent(child, mSurface);
mRotateChildren.add(child);
}
void cleanUp(SurfaceControl rootLeash) {
if (mSurface == null) return;
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
for (int i = mRotateChildren.size() - 1; i >= 0; --i) {
t.reparent(mRotateChildren.get(i), rootLeash);
}
t.remove(mSurface);
t.apply();
}
}
private static IRemoteTransition.Stub wrapRemoteTransition(
final RemoteAnimationRunnerCompat remoteAnimationAdapter) {
return new IRemoteTransition.Stub() {
@@ -204,14 +158,14 @@ public class RemoteAnimationAdapterCompat {
if (launcherTask != null && rotateDelta != 0 && launcherTask.getParent() != null) {
counterLauncher.setup(t, info.getChange(launcherTask.getParent()).getLeash(),
rotateDelta, displayW, displayH);
if (counterLauncher.mSurface != null) {
t.setLayer(counterLauncher.mSurface, launcherLayer);
if (counterLauncher.getSurface() != null) {
t.setLayer(counterLauncher.getSurface(), launcherLayer);
}
}
if (isReturnToHome) {
if (counterLauncher.mSurface != null) {
t.setLayer(counterLauncher.mSurface, info.getChanges().size() * 3);
if (counterLauncher.getSurface() != null) {
t.setLayer(counterLauncher.getSurface(), info.getChanges().size() * 3);
}
// Need to "boost" the closing things since that's what launcher expects.
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
@@ -237,8 +191,8 @@ public class RemoteAnimationAdapterCompat {
if (wallpaper != null && rotateDelta != 0 && wallpaper.getParent() != null) {
counterWallpaper.setup(t, info.getChange(wallpaper.getParent()).getLeash(),
rotateDelta, displayW, displayH);
if (counterWallpaper.mSurface != null) {
t.setLayer(counterWallpaper.mSurface, -1);
if (counterWallpaper.getSurface() != null) {
t.setLayer(counterWallpaper.getSurface(), -1);
counterWallpaper.addChild(t, leashMap.get(wallpaper.getLeash()));
}
}