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

Commit 7a23b151 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

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

parents 7ecf186f 14ea8c60
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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: [
+48 −10
Original line number Diff line number Diff line
@@ -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,8 +295,11 @@ 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) {
            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)) {
@@ -296,6 +309,31 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
                                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());
                    }
                }
            }

            if (change.getMode() == TRANSIT_CHANGE) {
+87 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -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",
}
+7 −53
Original line number Diff line number Diff line
@@ -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()));
                        }
                    }