From 61e037a7b732f3f83378036ede164a4423407085 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 26 Apr 2023 22:20:42 +0800 Subject: [PATCH] Set fixed transform hint on app level rotated surface This is similar to [1], but the transform is applied when switching activities with different requested orientations. Then the transform will be applied on ActivityRecord before display rotation happens. [1]: Id4ad45adb9719b078f46040a09f786092c325a8a Bug: 270282500 Test: atest SurfaceControlTests#testSurfaceChangedOnRotation Change-Id: I6650eef0b12d84f7014e5afc280c1cb5e907d7b2 --- .../android/server/wm/WindowContainer.java | 3 +++ .../com/android/server/wm/WindowToken.java | 1 + .../server/wm/SurfaceControlTests.java | 22 ++++++++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 510e6756b8ef0..a5cdd0b43eb01 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -3594,8 +3594,11 @@ class WindowContainer extends ConfigurationContainer< && !mTransitionController.useShellTransitionsRotation()) { if (deltaRotation != Surface.ROTATION_0) { updateSurfaceRotation(t, deltaRotation, null /* positionLeash */); + t.setFixedTransformHint(mSurfaceControl, + getWindowConfiguration().getDisplayRotation()); } else if (deltaRotation != mLastDeltaRotation) { t.setMatrix(mSurfaceControl, 1, 0, 0, 1); + t.unsetFixedTransformHint(mSurfaceControl); } } mLastDeltaRotation = deltaRotation; diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index da54b15fd0a42..4c5efef795d86 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -596,6 +596,7 @@ class WindowToken extends WindowContainer { .build(); t.setPosition(leash, mLastSurfacePosition.x, mLastSurfacePosition.y); t.reparent(getSurfaceControl(), leash); + t.setFixedTransformHint(leash, getWindowConfiguration().getDisplayRotation()); mFixedRotationTransformLeash = leash; updateSurfaceRotation(t, rotation, mFixedRotationTransformLeash); return mFixedRotationTransformLeash; diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java index 342ab83de6f08..4f45d5c2bf98b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java @@ -125,9 +125,10 @@ public class SurfaceControlTests { public void testSurfaceChangedOnRotation() { final Instrumentation instrumentation = getInstrumentation(); final Context context = instrumentation.getContext(); - final Activity activity = instrumentation.startActivitySync(new Intent().setComponent( + final Intent intent = new Intent().setComponent( new ComponentName(context, ActivityOptionsTest.MainActivity.class)) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); + final Activity activity = instrumentation.startActivitySync(intent); final SurfaceView sv = new SurfaceView(activity); final AtomicInteger surfaceChangedCount = new AtomicInteger(); instrumentation.runOnMainSync(() -> activity.setContentView(sv)); @@ -157,12 +158,27 @@ public class SurfaceControlTests { instrumentation.waitForIdleSync(); final int newRotation = activity.getResources().getConfiguration() .windowConfiguration.getRotation(); + if (rotation == newRotation) { + // The device might not support requested orientation. + activity.finishAndRemoveTask(); + return; + } final int count = surfaceChangedCount.get(); + activity.moveTaskToBack(true /* nonRoot */); + instrumentation.getUiAutomation().syncInputTransactions(); + context.startActivity(intent); + instrumentation.getUiAutomation().syncInputTransactions(); + final int countAfterToFront = count - surfaceChangedCount.get(); activity.finishAndRemoveTask(); + // The first count is triggered from creation, so the target number is 2. - if (rotation != newRotation && count > 2) { + if (count > 2) { fail("More than once surfaceChanged for rotation change: " + count); } + if (countAfterToFront > 1) { + fail("More than once surfaceChanged for app transition with rotation change: " + + countAfterToFront); + } } private SurfaceControl buildTestSurface() {