Loading services/core/java/com/android/server/wm/DisplayContent.java +8 −0 Original line number Diff line number Diff line Loading @@ -2190,6 +2190,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } mWmService.mDisplayManagerInternal.performTraversal(transaction); if (shellTransitions) { // Before setDisplayProjection is applied by the start transaction of transition, // set the transform hint to avoid using surface in old rotation. getPendingTransaction().setFixedTransformHint(mSurfaceControl, rotation); // The sync transaction should already contains setDisplayProjection, so unset the // hint to restore the natural state when the transaction is applied. transaction.unsetFixedTransformHint(mSurfaceControl); } scheduleAnimation(); mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation); Loading services/core/java/com/android/server/wm/Transition.java +7 −0 Original line number Diff line number Diff line Loading @@ -865,6 +865,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { if (c.getSnapshot() != null) { t.reparent(c.getSnapshot(), null); } // The fixed transform hint was set in DisplayContent#applyRotation(). Make sure to // clear the hint in case the start transaction is not applied. if (c.hasFlags(FLAG_IS_DISPLAY) && c.getStartRotation() != c.getEndRotation() && c.getContainer() != null) { t.unsetFixedTransformHint(WindowContainer.fromBinder(c.getContainer().asBinder()) .asDisplayContent().mSurfaceControl); } } for (int i = info.getRootCount() - 1; i >= 0; --i) { final SurfaceControl leash = info.getRoot(i).getLeash(); Loading services/core/java/com/android/server/wm/TransitionController.java +1 −0 Original line number Diff line number Diff line Loading @@ -823,6 +823,7 @@ class TransitionController { // Can reset track-count now that everything is idle. mTrackCount = 0; validateStates(); mAtm.mWindowManager.onAnimationFinished(); } } Loading services/tests/wmtests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ android:turnScreenOn="true" android:showWhenLocked="true" /> <activity android:name="com.android.server.wm.ActivityOptionsTest$MainActivity" android:configChanges="screenLayout|screenSize|smallestScreenSize|orientation" android:turnScreenOn="true" android:showWhenLocked="true" /> <activity android:name="com.android.server.wm.ScreenshotTests$ScreenshotActivity" Loading services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java +59 −0 Original line number Diff line number Diff line Loading @@ -16,19 +16,34 @@ package com.android.server.wm; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import android.app.Activity; import android.app.Instrumentation; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.os.Parcel; import android.platform.test.annotations.Presubmit; import android.util.Log; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import java.util.concurrent.atomic.AtomicInteger; /** * Class for testing {@link SurfaceControl}. * Loading Loading @@ -106,6 +121,50 @@ public class SurfaceControlTests { } } @Test public void testSurfaceChangedOnRotation() { final Instrumentation instrumentation = getInstrumentation(); final Context context = instrumentation.getContext(); final Activity activity = instrumentation.startActivitySync(new Intent().setComponent( new ComponentName(context, ActivityOptionsTest.MainActivity.class)) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); final SurfaceView sv = new SurfaceView(activity); final AtomicInteger surfaceChangedCount = new AtomicInteger(); instrumentation.runOnMainSync(() -> activity.setContentView(sv)); sv.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { } @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { surfaceChangedCount.getAndIncrement(); Log.i("surfaceChanged", "width=" + width + " height=" + height + " getTransformHint=" + sv.getViewRootImpl().getSurfaceControl().getTransformHint()); } @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { } }); final int rotation = activity.getResources().getConfiguration() .windowConfiguration.getRotation(); activity.setRequestedOrientation(activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); instrumentation.getUiAutomation().syncInputTransactions(); instrumentation.waitForIdleSync(); final int newRotation = activity.getResources().getConfiguration() .windowConfiguration.getRotation(); final int count = surfaceChangedCount.get(); activity.finishAndRemoveTask(); // The first count is triggered from creation, so the target number is 2. if (rotation != newRotation && count > 2) { fail("More than once surfaceChanged for rotation change: " + count); } } private SurfaceControl buildTestSurface() { return new SurfaceControl.Builder() .setContainerLayer() Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +8 −0 Original line number Diff line number Diff line Loading @@ -2190,6 +2190,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } mWmService.mDisplayManagerInternal.performTraversal(transaction); if (shellTransitions) { // Before setDisplayProjection is applied by the start transaction of transition, // set the transform hint to avoid using surface in old rotation. getPendingTransaction().setFixedTransformHint(mSurfaceControl, rotation); // The sync transaction should already contains setDisplayProjection, so unset the // hint to restore the natural state when the transaction is applied. transaction.unsetFixedTransformHint(mSurfaceControl); } scheduleAnimation(); mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation); Loading
services/core/java/com/android/server/wm/Transition.java +7 −0 Original line number Diff line number Diff line Loading @@ -865,6 +865,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener { if (c.getSnapshot() != null) { t.reparent(c.getSnapshot(), null); } // The fixed transform hint was set in DisplayContent#applyRotation(). Make sure to // clear the hint in case the start transaction is not applied. if (c.hasFlags(FLAG_IS_DISPLAY) && c.getStartRotation() != c.getEndRotation() && c.getContainer() != null) { t.unsetFixedTransformHint(WindowContainer.fromBinder(c.getContainer().asBinder()) .asDisplayContent().mSurfaceControl); } } for (int i = info.getRootCount() - 1; i >= 0; --i) { final SurfaceControl leash = info.getRoot(i).getLeash(); Loading
services/core/java/com/android/server/wm/TransitionController.java +1 −0 Original line number Diff line number Diff line Loading @@ -823,6 +823,7 @@ class TransitionController { // Can reset track-count now that everything is idle. mTrackCount = 0; validateStates(); mAtm.mWindowManager.onAnimationFinished(); } } Loading
services/tests/wmtests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ android:turnScreenOn="true" android:showWhenLocked="true" /> <activity android:name="com.android.server.wm.ActivityOptionsTest$MainActivity" android:configChanges="screenLayout|screenSize|smallestScreenSize|orientation" android:turnScreenOn="true" android:showWhenLocked="true" /> <activity android:name="com.android.server.wm.ScreenshotTests$ScreenshotActivity" Loading
services/tests/wmtests/src/com/android/server/wm/SurfaceControlTests.java +59 −0 Original line number Diff line number Diff line Loading @@ -16,19 +16,34 @@ package com.android.server.wm; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import android.app.Activity; import android.app.Instrumentation; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.os.Parcel; import android.platform.test.annotations.Presubmit; import android.util.Log; import android.view.SurfaceControl; import android.view.SurfaceHolder; import android.view.SurfaceView; import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import java.util.concurrent.atomic.AtomicInteger; /** * Class for testing {@link SurfaceControl}. * Loading Loading @@ -106,6 +121,50 @@ public class SurfaceControlTests { } } @Test public void testSurfaceChangedOnRotation() { final Instrumentation instrumentation = getInstrumentation(); final Context context = instrumentation.getContext(); final Activity activity = instrumentation.startActivitySync(new Intent().setComponent( new ComponentName(context, ActivityOptionsTest.MainActivity.class)) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); final SurfaceView sv = new SurfaceView(activity); final AtomicInteger surfaceChangedCount = new AtomicInteger(); instrumentation.runOnMainSync(() -> activity.setContentView(sv)); sv.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { } @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { surfaceChangedCount.getAndIncrement(); Log.i("surfaceChanged", "width=" + width + " height=" + height + " getTransformHint=" + sv.getViewRootImpl().getSurfaceControl().getTransformHint()); } @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { } }); final int rotation = activity.getResources().getConfiguration() .windowConfiguration.getRotation(); activity.setRequestedOrientation(activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); instrumentation.getUiAutomation().syncInputTransactions(); instrumentation.waitForIdleSync(); final int newRotation = activity.getResources().getConfiguration() .windowConfiguration.getRotation(); final int count = surfaceChangedCount.get(); activity.finishAndRemoveTask(); // The first count is triggered from creation, so the target number is 2. if (rotation != newRotation && count > 2) { fail("More than once surfaceChanged for rotation change: " + count); } } private SurfaceControl buildTestSurface() { return new SurfaceControl.Builder() .setContainerLayer() Loading