From 8995590e444d02746bb580ff4aef7ddf0b3ee3da Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 23 Jun 2020 16:52:04 +0800 Subject: [PATCH] Use isolated display context to get display info While display is in landscape, and the launcher is transformed to portrait, the display rotation from activity or application context will get the rotation in portrait. In order to transform the input event when the orientations are different, the actual device rotation is still needed. By creating the display context from application context, the resources of the new context won't be affected by the activity/application level display info adjustments. That provides the actual device states. Additionally, DefaultDisplay#INSTANCE should only be used for the operations related to physical orientation/size because it won't contain the override information from activity. Bug: 157456493 Test: Use a device which may switch refresh rate. Open Maps and put device in landscape. Use gesture navigation to swipe up. The direction of movement should be consistent with UI. Change-Id: I03108b1ab057e28727b6a6db3629d2c1c069e828 --- .../launcher3/util/DefaultDisplay.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java index 150fb5b043..35788a54c8 100644 --- a/src/com/android/launcher3/util/DefaultDisplay.java +++ b/src/com/android/launcher3/util/DefaultDisplay.java @@ -49,20 +49,25 @@ public class DefaultDisplay implements DisplayListener { public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION | CHANGE_FRAME_DELAY; - private final Context mContext; + private final Context mDisplayContext; private final int mId; private final ArrayList mListeners = new ArrayList<>(); private final Handler mChangeHandler; private Info mInfo; private DefaultDisplay(Context context) { - mContext = context; - mInfo = new Info(context); + DisplayManager dm = context.getSystemService(DisplayManager.class); + // Use application context to create display context so that it can have its own Resources. + mDisplayContext = context.getApplicationContext().createDisplayContext( + dm.getDisplay(DEFAULT_DISPLAY)); + // Note that the Display object must be obtained from DisplayManager which is associated to + // the display context, so the Display is isolated from Activity and Application to provide + // the actual state of device that excludes the additional adjustment and override. + mInfo = new Info(mDisplayContext); mId = mInfo.id; mChangeHandler = new Handler(this::onChange); - context.getSystemService(DisplayManager.class) - .registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler()); + dm.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler()); } @Override @@ -78,7 +83,7 @@ public class DefaultDisplay implements DisplayListener { } Info oldInfo = mInfo; - Info info = new Info(mContext); + Info info = new Info(mDisplayContext); int change = 0; if (info.hasDifferentSize(oldInfo)) { @@ -162,8 +167,7 @@ public class DefaultDisplay implements DisplayListener { display.getRealSize(realSize); display.getCurrentSizeRange(smallestSize, largestSize); - Context defaultDisplayContext = context.createDisplayContext(display); - metrics = defaultDisplayContext.getResources().getDisplayMetrics(); + metrics = context.getResources().getDisplayMetrics(); } private boolean hasDifferentSize(Info info) {