From 2874d8877051e56e169708a9634829bf45a35e9b Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Thu, 6 Jul 2023 16:15:31 -0700 Subject: Add a failsafe to update surface position after activity-level transit ActivityRecord isn't expected to change independently, however, there is now compat behavior that will enable client-code to trigger changes to an AR's surface outside of any WM-side lifecycles. This already causes glitchy offsets w/ legacy during animation, but w/ shell, the activity could get stuck with the offset if the compat properties were changed during the animation. Until we come-up with a proper solution for this, just "sync up" the surface state when idle so at-least it won't be stuck. It will still have an offset during the animation, but that is the behavior we already had. Bug: 282129721 Test: Use a forced-landscape device (eg. unfolded landscape) and launch an activity which has portrait rotation in manifest but then requests landscape rotation in onResume before animation finishes. Change-Id: I92ee7884687433b12bc2649ade7416abb9953943 --- .../core/java/com/android/server/wm/ActivityRecord.java | 3 +++ .../com/android/server/wm/TransitionController.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 788bfbcd65c9..64b37d496dbc 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -7981,6 +7981,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mLastReportedConfiguration.getMergedConfiguration())) { ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */, false /* ignoreVisibility */, true /* isRequestedOrientationChanged */); + if (mTransitionController.inPlayingTransition(this)) { + mTransitionController.mValidateActivityCompat.add(this); + } } mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged( diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index a539a4893d4f..b05c6b4839e5 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -30,6 +30,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.IApplicationThread; import android.app.WindowConfiguration; +import android.graphics.Point; import android.graphics.Rect; import android.os.Handler; import android.os.IBinder; @@ -140,6 +141,14 @@ class TransitionController { */ final ArrayList mValidateCommitVis = new ArrayList<>(); + /** + * List of activity-level participants. ActivityRecord is not expected to change independently, + * however, recent compatibility logic can now cause this at arbitrary times determined by + * client code. If it happens during an animation, the surface can be left at the wrong spot. + * TODO(b/290237710) remove when compat logic is moved. + */ + final ArrayList mValidateActivityCompat = new ArrayList<>(); + /** * Currently playing transitions (in the order they were started). When finished, records are * removed from this list. @@ -905,6 +914,14 @@ class TransitionController { } } mValidateCommitVis.clear(); + for (int i = 0; i < mValidateActivityCompat.size(); ++i) { + ActivityRecord ar = mValidateActivityCompat.get(i); + if (ar.getSurfaceControl() == null) continue; + final Point tmpPos = new Point(); + ar.getRelativePosition(tmpPos); + ar.getSyncTransaction().setPosition(ar.getSurfaceControl(), tmpPos.x, tmpPos.y); + } + mValidateActivityCompat.clear(); } /** -- cgit v1.2.3-59-g8ed1b