1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wm.shell.util; 18 19 import android.view.SurfaceControl; 20 21 import java.util.ArrayList; 22 23 /** 24 * Utility class that takes care of counter-rotating surfaces during a transition animation. 25 */ 26 public class CounterRotator { 27 SurfaceControl mSurface = null; 28 ArrayList<SurfaceControl> mRotateChildren = null; 29 30 /** Gets the surface with the counter-rotation. */ getSurface()31 public SurfaceControl getSurface() { 32 return mSurface; 33 } 34 35 /** 36 * Sets up this rotator. 37 * 38 * @param rotateDelta is the forward rotation change (the rotation the display is making). 39 * @param displayW (and H) Is the size of the rotating display. 40 */ setup(SurfaceControl.Transaction t, SurfaceControl parent, int rotateDelta, float displayW, float displayH)41 public void setup(SurfaceControl.Transaction t, SurfaceControl parent, int rotateDelta, 42 float displayW, float displayH) { 43 if (rotateDelta == 0) return; 44 mRotateChildren = new ArrayList<>(); 45 // We want to counter-rotate, so subtract from 4 46 rotateDelta = 4 - (rotateDelta + 4) % 4; 47 mSurface = new SurfaceControl.Builder() 48 .setName("Transition Unrotate") 49 .setContainerLayer() 50 .setParent(parent) 51 .build(); 52 // column-major 53 if (rotateDelta == 1) { 54 t.setMatrix(mSurface, 0, 1, -1, 0); 55 t.setPosition(mSurface, displayW, 0); 56 } else if (rotateDelta == 2) { 57 t.setMatrix(mSurface, -1, 0, 0, -1); 58 t.setPosition(mSurface, displayW, displayH); 59 } else if (rotateDelta == 3) { 60 t.setMatrix(mSurface, 0, -1, 1, 0); 61 t.setPosition(mSurface, 0, displayH); 62 } 63 t.show(mSurface); 64 } 65 66 /** 67 * Add a surface that needs to be counter-rotate. 68 */ addChild(SurfaceControl.Transaction t, SurfaceControl child)69 public void addChild(SurfaceControl.Transaction t, SurfaceControl child) { 70 if (mSurface == null) return; 71 t.reparent(child, mSurface); 72 mRotateChildren.add(child); 73 } 74 75 /** 76 * Clean-up. This undoes any reparenting and effectively stops the counter-rotation. 77 */ cleanUp(SurfaceControl rootLeash)78 public void cleanUp(SurfaceControl rootLeash) { 79 if (mSurface == null) return; 80 SurfaceControl.Transaction t = new SurfaceControl.Transaction(); 81 for (int i = mRotateChildren.size() - 1; i >= 0; --i) { 82 t.reparent(mRotateChildren.get(i), rootLeash); 83 } 84 t.remove(mSurface); 85 t.apply(); 86 } 87 } 88