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 5c9fd4705b..3867c35050 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.states.StateAnimationConfig.SKIP_OVERVIEW; 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 d2fee30ca3..282f6fa2b8 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.LAUNCH 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 e2e25f32d3..a5af1814d9 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.DeviceProfile; 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 @@ public final class TaskViewUtils { 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 be3fddecf0..a4a7bd3ae9 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 android.view.MotionEvent; 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 @@ public class FallbackNavBarTouchController implements TouchController, 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 7032fae8f0..584ff28fdb 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.R; 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 @@ public class DeviceLockedInputConsumer implements InputConsumer, 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 22d205a7cd..5cb55ec2d0 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.MotionEvent; 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 @@ public class OrientationTouchTransformerTest { private OrientationTouchTransformer mTouchTransformer; Resources mResources; - private DefaultDisplay.Info mInfo; + private DisplayController.Info mInfo; @Before @@ -231,12 +231,12 @@ public class OrientationTouchTransformerTest { 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 a31ba2177b..5491daae7b 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 android.view.SurfaceControl; 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 @@ public class TaskViewSimulatorTest { 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 5ad0bca11f..199cf63b92 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 b2bce0c043..eb33f98dad 100644 --- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java +++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java @@ -37,7 +37,7 @@ import android.view.Surface; 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 @@ class OrientationTouchTransformer { * 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 @@ class OrientationTouchTransformer { 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 @@ class OrientationTouchTransformer { 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 @@ class OrientationTouchTransformer { 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 @@ class OrientationTouchTransformer { * 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 @@ class OrientationTouchTransformer { * @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 @@ class OrientationTouchTransformer { * * @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 @@ class OrientationTouchTransformer { * 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 @@ class OrientationTouchTransformer { } } - 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 fe152a0cd9..e9fc42328b 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -17,8 +17,8 @@ package com.android.quickstep; 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 androidx.annotation.BinderThread; 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 @@ import java.util.stream.Collectors; */ 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 @@ public class RecentsAnimationDeviceState implements 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 @@ public class RecentsAnimationDeviceState implements @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 @@ public class RecentsAnimationDeviceState implements 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 @@ public class RecentsAnimationDeviceState implements } 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 2b5e42a61e..2cf32122cf 100644 --- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java +++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java @@ -17,8 +17,8 @@ package com.android.quickstep; 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.MotionEvent; 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 @@ import java.util.ArrayList; 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 @@ public class RotationTouchHelper implements 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 @@ public class RotationTouchHelper implements return; } - mOrientationTouchTransformer.createOrAddTouchRegion(mDefaultDisplay.getInfo()); + mOrientationTouchTransformer.createOrAddTouchRegion(mDisplayHolder.getInfo()); } /** @@ -222,11 +223,11 @@ public class RotationTouchHelper implements @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 @@ public class RotationTouchHelper implements } @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 @@ public class RotationTouchHelper implements * Sets the gestural height. */ void setGesturalHeight(int newGesturalHeight) { - mOrientationTouchTransformer.setGesturalHeight(newGesturalHeight, mDefaultDisplay.getInfo(), + mOrientationTouchTransformer.setGesturalHeight(newGesturalHeight, mDisplayHolder.getInfo(), mContext.getResources()); } @@ -292,7 +293,7 @@ public class RotationTouchHelper implements } 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 @@ public class RotationTouchHelper implements * 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 60d8ef6ff4..865b66e64b 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 0a98e1bfea..449dba8f26 100644 --- a/quickstep/src/com/android/quickstep/util/NavBarPosition.java +++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java @@ -19,7 +19,7 @@ import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON; 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 @@ public class NavBarPosition { 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 a770e8e2b5..176478f1dc 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.Nullable; 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 @@ public class SplitScreenBounds { 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 bd8c53cb92..cbc3abcc41 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.ItemInfo; 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 @@ public abstract class BaseDraggingActivity extends BaseActivity 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 @@ public abstract class BaseDraggingActivity extends BaseActivity 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 49caa93e61..12ce9f3448 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -28,7 +28,8 @@ import com.android.launcher3.CellLayout.ContainerType; 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 class DeviceProfile { public final InvariantDeviceProfile inv; - private final DefaultDisplay.Info mInfo; + private final Info mInfo; // Device properties public final boolean isTablet; @@ -140,7 +141,7 @@ public class DeviceProfile { 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 class DeviceProfile { */ 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 @@ public class DeviceProfile { } } - 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 class DeviceProfile { 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 @@ public class DeviceProfile { 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 6c5bc40b3e..a199a5779a 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 e39e89c038..370bd6ffc8 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -48,8 +48,8 @@ import androidx.annotation.VisibleForTesting; 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 @@ public class InvariantDeviceProfile { // 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 @@ public class InvariantDeviceProfile { } private String initGrid(Context context, String gridName) { - DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(context).getInfo(); + Info displayInfo = DisplayController.getDefaultDisplay(context).getInfo(); ArrayList allOptions = getPredefinedDeviceProfiles(context, gridName); DisplayOption displayOption = invDistWeightedInterpolate(displayInfo, allOptions); @@ -240,7 +240,7 @@ public class InvariantDeviceProfile { } 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 @@ public class InvariantDeviceProfile { @VisibleForTesting static DisplayOption invDistWeightedInterpolate( - DefaultDisplay.Info displayInfo, ArrayList points) { + Info displayInfo, ArrayList 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 ea0ff8b687..dcdfb6e51a 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.Utilities.boundToRange; 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 6ad43ea1e4..8016b2d5b8 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 a9702b4784..bd52158f0a 100644 --- a/src/com/android/launcher3/anim/SpringAnimationBuilder.java +++ b/src/com/android/launcher3/anim/SpringAnimationBuilder.java @@ -25,7 +25,7 @@ import android.util.FloatProperty; 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 class SpringAnimationBuilder { } 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 02ca92618e..8ee5a6e533 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.logging.StatsLogManager.LauncherEvent.LAUNCH 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 0f81520578..b3b69f6ab3 100644 --- a/src/com/android/launcher3/util/ConfigMonitor.java +++ b/src/com/android/launcher3/util/ConfigMonitor.java @@ -26,14 +26,16 @@ import android.content.res.Configuration; 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 @@ public class ConfigMonitor extends BroadcastReceiver implements 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 @@ public class ConfigMonitor extends BroadcastReceiver implements } @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 class ConfigMonitor extends BroadcastReceiver implements 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 35788a54c8..0000000000 --- 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 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 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 0000000000..e5c84418c6 --- /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 INSTANCE = + new MainThreadInitializedObject<>(DisplayController::new); + + private final SparseArray 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 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 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 357eeb81f9..2be827b01a 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_CANCEL; 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 040619e9c7..9582232279 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.GestureNavContract; 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 @@ public class FloatingSurfaceView extends AbstractFloatingView implements // 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() {