Wrapping display properties in a wrapper class
This would allow us to support gestures on multiple-displays
Change-Id: I8f426bbdf04520f4189cadce2bde6aab4933c8d9
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 5c9fd47..3867c35 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -38,7 +38,7 @@
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
import static com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory.INDEX_PAUSE_TO_OVERVIEW_ANIM;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.CANCEL;
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AbsSwipeUpHandler.java
index d2fee30..282f6fa 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -29,7 +29,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index e2e25f3..a5af181 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -41,7 +41,7 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statehandlers.DepthController;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
@@ -146,7 +146,7 @@
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
// RecentsView never updates the display rotation until swipe-up so the value may be stale.
// Use the display value instead.
- int displayRotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation;
+ int displayRotation = DisplayController.getDefaultDisplay(context).getInfo().rotation;
TaskViewSimulator topMostSimulator = null;
if (targets.apps.length > 0) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
index be3fdde..a4a7bd3 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
@@ -21,7 +21,7 @@
import androidx.annotation.Nullable;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.SysUINavigationMode;
@@ -43,7 +43,7 @@
SysUINavigationMode.Mode sysUINavigationMode = SysUINavigationMode.getMode(mActivity);
if (sysUINavigationMode == SysUINavigationMode.Mode.NO_BUTTON) {
NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode,
- DefaultDisplay.INSTANCE.get(mActivity).getInfo());
+ DisplayController.getDefaultDisplay(mActivity).getInfo());
mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity,
true /* disableHorizontalSwipe */, navBarPosition,
null /* onInterceptTouch */, this);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 7032fae..584ff28 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -41,7 +41,7 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
@@ -115,7 +115,7 @@
R.dimen.device_locked_y_offset);
// Do not use DeviceProfile as the user data might be locked
- mDisplaySize = DefaultDisplay.INSTANCE.get(context).getInfo().realSize;
+ mDisplaySize = DisplayController.getDefaultDisplay(context).getInfo().realSize;
// Init states
mStateCallback = new MultiStateCallback(STATE_NAMES);
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index 22d205a..5cb55ec 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -32,7 +32,7 @@
import android.view.Surface;
import com.android.launcher3.ResourceUtils;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
import org.junit.Before;
import org.junit.Ignore;
@@ -50,7 +50,7 @@
private OrientationTouchTransformer mTouchTransformer;
Resources mResources;
- private DefaultDisplay.Info mInfo;
+ private DisplayController.Info mInfo;
@Before
@@ -231,12 +231,12 @@
assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion2.getX(), inRegion2.getY()));
}
- private DefaultDisplay.Info createDisplayInfo(int rotation) {
+ private DisplayController.Info createDisplayInfo(int rotation) {
Point p = new Point(SIZE_WIDTH, SIZE_HEIGHT);
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
p = new Point(SIZE_HEIGHT, SIZE_WIDTH);
}
- return new DefaultDisplay.Info(0, rotation, 0, p, p, p, null);
+ return new DisplayController.Info(0, rotation, 0, p, p, p, null);
}
private float generateTouchRegionHeight(int rotation) {
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index a31ba21..5491daa 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -27,7 +27,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.shadows.LShadowDisplay;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
import com.android.quickstep.LauncherActivityInterface;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
@@ -144,7 +144,7 @@
LauncherActivityInterface.INSTANCE);
tvs.setDp(mDeviceProfile);
- int launcherRotation = DefaultDisplay.INSTANCE.get(mContext).getInfo().rotation;
+ int launcherRotation = DisplayController.INSTANCE.get(mContext).getInfo().rotation;
if (mAppRotation < 0) {
mAppRotation = launcherRotation;
}
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 5ad0bca..199cf63 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -16,7 +16,7 @@
package com.android.launcher3;
import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
import android.animation.Animator;
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index b2bce0c..eb33f98 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -37,7 +37,7 @@
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController.Info;
import java.io.PrintWriter;
@@ -85,7 +85,7 @@
* QUICKSTEP_ROTATION_UNINITIALIZED, then user has not tapped on an active nav region.
* Otherwise it will be the rotation of the display when the user first interacted with the
* active nav bar region.
- * The "session" ends when {@link #enableMultipleRegions(boolean, DefaultDisplay.Info)} is
+ * The "session" ends when {@link #enableMultipleRegions(boolean, Info)} is
* called - usually from a timeout or if user starts interacting w/ the foreground app.
*
* This is different than {@link #mLastRectTouched} as it can get reset by the system whereas
@@ -108,7 +108,7 @@
mNavBarGesturalHeight = getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE);
}
- private void refreshTouchRegion(DefaultDisplay.Info info, Resources newRes) {
+ private void refreshTouchRegion(Info info, Resources newRes) {
// Swipe touch regions are independent of nav mode, so we have to clear them explicitly
// here to avoid, for ex, a nav region for 2-button rotation 0 being used for 3-button mode
// It tries to cache and reuse swipe regions whenever possible based only on rotation
@@ -117,7 +117,7 @@
resetSwipeRegions(info);
}
- void setNavigationMode(SysUINavigationMode.Mode newMode, DefaultDisplay.Info info,
+ void setNavigationMode(SysUINavigationMode.Mode newMode, Info info,
Resources newRes) {
if (mMode == newMode) {
return;
@@ -126,7 +126,7 @@
refreshTouchRegion(info, newRes);
}
- void setGesturalHeight(int newGesturalHeight, DefaultDisplay.Info info, Resources newRes) {
+ void setGesturalHeight(int newGesturalHeight, Info info, Resources newRes) {
if (mNavBarGesturalHeight == newGesturalHeight) {
return;
}
@@ -140,9 +140,9 @@
* alongside other regions.
* Ok to call multiple times
*
- * @see #enableMultipleRegions(boolean, DefaultDisplay.Info)
+ * @see #enableMultipleRegions(boolean, Info)
*/
- void createOrAddTouchRegion(DefaultDisplay.Info info) {
+ void createOrAddTouchRegion(Info info) {
mCurrentDisplayRotation = info.rotation;
if (mQuickStepStartingRotation > QUICKSTEP_ROTATION_UNINITIALIZED
&& mCurrentDisplayRotation == mQuickStepStartingRotation) {
@@ -170,7 +170,7 @@
* @param enableMultipleRegions Set to true to start tracking multiple nav bar regions
* @param info The current displayInfo which will be the start of the quickswitch gesture
*/
- void enableMultipleRegions(boolean enableMultipleRegions, DefaultDisplay.Info info) {
+ void enableMultipleRegions(boolean enableMultipleRegions, Info info) {
mEnableMultipleRegions = enableMultipleRegions &&
mMode != SysUINavigationMode.Mode.TWO_BUTTONS;
if (mEnableMultipleRegions) {
@@ -191,7 +191,7 @@
*
* @param displayInfo The display whos rotation will be used as the current active rotation
*/
- void setSingleActiveRegion(DefaultDisplay.Info displayInfo) {
+ void setSingleActiveRegion(Info displayInfo) {
mActiveTouchRotation = displayInfo.rotation;
resetSwipeRegions(displayInfo);
}
@@ -202,7 +202,7 @@
* To be called whenever we want to stop tracking more than one swipe region.
* Ok to call multiple times.
*/
- private void resetSwipeRegions(DefaultDisplay.Info region) {
+ private void resetSwipeRegions(Info region) {
if (DEBUG) {
Log.d(TAG, "clearing all regions except rotation: " + mCurrentDisplayRotation);
}
@@ -226,7 +226,7 @@
}
}
- private OrientationRectF createRegionForDisplay(DefaultDisplay.Info display) {
+ private OrientationRectF createRegionForDisplay(Info display) {
if (DEBUG) {
Log.d(TAG, "creating rotation region for: " + mCurrentDisplayRotation);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index fe152a0..e9fc423 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -17,8 +17,8 @@
import static android.content.Intent.ACTION_USER_UNLOCKED;
-import static com.android.launcher3.util.DefaultDisplay.CHANGE_ALL;
-import static com.android.launcher3.util.DefaultDisplay.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL;
+import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
@@ -56,7 +56,10 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.DisplayHolder;
+import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.SecureSettingsObserver;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SysUINavigationMode.OneHandedModeChangeListener;
@@ -76,14 +79,14 @@
*/
public class RecentsAnimationDeviceState implements
NavigationModeChangeListener,
- DefaultDisplay.DisplayInfoChangeListener,
+ DisplayInfoChangeListener,
OneHandedModeChangeListener {
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
private final Context mContext;
private final SysUINavigationMode mSysUiNavMode;
- private final DefaultDisplay mDefaultDisplay;
+ private final DisplayHolder mDisplayHolder;
private final int mDisplayId;
private final RotationTouchHelper mRotationTouchHelper;
@@ -120,13 +123,17 @@
private boolean mIsUserSetupComplete;
public RecentsAnimationDeviceState(Context context) {
+ this(context, DisplayController.getDefaultDisplay(context));
+ }
+
+ public RecentsAnimationDeviceState(Context context, DisplayHolder displayHolder) {
mContext = context;
+ mDisplayHolder = displayHolder;
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
- mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
- mDisplayId = mDefaultDisplay.getInfo().id;
+ mDisplayId = mDisplayHolder.getInfo().id;
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
- runOnDestroy(() -> mDefaultDisplay.removeChangeListener(this));
- mRotationTouchHelper = new RotationTouchHelper(context);
+ runOnDestroy(() -> mDisplayHolder.removeChangeListener(this));
+ mRotationTouchHelper = new RotationTouchHelper(context, mDisplayHolder);
runOnDestroy(mRotationTouchHelper::destroy);
// Register for user unlocked if necessary
@@ -232,9 +239,9 @@
@Override
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- mDefaultDisplay.removeChangeListener(this);
- mDefaultDisplay.addChangeListener(this);
- onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
+ mDisplayHolder.removeChangeListener(this);
+ mDisplayHolder.addChangeListener(this);
+ onDisplayInfoChanged(mDisplayHolder.getInfo(), CHANGE_ALL);
if (newMode == NO_BUTTON) {
mExclusionListener.register();
@@ -242,12 +249,12 @@
mExclusionListener.unregister();
}
- mNavBarPosition = new NavBarPosition(newMode, mDefaultDisplay.getInfo());
+ mNavBarPosition = new NavBarPosition(newMode, mDisplayHolder.getInfo());
mMode = newMode;
}
@Override
- public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
+ public void onDisplayInfoChanged(Info info, int flags) {
if (info.id != getDisplayId() || flags == CHANGE_FRAME_DELAY) {
// ignore displays that aren't running launcher and frame refresh rate changes
return;
@@ -529,7 +536,7 @@
}
if (mIsOneHandedModeEnabled || mIsSwipeToNotificationEnabled) {
- final DefaultDisplay.Info displayInfo = mDefaultDisplay.getInfo();
+ final Info displayInfo = mDisplayHolder.getInfo();
return (mRotationTouchHelper.touchInOneHandedModeRegion(ev)
&& displayInfo.rotation != Surface.ROTATION_90
&& displayInfo.rotation != Surface.ROTATION_270
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 2b5e42a..2cf3212 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -17,8 +17,8 @@
import static android.view.Surface.ROTATION_0;
-import static com.android.launcher3.util.DefaultDisplay.CHANGE_ALL;
-import static com.android.launcher3.util.DefaultDisplay.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ALL;
+import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_FRAME_DELAY;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
@@ -28,8 +28,9 @@
import android.view.OrientationEventListener;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.DefaultDisplay;
-import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.DisplayController.DisplayHolder;
+import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
@@ -40,10 +41,10 @@
public class RotationTouchHelper implements
SysUINavigationMode.NavigationModeChangeListener,
- DefaultDisplay.DisplayInfoChangeListener {
+ DisplayInfoChangeListener {
private final OrientationTouchTransformer mOrientationTouchTransformer;
- private final DefaultDisplay mDefaultDisplay;
+ private final DisplayHolder mDisplayHolder;
private final SysUINavigationMode mSysUiNavMode;
private final int mDisplayId;
private int mDisplayRotation;
@@ -120,12 +121,12 @@
private final Context mContext;
- public RotationTouchHelper(Context context) {
+ public RotationTouchHelper(Context context, DisplayHolder displayHolder) {
mContext = context;
+ mDisplayHolder = displayHolder;
Resources resources = mContext.getResources();
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
- mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
- mDisplayId = mDefaultDisplay.getInfo().id;
+ mDisplayId = mDisplayHolder.getInfo().id;
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
() -> QuickStepContract.getWindowCornerRadius(resources));
@@ -200,7 +201,7 @@
return;
}
- mOrientationTouchTransformer.createOrAddTouchRegion(mDefaultDisplay.getInfo());
+ mOrientationTouchTransformer.createOrAddTouchRegion(mDisplayHolder.getInfo());
}
/**
@@ -222,11 +223,11 @@
@Override
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- mDefaultDisplay.removeChangeListener(this);
- mDefaultDisplay.addChangeListener(this);
- onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
+ mDisplayHolder.removeChangeListener(this);
+ mDisplayHolder.addChangeListener(this);
+ onDisplayInfoChanged(mDisplayHolder.getInfo(), CHANGE_ALL);
- mOrientationTouchTransformer.setNavigationMode(newMode, mDefaultDisplay.getInfo(),
+ mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayHolder.getInfo(),
mContext.getResources());
if (!mMode.hasGestures && newMode.hasGestures) {
setupOrientationSwipeHandler();
@@ -242,7 +243,7 @@
}
@Override
- public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
+ public void onDisplayInfoChanged(Info info, int flags) {
if (info.id != mDisplayId|| flags == CHANGE_FRAME_DELAY) {
// ignore displays that aren't running launcher and frame refresh rate changes
return;
@@ -275,7 +276,7 @@
* Sets the gestural height.
*/
void setGesturalHeight(int newGesturalHeight) {
- mOrientationTouchTransformer.setGesturalHeight(newGesturalHeight, mDefaultDisplay.getInfo(),
+ mOrientationTouchTransformer.setGesturalHeight(newGesturalHeight, mDisplayHolder.getInfo(),
mContext.getResources());
}
@@ -292,7 +293,7 @@
}
private void enableMultipleRegions(boolean enable) {
- mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
+ mOrientationTouchTransformer.enableMultipleRegions(enable, mDisplayHolder.getInfo());
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
if (enable && !mInOverview && !TestProtocol.sDisableSensorRotation) {
// Clear any previous state from sensor manager
@@ -355,7 +356,7 @@
* notifies system UI of the primary rotation the user is interacting with
*/
private void toggleSecondaryNavBarsForRotation() {
- mOrientationTouchTransformer.setSingleActiveRegion(mDefaultDisplay.getInfo());
+ mOrientationTouchTransformer.setSingleActiveRegion(mDisplayHolder.getInfo());
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index 60d8ef6..865b66e 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -16,7 +16,7 @@
package com.android.quickstep.interaction;
import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.AbsSwipeUpHandler.MAX_SWIPE_DURATION;
import static com.android.quickstep.interaction.TutorialController.TutorialType.HOME_NAVIGATION_COMPLETE;
diff --git a/quickstep/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
index 0a98e1b..449dba8 100644
--- a/quickstep/src/com/android/quickstep/util/NavBarPosition.java
+++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
@@ -19,7 +19,7 @@
import android.view.Surface;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.quickstep.SysUINavigationMode;
/**
@@ -30,7 +30,7 @@
private final SysUINavigationMode.Mode mMode;
private final int mDisplayRotation;
- public NavBarPosition(SysUINavigationMode.Mode mode, DefaultDisplay.Info info) {
+ public NavBarPosition(SysUINavigationMode.Mode mode, Info info) {
mMode = mode;
mDisplayRotation = info.rotation;
}
diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
index a770e8e..176478f 100644
--- a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
+++ b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
@@ -32,7 +32,7 @@
import androidx.annotation.UiThread;
import com.android.launcher3.R;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.WindowBounds;
import java.util.ArrayList;
@@ -77,7 +77,7 @@
WindowBounds bounds = new WindowBounds(wm.getBounds(),
new Rect(insets.left, insets.top, insets.right, insets.bottom));
- int rotation = DefaultDisplay.INSTANCE.get(context).getInfo().rotation;
+ int rotation = DisplayController.getDefaultDisplay(context).getInfo().rotation;
int halfDividerSize = context.getResources()
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index bd8c53c..cbc3abc 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -17,7 +17,7 @@
package com.android.launcher3;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
-import static com.android.launcher3.util.DefaultDisplay.CHANGE_ROTATION;
+import static com.android.launcher3.util.DisplayController.DisplayHolder.CHANGE_ROTATION;
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
@@ -50,9 +50,9 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
-import com.android.launcher3.util.DefaultDisplay;
-import com.android.launcher3.util.DefaultDisplay.DisplayInfoChangeListener;
-import com.android.launcher3.util.DefaultDisplay.Info;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TraceHelper;
@@ -84,7 +84,7 @@
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
() -> getPackageManager().isSafeMode());
- DefaultDisplay.INSTANCE.get(this).addChangeListener(this);
+ DisplayController.getDefaultDisplay(this).addChangeListener(this);
// Update theme
WallpaperColorInfo.INSTANCE.get(this).addOnChangeListener(this);
@@ -257,7 +257,7 @@
protected void onDestroy() {
super.onDestroy();
WallpaperColorInfo.INSTANCE.get(this).removeOnChangeListener(this);
- DefaultDisplay.INSTANCE.get(this).removeChangeListener(this);
+ DisplayController.getDefaultDisplay(this).removeChangeListener(this);
}
public void runOnceOnStart(Runnable action) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 49caa93..12ce9f3 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -28,7 +28,8 @@
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconNormalizer;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.WindowBounds;
public class DeviceProfile {
@@ -38,7 +39,7 @@
public final InvariantDeviceProfile inv;
- private final DefaultDisplay.Info mInfo;
+ private final Info mInfo;
// Device properties
public final boolean isTablet;
@@ -140,7 +141,7 @@
public DotRenderer mDotRendererWorkSpace;
public DotRenderer mDotRendererAllApps;
- DeviceProfile(Context context, InvariantDeviceProfile inv, DefaultDisplay.Info info,
+ DeviceProfile(Context context, InvariantDeviceProfile inv, Info info,
Point minSize, Point maxSize, int width, int height, boolean isLandscape,
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
Point windowPosition) {
@@ -606,7 +607,7 @@
*/
public boolean updateIsSeascape(Context context) {
if (isVerticalBarLayout()) {
- boolean isSeascape = DefaultDisplay.INSTANCE.get(context).getInfo().rotation
+ boolean isSeascape = DisplayController.getDefaultDisplay(context).getInfo().rotation
== Surface.ROTATION_270;
if (mIsSeascape != isSeascape) {
mIsSeascape = isSeascape;
@@ -638,7 +639,7 @@
}
}
- private static Context getContext(Context c, DefaultDisplay.Info info, int orientation) {
+ private static Context getContext(Context c, Info info, int orientation) {
Configuration config = new Configuration(c.getResources().getConfiguration());
config.orientation = orientation;
config.densityDpi = info.metrics.densityDpi;
@@ -662,7 +663,7 @@
public static class Builder {
private Context mContext;
private InvariantDeviceProfile mInv;
- private DefaultDisplay.Info mInfo;
+ private Info mInfo;
private final Point mWindowPosition = new Point();
private Point mMinSize, mMaxSize;
@@ -672,7 +673,7 @@
private boolean mIsMultiWindowMode = false;
private boolean mTransposeLayoutWithOrientation;
- public Builder(Context context, InvariantDeviceProfile inv, DefaultDisplay.Info info) {
+ public Builder(Context context, InvariantDeviceProfile inv, Info info) {
mContext = context;
mInv = inv;
mInfo = info;
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
index 6c5bc40..a199a57 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index e39e89c..370bd6f 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -48,8 +48,8 @@
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.util.ConfigMonitor;
-import com.android.launcher3.util.DefaultDisplay;
-import com.android.launcher3.util.DefaultDisplay.Info;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Themes;
@@ -198,7 +198,7 @@
// Get the display info based on default display and interpolate it to existing display
DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
- DefaultDisplay.INSTANCE.get(context).getInfo(),
+ DisplayController.getDefaultDisplay(context).getInfo(),
getPredefinedDeviceProfiles(context, gridName));
Info myInfo = new Info(context, display);
@@ -231,7 +231,7 @@
}
private String initGrid(Context context, String gridName) {
- DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(context).getInfo();
+ Info displayInfo = DisplayController.getDefaultDisplay(context).getInfo();
ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
DisplayOption displayOption = invDistWeightedInterpolate(displayInfo, allOptions);
@@ -240,7 +240,7 @@
}
private void initGrid(
- Context context, DefaultDisplay.Info displayInfo, DisplayOption displayOption) {
+ Context context, Info displayInfo, DisplayOption displayOption) {
GridOption closestProfile = displayOption.grid;
numRows = closestProfile.numRows;
numColumns = closestProfile.numColumns;
@@ -466,7 +466,7 @@
@VisibleForTesting
static DisplayOption invDistWeightedInterpolate(
- DefaultDisplay.Info displayInfo, ArrayList<DisplayOption> points) {
+ Info displayInfo, ArrayList<DisplayOption> points) {
Point smallestSize = new Point(displayInfo.smallestSize);
Point largestSize = new Point(displayInfo.largestSize);
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index ea0ff8b..dcdfb6e 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 6ad43ea..8016b2d 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -16,7 +16,7 @@
package com.android.launcher3.anim;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.content.Context;
import android.graphics.Path;
diff --git a/src/com/android/launcher3/anim/SpringAnimationBuilder.java b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
index a9702b4..bd52158 100644
--- a/src/com/android/launcher3/anim/SpringAnimationBuilder.java
+++ b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
@@ -25,7 +25,7 @@
import androidx.annotation.FloatRange;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
/**
* Utility class to build an object animator which follows the same path as a spring animation for
@@ -134,7 +134,7 @@
}
public SpringAnimationBuilder computeParams() {
- int singleFrameMs = DefaultDisplay.getSingleFrameMs(mContext);
+ int singleFrameMs = DisplayController.getSingleFrameMs(mContext);
double naturalFreq = Math.sqrt(mStiffness);
double dampedFreq = naturalFreq * Math.sqrt(1 - mDampingRatio * mDampingRatio);
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 02ca926..8ee5a6e 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -26,7 +26,7 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
import static com.android.launcher3.states.StateAnimationConfig.PLAY_ATOMIC_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.PLAY_NON_ATOMIC;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
index 0f81520..b3b69f6 100644
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ b/src/com/android/launcher3/util/ConfigMonitor.java
@@ -26,14 +26,16 @@
import android.graphics.Point;
import android.util.Log;
+import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
+import com.android.launcher3.util.DisplayController.Info;
+
import java.util.function.Consumer;
/**
* {@link BroadcastReceiver} which watches configuration changes and
* notifies the callback in case changes which affect the device profile occur.
*/
-public class ConfigMonitor extends BroadcastReceiver implements
- DefaultDisplay.DisplayInfoChangeListener {
+public class ConfigMonitor extends BroadcastReceiver implements DisplayInfoChangeListener {
private static final String TAG = "ConfigMonitor";
@@ -57,9 +59,9 @@
mFontScale = config.fontScale;
mDensity = config.densityDpi;
- DefaultDisplay display = DefaultDisplay.INSTANCE.get(context);
+ DisplayController.DisplayHolder display = DisplayController.getDefaultDisplay(context);
display.addChangeListener(this);
- DefaultDisplay.Info displayInfo = display.getInfo();
+ Info displayInfo = display.getInfo();
mDisplayId = displayInfo.id;
mRealSize = new Point(displayInfo.realSize);
@@ -82,7 +84,7 @@
}
@Override
- public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
+ public void onDisplayInfoChanged(Info info, int flags) {
if (info.id != mDisplayId) {
return;
}
@@ -113,8 +115,7 @@
public void unregister() {
try {
mContext.unregisterReceiver(this);
- DefaultDisplay display = DefaultDisplay.INSTANCE.get(mContext);
- display.removeChangeListener(this);
+ DisplayController.getDefaultDisplay(mContext).removeChangeListener(this);
} catch (Exception e) {
Log.e(TAG, "Failed to unregister config monitor", e);
}
diff --git a/src/com/android/launcher3/util/DefaultDisplay.java b/src/com/android/launcher3/util/DefaultDisplay.java
deleted file mode 100644
index 35788a5..0000000
--- a/src/com/android/launcher3/util/DefaultDisplay.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
-import android.content.Context;
-import android.graphics.Point;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
-import android.os.Handler;
-import android.os.Message;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.Display;
-
-import androidx.annotation.VisibleForTesting;
-
-import java.util.ArrayList;
-
-/**
- * Utility class to cache properties of default display to avoid a system RPC on every call.
- */
-public class DefaultDisplay implements DisplayListener {
-
- public static final MainThreadInitializedObject<DefaultDisplay> INSTANCE =
- new MainThreadInitializedObject<>(DefaultDisplay::new);
-
- private static final String TAG = "DefaultDisplay";
-
- public static final int CHANGE_SIZE = 1 << 0;
- public static final int CHANGE_ROTATION = 1 << 1;
- public static final int CHANGE_FRAME_DELAY = 1 << 2;
-
- public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION | CHANGE_FRAME_DELAY;
-
- private final Context mDisplayContext;
- private final int mId;
- private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
- private final Handler mChangeHandler;
- private Info mInfo;
-
- private DefaultDisplay(Context 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);
-
- dm.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
- }
-
- @Override
- public final void onDisplayAdded(int displayId) { }
-
- @Override
- public final void onDisplayRemoved(int displayId) { }
-
- @Override
- public final void onDisplayChanged(int displayId) {
- if (displayId != mId) {
- return;
- }
-
- Info oldInfo = mInfo;
- Info info = new Info(mDisplayContext);
-
- int change = 0;
- if (info.hasDifferentSize(oldInfo)) {
- change |= CHANGE_SIZE;
- }
- if (oldInfo.rotation != info.rotation) {
- change |= CHANGE_ROTATION;
- }
- if (info.singleFrameMs != oldInfo.singleFrameMs) {
- change |= CHANGE_FRAME_DELAY;
- }
-
- if (change != 0) {
- mInfo = info;
- mChangeHandler.sendEmptyMessage(change);
- }
- }
-
- public static int getSingleFrameMs(Context context) {
- return INSTANCE.get(context).getInfo().singleFrameMs;
- }
-
- public Info getInfo() {
- return mInfo;
- }
-
- public void addChangeListener(DisplayInfoChangeListener listener) {
- mListeners.add(listener);
- }
-
- public void removeChangeListener(DisplayInfoChangeListener listener) {
- mListeners.remove(listener);
- }
-
- private boolean onChange(Message msg) {
- for (int i = mListeners.size() - 1; i >= 0; i--) {
- mListeners.get(i).onDisplayInfoChanged(mInfo, msg.what);
- }
- return true;
- }
-
- public static class Info {
-
- public final int id;
- public final int rotation;
- public final int singleFrameMs;
-
- public final Point realSize;
- public final Point smallestSize;
- public final Point largestSize;
-
- public final DisplayMetrics metrics;
-
- @VisibleForTesting
- public Info(int id, int rotation, int singleFrameMs, Point realSize, Point smallestSize,
- Point largestSize, DisplayMetrics metrics) {
- this.id = id;
- this.rotation = rotation;
- this.singleFrameMs = singleFrameMs;
- this.realSize = realSize;
- this.smallestSize = smallestSize;
- this.largestSize = largestSize;
- this.metrics = metrics;
- }
-
- private Info(Context context) {
- this(context, context.getSystemService(DisplayManager.class)
- .getDisplay(DEFAULT_DISPLAY));
- }
-
- public Info(Context context, Display display) {
- id = display.getDisplayId();
- rotation = display.getRotation();
-
- float refreshRate = display.getRefreshRate();
- singleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
-
- realSize = new Point();
- smallestSize = new Point();
- largestSize = new Point();
- display.getRealSize(realSize);
- display.getCurrentSizeRange(smallestSize, largestSize);
-
- metrics = context.getResources().getDisplayMetrics();
- }
-
- private boolean hasDifferentSize(Info info) {
- if (!realSize.equals(info.realSize)
- && !realSize.equals(info.realSize.y, info.realSize.x)) {
- Log.d(TAG, String.format("Display size changed from %s to %s",
- info.realSize, realSize));
- return true;
- }
-
- if (!smallestSize.equals(info.smallestSize) || !largestSize.equals(info.largestSize)) {
- Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
- smallestSize, largestSize, info.smallestSize, info.largestSize));
- return true;
- }
-
- return false;
- }
- }
-
- /**
- * Interface for listening for display changes
- */
- public interface DisplayInfoChangeListener {
-
- void onDisplayInfoChanged(Info info, int flags);
- }
-}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
new file mode 100644
index 0000000..e5c8441
--- /dev/null
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Display;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.util.ArrayList;
+
+/**
+ * Utility class to cache properties of default display to avoid a system RPC on every call.
+ */
+public class DisplayController implements DisplayListener {
+
+ private static final String TAG = "DisplayController";
+
+ public static final MainThreadInitializedObject<DisplayController> INSTANCE =
+ new MainThreadInitializedObject<>(DisplayController::new);
+
+ private final SparseArray<DisplayHolder> mOtherDisplays = new SparseArray<>(0);
+ // We store the default display separately, to avoid null checks for primary use case.
+ private final DisplayHolder mDefaultDisplay;
+
+ private final ArrayList<DisplayListChangeListener> mListListeners = new ArrayList<>();
+
+ private DisplayController(Context context) {
+ mDefaultDisplay = new DisplayHolder(context, DEFAULT_DISPLAY);
+
+ DisplayManager dm = context.getSystemService(DisplayManager.class);
+ dm.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
+ }
+
+ @Override
+ public final void onDisplayAdded(int displayId) {
+ DisplayHolder holder = new DisplayHolder(mDefaultDisplay.mDisplayContext, displayId);
+ synchronized (mOtherDisplays) {
+ mOtherDisplays.put(displayId, holder);
+ }
+ MAIN_EXECUTOR.execute(() -> mListListeners.forEach(l-> l.onDisplayAdded(holder)));
+ }
+
+ @Override
+ public final void onDisplayRemoved(int displayId) {
+ synchronized (mOtherDisplays) {
+ mOtherDisplays.remove(displayId);
+ }
+ MAIN_EXECUTOR.execute(() -> mListListeners.forEach(l-> l.onDisplayRemoved(displayId)));
+ }
+
+ /**
+ * Returns the holder corresponding to the given display
+ */
+ public DisplayHolder getHolder(int displayId) {
+ if (displayId == mDefaultDisplay.mId) {
+ return mDefaultDisplay;
+ } else {
+ synchronized (mOtherDisplays) {
+ return mOtherDisplays.get(displayId);
+ }
+ }
+ }
+
+ /**
+ * Adds a listener for display list changes
+ */
+ public void addListChangeListener(DisplayListChangeListener listener) {
+ mListListeners.add(listener);
+ }
+
+ /**
+ * Removes a previously added display list change listener
+ */
+ public void removeListChangeListener(DisplayListChangeListener listener) {
+ mListListeners.remove(listener);
+ }
+
+ @Override
+ public final void onDisplayChanged(int displayId) {
+ DisplayHolder holder = getHolder(displayId);
+ if (holder != null) {
+ holder.handleOnChange();
+ }
+ }
+
+ public static int getSingleFrameMs(Context context) {
+ return getDefaultDisplay(context).getInfo().singleFrameMs;
+ }
+
+ public static DisplayHolder getDefaultDisplay(Context context) {
+ return INSTANCE.get(context).mDefaultDisplay;
+ }
+
+ /**
+ * A listener to receiving addition or removal of new displays
+ */
+ public interface DisplayListChangeListener {
+
+ /**
+ * Called when a new display is added
+ */
+ void onDisplayAdded(DisplayHolder holder);
+
+ /**
+ * Called when a previously added display is removed
+ */
+ void onDisplayRemoved(int displayId);
+ }
+
+ /**
+ * Interface for listening for display changes
+ */
+ public interface DisplayInfoChangeListener {
+
+ void onDisplayInfoChanged(Info info, int flags);
+ }
+
+ public static class DisplayHolder {
+
+ public static final int CHANGE_SIZE = 1 << 0;
+ public static final int CHANGE_ROTATION = 1 << 1;
+ public static final int CHANGE_FRAME_DELAY = 1 << 2;
+
+ public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION | CHANGE_FRAME_DELAY;
+
+ final Context mDisplayContext;
+ final int mId;
+ private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
+ private DisplayController.Info mInfo;
+
+ public DisplayHolder(Context context, int id) {
+ 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(id));
+ // 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 DisplayController.Info(mDisplayContext);
+ mId = mInfo.id;
+ }
+
+ public void addChangeListener(DisplayInfoChangeListener listener) {
+ mListeners.add(listener);
+ }
+
+ public void removeChangeListener(DisplayInfoChangeListener listener) {
+ mListeners.remove(listener);
+ }
+
+ public DisplayController.Info getInfo() {
+ return mInfo;
+ }
+
+ protected void handleOnChange() {
+ Info oldInfo = mInfo;
+ Info info = new Info(mDisplayContext);
+
+ int change = 0;
+ if (info.hasDifferentSize(oldInfo)) {
+ change |= CHANGE_SIZE;
+ }
+ if (oldInfo.rotation != info.rotation) {
+ change |= CHANGE_ROTATION;
+ }
+ if (info.singleFrameMs != oldInfo.singleFrameMs) {
+ change |= CHANGE_FRAME_DELAY;
+ }
+
+ if (change != 0) {
+ mInfo = info;
+ final int flags = change;
+ MAIN_EXECUTOR.execute(() -> notifyChange(flags));
+ }
+ }
+
+ private void notifyChange(int flags) {
+ for (int i = mListeners.size() - 1; i >= 0; i--) {
+ mListeners.get(i).onDisplayInfoChanged(mInfo, flags);
+ }
+ }
+
+ }
+
+ public static class Info {
+
+ public final int id;
+ public final int rotation;
+ public final int singleFrameMs;
+
+ public final Point realSize;
+ public final Point smallestSize;
+ public final Point largestSize;
+
+ public final DisplayMetrics metrics;
+
+ @VisibleForTesting
+ public Info(int id, int rotation, int singleFrameMs, Point realSize, Point smallestSize,
+ Point largestSize, DisplayMetrics metrics) {
+ this.id = id;
+ this.rotation = rotation;
+ this.singleFrameMs = singleFrameMs;
+ this.realSize = realSize;
+ this.smallestSize = smallestSize;
+ this.largestSize = largestSize;
+ this.metrics = metrics;
+ }
+
+ private Info(Context context) {
+ this(context, context.getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY));
+ }
+
+ public Info(Context context, Display display) {
+ id = display.getDisplayId();
+ rotation = display.getRotation();
+
+ float refreshRate = display.getRefreshRate();
+ singleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
+
+ realSize = new Point();
+ smallestSize = new Point();
+ largestSize = new Point();
+ display.getRealSize(realSize);
+ display.getCurrentSizeRange(smallestSize, largestSize);
+
+ metrics = context.getResources().getDisplayMetrics();
+ }
+
+ private boolean hasDifferentSize(Info info) {
+ if (!realSize.equals(info.realSize)
+ && !realSize.equals(info.realSize.y, info.realSize.x)) {
+ Log.d(TAG, String.format("Display size changed from %s to %s",
+ info.realSize, realSize));
+ return true;
+ }
+
+ if (!smallestSize.equals(info.smallestSize) || !largestSize.equals(info.largestSize)) {
+ Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
+ smallestSize, largestSize, info.smallestSize, info.largestSize));
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 357eeb8..2be827b 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -20,7 +20,7 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
-import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.annotation.TargetApi;
import android.app.WallpaperInfo;
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index 040619e..9582232 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -40,7 +40,7 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.util.DefaultDisplay;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors;
/**
@@ -97,7 +97,7 @@
// Remove after some time, to avoid flickering
Executors.MAIN_EXECUTOR.getHandler().postDelayed(mRemoveViewRunnable,
- DefaultDisplay.INSTANCE.get(mLauncher).getInfo().singleFrameMs);
+ DisplayController.getDefaultDisplay(mLauncher).getInfo().singleFrameMs);
}
private void removeViewFromParent() {