blob: 7e95814c06c2c9d65dee55c3558987b45490aad7 [file] [log] [blame]
/*
* 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.graphics.Point;
import android.util.RotationUtils;
import android.view.SurfaceControl;
/**
* Utility class that takes care of rotating unchanging child-surfaces to match the parent rotation
* during a transition animation. This gives the illusion that the child surfaces haven't rotated
* relative to the screen.
*/
public class CounterRotator {
private SurfaceControl mSurface = 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 parentW (and H) Is the size of the rotating parent after the rotation.
*/
public void setup(SurfaceControl.Transaction t, SurfaceControl parent, int rotateDelta,
float parentW, float parentH) {
if (rotateDelta == 0) return;
mSurface = new SurfaceControl.Builder()
.setName("Transition Unrotate")
.setContainerLayer()
.setParent(parent)
.build();
// Rotate forward to match the new rotation (rotateDelta is the forward rotation the parent
// already took). Child surfaces will be in the old rotation relative to the new parent
// rotation, so we need to forward-rotate the child surfaces to match.
RotationUtils.rotateSurface(t, mSurface, rotateDelta);
final Point tmpPt = new Point(0, 0);
// parentW/H are the size in the END rotation, the rotation utilities expect the starting
// size. So swap them if necessary
if ((rotateDelta % 2) != 0) {
final float w = parentW;
parentW = parentH;
parentH = w;
}
RotationUtils.rotatePoint(tmpPt, rotateDelta, (int) parentW, (int) parentH);
t.setPosition(mSurface, tmpPt.x, tmpPt.y);
t.show(mSurface);
}
/**
* Adds a surface that needs to be counter-rotate.
*/
public void addChild(SurfaceControl.Transaction t, SurfaceControl child) {
if (mSurface == null) return;
t.reparent(child, mSurface);
}
/**
* Clean-up. Since finishTransaction should reset all change leashes, we only need to remove the
* counter rotation surface.
*/
public void cleanUp(SurfaceControl.Transaction finishTransaction) {
if (mSurface == null) return;
finishTransaction.remove(mSurface);
}
}