Loading libs/WindowManager/Shell/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ <uses-permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE" /> <uses-permission android:name="android.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION" /> <uses-permission android:name="android.permission.MANAGE_KEY_GESTURES" /> <uses-permission android:name="android.permission.MANAGE_DISPLAYS" /> <application> <activity Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +26 −4 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayTopology; import android.os.RemoteException; import android.util.ArraySet; import android.util.Size; Loading @@ -34,6 +35,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.BinderThread; import com.android.window.flags.Flags; import com.android.wm.shell.common.DisplayChangeController.OnDisplayChangingListener; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellInit; Loading @@ -54,6 +56,7 @@ public class DisplayController { private final ShellExecutor mMainExecutor; private final Context mContext; private final IWindowManager mWmService; private final DisplayManager mDisplayManager; private final DisplayChangeController mChangeController; private final IDisplayWindowListener mDisplayContainerListener; Loading @@ -61,10 +64,11 @@ public class DisplayController { private final ArrayList<OnDisplaysChangedListener> mDisplayChangedListeners = new ArrayList<>(); public DisplayController(Context context, IWindowManager wmService, ShellInit shellInit, ShellExecutor mainExecutor) { ShellExecutor mainExecutor, DisplayManager displayManager) { mMainExecutor = mainExecutor; mContext = context; mWmService = wmService; mDisplayManager = displayManager; // TODO: Inject this instead mChangeController = new DisplayChangeController(mWmService, shellInit, mainExecutor); mDisplayContainerListener = new DisplayWindowListenerImpl(); Loading @@ -74,7 +78,7 @@ public class DisplayController { } /** * Initializes the window listener. * Initializes the window listener and the topology listener. */ public void onInit() { try { Loading @@ -82,6 +86,12 @@ public class DisplayController { for (int i = 0; i < displayIds.length; i++) { onDisplayAdded(displayIds[i]); } if (Flags.enableConnectedDisplaysWindowDrag()) { mDisplayManager.registerTopologyListener(mMainExecutor, this::onDisplayTopologyChanged); onDisplayTopologyChanged(mDisplayManager.getDisplayTopology()); } } catch (RemoteException e) { throw new RuntimeException("Unable to register display controller"); } Loading @@ -91,8 +101,7 @@ public class DisplayController { * Gets a display by id from DisplayManager. */ public Display getDisplay(int displayId) { final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); return displayManager.getDisplay(displayId); return mDisplayManager.getDisplay(displayId); } /** Loading Loading @@ -221,6 +230,14 @@ public class DisplayController { } } private void onDisplayTopologyChanged(DisplayTopology topology) { // TODO(b/381472611): Call DisplayTopology#getCoordinates and update values in // DisplayLayout when DM code is ready. for (int i = 0; i < mDisplayChangedListeners.size(); ++i) { mDisplayChangedListeners.get(i).onTopologyChanged(); } } private void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { synchronized (mDisplays) { final DisplayRecord dr = mDisplays.get(displayId); Loading Loading @@ -408,5 +425,10 @@ public class DisplayController { */ default void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) {} /** * Called when the display topology has changed. */ default void onTopologyChanged() {} } } libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java +66 −4 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.SystemProperties; import android.provider.Settings; import android.util.DisplayMetrics; Loading Loading @@ -71,9 +73,12 @@ public class DisplayLayout { public static final int NAV_BAR_RIGHT = 1 << 1; public static final int NAV_BAR_BOTTOM = 1 << 2; private static final String TAG = "DisplayLayout"; private int mUiMode; private int mWidth; private int mHeight; private RectF mGlobalBoundsDp; private DisplayCutout mCutout; private int mRotation; private int mDensityDpi; Loading Loading @@ -109,6 +114,7 @@ public class DisplayLayout { return mUiMode == other.mUiMode && mWidth == other.mWidth && mHeight == other.mHeight && Objects.equals(mGlobalBoundsDp, other.mGlobalBoundsDp) && Objects.equals(mCutout, other.mCutout) && mRotation == other.mRotation && mDensityDpi == other.mDensityDpi Loading @@ -127,8 +133,8 @@ public class DisplayLayout { @Override public int hashCode() { return Objects.hash(mUiMode, mWidth, mHeight, mCutout, mRotation, mDensityDpi, mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar, return Objects.hash(mUiMode, mWidth, mHeight, mGlobalBoundsDp, mCutout, mRotation, mDensityDpi, mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar, mNavBarFrameHeight, mTaskbarFrameHeight, mAllowSeamlessRotationDespiteNavBarMoving, mNavigationBarCanMove, mReverseDefaultRotation, mInsetsState); } Loading Loading @@ -170,6 +176,7 @@ public class DisplayLayout { mUiMode = dl.mUiMode; mWidth = dl.mWidth; mHeight = dl.mHeight; mGlobalBoundsDp = dl.mGlobalBoundsDp; mCutout = dl.mCutout; mRotation = dl.mRotation; mDensityDpi = dl.mDensityDpi; Loading @@ -193,6 +200,7 @@ public class DisplayLayout { mRotation = info.rotation; mCutout = info.displayCutout; mDensityDpi = info.logicalDensityDpi; mGlobalBoundsDp = new RectF(0, 0, pxToDp(mWidth), pxToDp(mHeight)); mHasNavigationBar = hasNavigationBar; mHasStatusBar = hasStatusBar; mAllowSeamlessRotationDespiteNavBarMoving = res.getBoolean( Loading Loading @@ -255,6 +263,11 @@ public class DisplayLayout { recalcInsets(res); } /** Update the global bounds of this layout, in DP. */ public void setGlobalBoundsDp(RectF bounds) { mGlobalBoundsDp = bounds; } /** Get this layout's non-decor insets. */ public Rect nonDecorInsets() { return mNonDecorInsets; Loading @@ -265,16 +278,21 @@ public class DisplayLayout { return mStableInsets; } /** Get this layout's width. */ /** Get this layout's width in pixels. */ public int width() { return mWidth; } /** Get this layout's height. */ /** Get this layout's height in pixels. */ public int height() { return mHeight; } /** Get this layout's global bounds in the multi-display coordinate system in DP. */ public RectF globalBoundsDp() { return mGlobalBoundsDp; } /** Get this layout's display rotation. */ public int rotation() { return mRotation; Loading Loading @@ -486,4 +504,48 @@ public class DisplayLayout { ? R.dimen.navigation_bar_frame_height_landscape : R.dimen.navigation_bar_frame_height); } /** * Converts a pixel value to a density-independent pixel (dp) value. * * @param px The pixel value to convert. * @return The equivalent value in DP units. */ public float pxToDp(Number px) { return px.floatValue() * DisplayMetrics.DENSITY_DEFAULT / mDensityDpi; } /** * Converts a density-independent pixel (dp) value to a pixel value. * * @param dp The DP value to convert. * @return The equivalent value in pixel units. */ public float dpToPx(Number dp) { return dp.floatValue() * mDensityDpi / DisplayMetrics.DENSITY_DEFAULT; } /** * Converts local pixel coordinates on this layout to global DP coordinates. * * @param xPx The x-coordinate in pixels, relative to the layout's origin. * @param yPx The y-coordinate in pixels, relative to the layout's origin. * @return A PointF object representing the coordinates in global DP units. */ public PointF localPxToGlobalDp(Number xPx, Number yPx) { return new PointF(mGlobalBoundsDp.left + pxToDp(xPx), mGlobalBoundsDp.top + pxToDp(yPx)); } /** * Converts global DP coordinates to local pixel coordinates on this layout. * * @param xDp The x-coordinate in global DP units. * @param yDp The y-coordinate in global DP units. * @return A PointF object representing the coordinates in local pixel units on this layout. */ public PointF globalDpToLocalPx(Number xDp, Number yDp) { return new PointF(dpToPx(xDp.floatValue() - mGlobalBoundsDp.left), dpToPx(yDp.floatValue() - mGlobalBoundsDp.top)); } } libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +4 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.annotation.NonNull; import android.app.ActivityTaskManager; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.SystemProperties; import android.provider.Settings; Loading Loading @@ -175,8 +176,9 @@ public abstract class WMShellBaseModule { static DisplayController provideDisplayController(Context context, IWindowManager wmService, ShellInit shellInit, @ShellMainThread ShellExecutor mainExecutor) { return new DisplayController(context, wmService, shellInit, mainExecutor); @ShellMainThread ShellExecutor mainExecutor, DisplayManager displayManager) { return new DisplayController(context, wmService, shellInit, mainExecutor, displayManager); } @WMSingleton Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java +4 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.Context; import android.hardware.display.DisplayManager; import android.view.IWindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading Loading @@ -50,12 +51,14 @@ public class DisplayControllerTests extends ShellTestCase { private @Mock IWindowManager mWM; private @Mock ShellInit mShellInit; private @Mock ShellExecutor mMainExecutor; private @Mock DisplayManager mDisplayManager; private DisplayController mController; @Before public void setUp() { MockitoAnnotations.initMocks(this); mController = new DisplayController(mContext, mWM, mShellInit, mMainExecutor); mController = new DisplayController( mContext, mWM, mShellInit, mMainExecutor, mDisplayManager); } @Test Loading Loading
libs/WindowManager/Shell/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ <uses-permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE" /> <uses-permission android:name="android.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION" /> <uses-permission android:name="android.permission.MANAGE_KEY_GESTURES" /> <uses-permission android:name="android.permission.MANAGE_DISPLAYS" /> <application> <activity Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +26 −4 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.hardware.display.DisplayTopology; import android.os.RemoteException; import android.util.ArraySet; import android.util.Size; Loading @@ -34,6 +35,7 @@ import android.window.WindowContainerTransaction; import androidx.annotation.BinderThread; import com.android.window.flags.Flags; import com.android.wm.shell.common.DisplayChangeController.OnDisplayChangingListener; import com.android.wm.shell.shared.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellInit; Loading @@ -54,6 +56,7 @@ public class DisplayController { private final ShellExecutor mMainExecutor; private final Context mContext; private final IWindowManager mWmService; private final DisplayManager mDisplayManager; private final DisplayChangeController mChangeController; private final IDisplayWindowListener mDisplayContainerListener; Loading @@ -61,10 +64,11 @@ public class DisplayController { private final ArrayList<OnDisplaysChangedListener> mDisplayChangedListeners = new ArrayList<>(); public DisplayController(Context context, IWindowManager wmService, ShellInit shellInit, ShellExecutor mainExecutor) { ShellExecutor mainExecutor, DisplayManager displayManager) { mMainExecutor = mainExecutor; mContext = context; mWmService = wmService; mDisplayManager = displayManager; // TODO: Inject this instead mChangeController = new DisplayChangeController(mWmService, shellInit, mainExecutor); mDisplayContainerListener = new DisplayWindowListenerImpl(); Loading @@ -74,7 +78,7 @@ public class DisplayController { } /** * Initializes the window listener. * Initializes the window listener and the topology listener. */ public void onInit() { try { Loading @@ -82,6 +86,12 @@ public class DisplayController { for (int i = 0; i < displayIds.length; i++) { onDisplayAdded(displayIds[i]); } if (Flags.enableConnectedDisplaysWindowDrag()) { mDisplayManager.registerTopologyListener(mMainExecutor, this::onDisplayTopologyChanged); onDisplayTopologyChanged(mDisplayManager.getDisplayTopology()); } } catch (RemoteException e) { throw new RuntimeException("Unable to register display controller"); } Loading @@ -91,8 +101,7 @@ public class DisplayController { * Gets a display by id from DisplayManager. */ public Display getDisplay(int displayId) { final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); return displayManager.getDisplay(displayId); return mDisplayManager.getDisplay(displayId); } /** Loading Loading @@ -221,6 +230,14 @@ public class DisplayController { } } private void onDisplayTopologyChanged(DisplayTopology topology) { // TODO(b/381472611): Call DisplayTopology#getCoordinates and update values in // DisplayLayout when DM code is ready. for (int i = 0; i < mDisplayChangedListeners.size(); ++i) { mDisplayChangedListeners.get(i).onTopologyChanged(); } } private void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { synchronized (mDisplays) { final DisplayRecord dr = mDisplays.get(displayId); Loading Loading @@ -408,5 +425,10 @@ public class DisplayController { */ default void onKeepClearAreasChanged(int displayId, Set<Rect> restricted, Set<Rect> unrestricted) {} /** * Called when the display topology has changed. */ default void onTopologyChanged() {} } }
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java +66 −4 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.SystemProperties; import android.provider.Settings; import android.util.DisplayMetrics; Loading Loading @@ -71,9 +73,12 @@ public class DisplayLayout { public static final int NAV_BAR_RIGHT = 1 << 1; public static final int NAV_BAR_BOTTOM = 1 << 2; private static final String TAG = "DisplayLayout"; private int mUiMode; private int mWidth; private int mHeight; private RectF mGlobalBoundsDp; private DisplayCutout mCutout; private int mRotation; private int mDensityDpi; Loading Loading @@ -109,6 +114,7 @@ public class DisplayLayout { return mUiMode == other.mUiMode && mWidth == other.mWidth && mHeight == other.mHeight && Objects.equals(mGlobalBoundsDp, other.mGlobalBoundsDp) && Objects.equals(mCutout, other.mCutout) && mRotation == other.mRotation && mDensityDpi == other.mDensityDpi Loading @@ -127,8 +133,8 @@ public class DisplayLayout { @Override public int hashCode() { return Objects.hash(mUiMode, mWidth, mHeight, mCutout, mRotation, mDensityDpi, mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar, return Objects.hash(mUiMode, mWidth, mHeight, mGlobalBoundsDp, mCutout, mRotation, mDensityDpi, mNonDecorInsets, mStableInsets, mHasNavigationBar, mHasStatusBar, mNavBarFrameHeight, mTaskbarFrameHeight, mAllowSeamlessRotationDespiteNavBarMoving, mNavigationBarCanMove, mReverseDefaultRotation, mInsetsState); } Loading Loading @@ -170,6 +176,7 @@ public class DisplayLayout { mUiMode = dl.mUiMode; mWidth = dl.mWidth; mHeight = dl.mHeight; mGlobalBoundsDp = dl.mGlobalBoundsDp; mCutout = dl.mCutout; mRotation = dl.mRotation; mDensityDpi = dl.mDensityDpi; Loading @@ -193,6 +200,7 @@ public class DisplayLayout { mRotation = info.rotation; mCutout = info.displayCutout; mDensityDpi = info.logicalDensityDpi; mGlobalBoundsDp = new RectF(0, 0, pxToDp(mWidth), pxToDp(mHeight)); mHasNavigationBar = hasNavigationBar; mHasStatusBar = hasStatusBar; mAllowSeamlessRotationDespiteNavBarMoving = res.getBoolean( Loading Loading @@ -255,6 +263,11 @@ public class DisplayLayout { recalcInsets(res); } /** Update the global bounds of this layout, in DP. */ public void setGlobalBoundsDp(RectF bounds) { mGlobalBoundsDp = bounds; } /** Get this layout's non-decor insets. */ public Rect nonDecorInsets() { return mNonDecorInsets; Loading @@ -265,16 +278,21 @@ public class DisplayLayout { return mStableInsets; } /** Get this layout's width. */ /** Get this layout's width in pixels. */ public int width() { return mWidth; } /** Get this layout's height. */ /** Get this layout's height in pixels. */ public int height() { return mHeight; } /** Get this layout's global bounds in the multi-display coordinate system in DP. */ public RectF globalBoundsDp() { return mGlobalBoundsDp; } /** Get this layout's display rotation. */ public int rotation() { return mRotation; Loading Loading @@ -486,4 +504,48 @@ public class DisplayLayout { ? R.dimen.navigation_bar_frame_height_landscape : R.dimen.navigation_bar_frame_height); } /** * Converts a pixel value to a density-independent pixel (dp) value. * * @param px The pixel value to convert. * @return The equivalent value in DP units. */ public float pxToDp(Number px) { return px.floatValue() * DisplayMetrics.DENSITY_DEFAULT / mDensityDpi; } /** * Converts a density-independent pixel (dp) value to a pixel value. * * @param dp The DP value to convert. * @return The equivalent value in pixel units. */ public float dpToPx(Number dp) { return dp.floatValue() * mDensityDpi / DisplayMetrics.DENSITY_DEFAULT; } /** * Converts local pixel coordinates on this layout to global DP coordinates. * * @param xPx The x-coordinate in pixels, relative to the layout's origin. * @param yPx The y-coordinate in pixels, relative to the layout's origin. * @return A PointF object representing the coordinates in global DP units. */ public PointF localPxToGlobalDp(Number xPx, Number yPx) { return new PointF(mGlobalBoundsDp.left + pxToDp(xPx), mGlobalBoundsDp.top + pxToDp(yPx)); } /** * Converts global DP coordinates to local pixel coordinates on this layout. * * @param xDp The x-coordinate in global DP units. * @param yDp The y-coordinate in global DP units. * @return A PointF object representing the coordinates in local pixel units on this layout. */ public PointF globalDpToLocalPx(Number xDp, Number yDp) { return new PointF(dpToPx(xDp.floatValue() - mGlobalBoundsDp.left), dpToPx(yDp.floatValue() - mGlobalBoundsDp.top)); } }
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +4 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.annotation.NonNull; import android.app.ActivityTaskManager; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.SystemProperties; import android.provider.Settings; Loading Loading @@ -175,8 +176,9 @@ public abstract class WMShellBaseModule { static DisplayController provideDisplayController(Context context, IWindowManager wmService, ShellInit shellInit, @ShellMainThread ShellExecutor mainExecutor) { return new DisplayController(context, wmService, shellInit, mainExecutor); @ShellMainThread ShellExecutor mainExecutor, DisplayManager displayManager) { return new DisplayController(context, wmService, shellInit, mainExecutor, displayManager); } @WMSingleton Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java +4 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.Context; import android.hardware.display.DisplayManager; import android.view.IWindowManager; import androidx.test.ext.junit.runners.AndroidJUnit4; Loading Loading @@ -50,12 +51,14 @@ public class DisplayControllerTests extends ShellTestCase { private @Mock IWindowManager mWM; private @Mock ShellInit mShellInit; private @Mock ShellExecutor mMainExecutor; private @Mock DisplayManager mDisplayManager; private DisplayController mController; @Before public void setUp() { MockitoAnnotations.initMocks(this); mController = new DisplayController(mContext, mWM, mShellInit, mMainExecutor); mController = new DisplayController( mContext, mWM, mShellInit, mMainExecutor, mDisplayManager); } @Test Loading