Loading packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java +189 −105 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settingslib.display; import android.content.Context; import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.os.AsyncTask; import android.os.RemoteException; import android.os.UserHandle; Loading @@ -32,6 +33,9 @@ import android.view.WindowManagerGlobal; import com.android.settingslib.R; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.function.Predicate; /** * Utility methods for working with display density. Loading Loading @@ -70,33 +74,78 @@ public class DisplayDensityUtils { */ private static final int MIN_DIMENSION_DP = 320; private final String[] mEntries; private final int[] mValues; private static final Predicate<DisplayInfo> INTERNAL_ONLY = (info) -> info.type == Display.TYPE_INTERNAL; private final int mDefaultDensity; private final int mCurrentIndex; private final Predicate<DisplayInfo> mPredicate; private final DisplayManager mDisplayManager; /** * The text description of the density values of the default display. */ private String[] mDefaultDisplayDensityEntries; /** * The density values of the default display. */ private int[] mDefaultDisplayDensityValues; /** * The density values, indexed by display unique ID. */ private final Map<String, int[]> mValuesPerDisplay = new HashMap(); private int mDefaultDensityForDefaultDisplay; private int mCurrentIndex = -1; public DisplayDensityUtils(Context context) { final int defaultDensity = DisplayDensityUtils.getDefaultDisplayDensity( Display.DEFAULT_DISPLAY); this(context, INTERNAL_ONLY); } /** * Creates an instance that stores the density values for the displays that satisfy * the predicate. * @param context The context * @param predicate Determines what displays the density should be set for. The default display * must satisfy this predicate. */ public DisplayDensityUtils(Context context, Predicate predicate) { mPredicate = predicate; mDisplayManager = context.getSystemService(DisplayManager.class); for (Display display : mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) { DisplayInfo info = new DisplayInfo(); if (!display.getDisplayInfo(info)) { Log.w(LOG_TAG, "Cannot fetch display info for display " + display.getDisplayId()); continue; } if (!mPredicate.test(info)) { if (display.getDisplayId() == Display.DEFAULT_DISPLAY) { throw new IllegalArgumentException("Predicate must not filter out the default " + "display."); } continue; } final int defaultDensity = DisplayDensityUtils.getDefaultDensityForDisplay( display.getDisplayId()); if (defaultDensity <= 0) { mEntries = null; mValues = null; mDefaultDensity = 0; mCurrentIndex = -1; return; Log.w(LOG_TAG, "Cannot fetch default density for display " + display.getDisplayId()); continue; } final Resources res = context.getResources(); DisplayInfo info = new DisplayInfo(); context.getDisplayNoVerify().getDisplayInfo(info); final int currentDensity = info.logicalDensityDpi; int currentDensityIndex = -1; // Compute number of "larger" and "smaller" scales for this display. final int minDimensionPx = Math.min(info.logicalWidth, info.logicalHeight); final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP; final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP; final float maxScaleDimen = context.getResources().getFraction( R.fraction.display_density_max_scale, 1, 1); final float maxScale = Math.min(maxScaleDimen, maxDensity / (float) defaultDensity); Loading Loading @@ -164,26 +213,30 @@ public class DisplayDensityUtils { displayIndex = curIndex; } mDefaultDensity = defaultDensity; if (display.getDisplayId() == Display.DEFAULT_DISPLAY) { mDefaultDensityForDefaultDisplay = defaultDensity; mCurrentIndex = displayIndex; mEntries = entries; mValues = values; mDefaultDisplayDensityEntries = entries; mDefaultDisplayDensityValues = values; } mValuesPerDisplay.put(info.uniqueId, values); } } public String[] getEntries() { return mEntries; public String[] getDefaultDisplayDensityEntries() { return mDefaultDisplayDensityEntries; } public int[] getValues() { return mValues; public int[] getDefaultDisplayDensityValues() { return mDefaultDisplayDensityValues; } public int getCurrentIndex() { public int getCurrentIndexForDefaultDisplay() { return mCurrentIndex; } public int getDefaultDensity() { return mDefaultDensity; public int getDefaultDensityForDefaultDisplay() { return mDefaultDensityForDefaultDisplay; } /** Loading @@ -193,7 +246,7 @@ public class DisplayDensityUtils { * @return the default density of the specified display, or {@code -1} if * the display does not exist or the density could not be obtained */ private static int getDefaultDisplayDensity(int displayId) { private static int getDefaultDensityForDisplay(int displayId) { try { final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); return wm.getInitialDisplayDensity(displayId); Loading @@ -203,19 +256,31 @@ public class DisplayDensityUtils { } /** * Asynchronously applies display density changes to the specified display. * Asynchronously applies display density changes to the displays that satisfy the predicate. * <p> * The change will be applied to the user specified by the value of * {@link UserHandle#myUserId()} at the time the method is called. * * @param displayId the identifier of the display to modify */ public static void clearForcedDisplayDensity(final int displayId) { public void clearForcedDisplayDensity() { final int userId = UserHandle.myUserId(); AsyncTask.execute(() -> { try { for (Display display : mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) { int displayId = display.getDisplayId(); DisplayInfo info = new DisplayInfo(); if (!display.getDisplayInfo(info)) { Log.w(LOG_TAG, "Unable to clear forced display density setting " + "for display " + displayId); continue; } if (!mPredicate.test(info)) { continue; } final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); wm.clearForcedDisplayDensityForUser(displayId, userId); } } catch (RemoteException exc) { Log.w(LOG_TAG, "Unable to clear forced display density setting"); } Loading @@ -223,20 +288,39 @@ public class DisplayDensityUtils { } /** * Asynchronously applies display density changes to the specified display. * Asynchronously applies display density changes to the displays that satisfy the predicate. * <p> * The change will be applied to the user specified by the value of * {@link UserHandle#myUserId()} at the time the method is called. * * @param displayId the identifier of the display to modify * @param density the density to force for the specified display * @param index The index of the density value */ public static void setForcedDisplayDensity(final int displayId, final int density) { public void setForcedDisplayDensity(final int index) { final int userId = UserHandle.myUserId(); AsyncTask.execute(() -> { try { for (Display display : mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) { int displayId = display.getDisplayId(); DisplayInfo info = new DisplayInfo(); if (!display.getDisplayInfo(info)) { Log.w(LOG_TAG, "Unable to save forced display density setting " + "for display " + displayId); continue; } if (!mPredicate.test(info)) { continue; } if (!mValuesPerDisplay.containsKey(info.uniqueId)) { Log.w(LOG_TAG, "Unable to save forced display density setting " + "for display " + info.uniqueId); continue; } final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); wm.setForcedDisplayDensityForUser(displayId, density, userId); wm.setForcedDisplayDensityForUser(displayId, mValuesPerDisplay.get(info.uniqueId)[index], userId); } } catch (RemoteException exc) { Log.w(LOG_TAG, "Unable to save forced display density setting"); } Loading services/core/java/com/android/server/wm/DisplayContent.java +1 −1 Original line number Diff line number Diff line Loading @@ -2974,7 +2974,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (density == mInitialDisplayDensity) { density = 0; } mWmService.mDisplayWindowSettings.setForcedDensity(this, density, userId); mWmService.mDisplayWindowSettings.setForcedDensity(getDisplayInfo(), density, userId); } /** @param mode {@link #FORCE_SCALING_MODE_AUTO} or {@link #FORCE_SCALING_MODE_DISABLED}. */ Loading services/core/java/com/android/server/wm/DisplayWindowSettings.java +3 −3 Original line number Diff line number Diff line Loading @@ -77,14 +77,14 @@ class DisplayWindowSettings { mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings); } void setForcedDensity(DisplayContent displayContent, int density, int userId) { if (displayContent.isDefaultDisplay) { void setForcedDensity(DisplayInfo info, int density, int userId) { if (info.displayId == Display.DEFAULT_DISPLAY) { final String densityString = density == 0 ? "" : Integer.toString(density); Settings.Secure.putStringForUser(mService.mContext.getContentResolver(), Settings.Secure.DISPLAY_DENSITY_FORCED, densityString, userId); } final DisplayInfo displayInfo = displayContent.getDisplayInfo(); final DisplayInfo displayInfo = info; final SettingsProvider.SettingsEntry overrideSettings = mSettingsProvider.getOverrideSettings(displayInfo); overrideSettings.mForcedDensity = density; Loading services/core/java/com/android/server/wm/WindowManagerService.java +16 −2 Original line number Diff line number Diff line Loading @@ -167,7 +167,6 @@ import android.app.IActivityManager; import android.app.IAssistDataReceiver; import android.app.WindowConfiguration; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading @@ -177,7 +176,6 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.TestUtilityService; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.database.ContentObserver; import android.graphics.Bitmap; Loading Loading @@ -5839,6 +5837,11 @@ public class WindowManagerService extends IWindowManager.Stub if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { return displayContent.mInitialDisplayDensity; } DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId); if (info != null && info.hasAccess(Binder.getCallingUid())) { return info.logicalDensityDpi; } } return -1; } Loading Loading @@ -5870,6 +5873,11 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent != null) { displayContent.setForcedDensity(density, targetUserId); } else { DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId); if (info != null) { mDisplayWindowSettings.setForcedDensity(info, density, userId); } } } } finally { Loading @@ -5894,6 +5902,12 @@ public class WindowManagerService extends IWindowManager.Stub if (displayContent != null) { displayContent.setForcedDensity(displayContent.mInitialDisplayDensity, callingUserId); } else { DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId); if (info != null) { mDisplayWindowSettings.setForcedDensity(info, info.logicalDensityDpi, userId); } } } } finally { Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -2064,7 +2064,8 @@ public class DisplayContentTests extends WindowTestsBase { // Update the forced size and density in settings and the unique id to simualate a display // remap. dc.mWmService.mDisplayWindowSettings.setForcedSize(dc, forcedWidth, forcedHeight); dc.mWmService.mDisplayWindowSettings.setForcedDensity(dc, forcedDensity, 0 /* userId */); dc.mWmService.mDisplayWindowSettings.setForcedDensity(displayInfo, forcedDensity, 0 /* userId */); dc.mCurrentUniqueDisplayId = mDisplayInfo.uniqueId + "-test"; // Trigger display changed. dc.onDisplayChanged(); Loading Loading
packages/SettingsLib/src/com/android/settingslib/display/DisplayDensityUtils.java +189 −105 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settingslib.display; import android.content.Context; import android.content.res.Resources; import android.hardware.display.DisplayManager; import android.os.AsyncTask; import android.os.RemoteException; import android.os.UserHandle; Loading @@ -32,6 +33,9 @@ import android.view.WindowManagerGlobal; import com.android.settingslib.R; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.function.Predicate; /** * Utility methods for working with display density. Loading Loading @@ -70,33 +74,78 @@ public class DisplayDensityUtils { */ private static final int MIN_DIMENSION_DP = 320; private final String[] mEntries; private final int[] mValues; private static final Predicate<DisplayInfo> INTERNAL_ONLY = (info) -> info.type == Display.TYPE_INTERNAL; private final int mDefaultDensity; private final int mCurrentIndex; private final Predicate<DisplayInfo> mPredicate; private final DisplayManager mDisplayManager; /** * The text description of the density values of the default display. */ private String[] mDefaultDisplayDensityEntries; /** * The density values of the default display. */ private int[] mDefaultDisplayDensityValues; /** * The density values, indexed by display unique ID. */ private final Map<String, int[]> mValuesPerDisplay = new HashMap(); private int mDefaultDensityForDefaultDisplay; private int mCurrentIndex = -1; public DisplayDensityUtils(Context context) { final int defaultDensity = DisplayDensityUtils.getDefaultDisplayDensity( Display.DEFAULT_DISPLAY); this(context, INTERNAL_ONLY); } /** * Creates an instance that stores the density values for the displays that satisfy * the predicate. * @param context The context * @param predicate Determines what displays the density should be set for. The default display * must satisfy this predicate. */ public DisplayDensityUtils(Context context, Predicate predicate) { mPredicate = predicate; mDisplayManager = context.getSystemService(DisplayManager.class); for (Display display : mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) { DisplayInfo info = new DisplayInfo(); if (!display.getDisplayInfo(info)) { Log.w(LOG_TAG, "Cannot fetch display info for display " + display.getDisplayId()); continue; } if (!mPredicate.test(info)) { if (display.getDisplayId() == Display.DEFAULT_DISPLAY) { throw new IllegalArgumentException("Predicate must not filter out the default " + "display."); } continue; } final int defaultDensity = DisplayDensityUtils.getDefaultDensityForDisplay( display.getDisplayId()); if (defaultDensity <= 0) { mEntries = null; mValues = null; mDefaultDensity = 0; mCurrentIndex = -1; return; Log.w(LOG_TAG, "Cannot fetch default density for display " + display.getDisplayId()); continue; } final Resources res = context.getResources(); DisplayInfo info = new DisplayInfo(); context.getDisplayNoVerify().getDisplayInfo(info); final int currentDensity = info.logicalDensityDpi; int currentDensityIndex = -1; // Compute number of "larger" and "smaller" scales for this display. final int minDimensionPx = Math.min(info.logicalWidth, info.logicalHeight); final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP; final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP; final float maxScaleDimen = context.getResources().getFraction( R.fraction.display_density_max_scale, 1, 1); final float maxScale = Math.min(maxScaleDimen, maxDensity / (float) defaultDensity); Loading Loading @@ -164,26 +213,30 @@ public class DisplayDensityUtils { displayIndex = curIndex; } mDefaultDensity = defaultDensity; if (display.getDisplayId() == Display.DEFAULT_DISPLAY) { mDefaultDensityForDefaultDisplay = defaultDensity; mCurrentIndex = displayIndex; mEntries = entries; mValues = values; mDefaultDisplayDensityEntries = entries; mDefaultDisplayDensityValues = values; } mValuesPerDisplay.put(info.uniqueId, values); } } public String[] getEntries() { return mEntries; public String[] getDefaultDisplayDensityEntries() { return mDefaultDisplayDensityEntries; } public int[] getValues() { return mValues; public int[] getDefaultDisplayDensityValues() { return mDefaultDisplayDensityValues; } public int getCurrentIndex() { public int getCurrentIndexForDefaultDisplay() { return mCurrentIndex; } public int getDefaultDensity() { return mDefaultDensity; public int getDefaultDensityForDefaultDisplay() { return mDefaultDensityForDefaultDisplay; } /** Loading @@ -193,7 +246,7 @@ public class DisplayDensityUtils { * @return the default density of the specified display, or {@code -1} if * the display does not exist or the density could not be obtained */ private static int getDefaultDisplayDensity(int displayId) { private static int getDefaultDensityForDisplay(int displayId) { try { final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); return wm.getInitialDisplayDensity(displayId); Loading @@ -203,19 +256,31 @@ public class DisplayDensityUtils { } /** * Asynchronously applies display density changes to the specified display. * Asynchronously applies display density changes to the displays that satisfy the predicate. * <p> * The change will be applied to the user specified by the value of * {@link UserHandle#myUserId()} at the time the method is called. * * @param displayId the identifier of the display to modify */ public static void clearForcedDisplayDensity(final int displayId) { public void clearForcedDisplayDensity() { final int userId = UserHandle.myUserId(); AsyncTask.execute(() -> { try { for (Display display : mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) { int displayId = display.getDisplayId(); DisplayInfo info = new DisplayInfo(); if (!display.getDisplayInfo(info)) { Log.w(LOG_TAG, "Unable to clear forced display density setting " + "for display " + displayId); continue; } if (!mPredicate.test(info)) { continue; } final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); wm.clearForcedDisplayDensityForUser(displayId, userId); } } catch (RemoteException exc) { Log.w(LOG_TAG, "Unable to clear forced display density setting"); } Loading @@ -223,20 +288,39 @@ public class DisplayDensityUtils { } /** * Asynchronously applies display density changes to the specified display. * Asynchronously applies display density changes to the displays that satisfy the predicate. * <p> * The change will be applied to the user specified by the value of * {@link UserHandle#myUserId()} at the time the method is called. * * @param displayId the identifier of the display to modify * @param density the density to force for the specified display * @param index The index of the density value */ public static void setForcedDisplayDensity(final int displayId, final int density) { public void setForcedDisplayDensity(final int index) { final int userId = UserHandle.myUserId(); AsyncTask.execute(() -> { try { for (Display display : mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)) { int displayId = display.getDisplayId(); DisplayInfo info = new DisplayInfo(); if (!display.getDisplayInfo(info)) { Log.w(LOG_TAG, "Unable to save forced display density setting " + "for display " + displayId); continue; } if (!mPredicate.test(info)) { continue; } if (!mValuesPerDisplay.containsKey(info.uniqueId)) { Log.w(LOG_TAG, "Unable to save forced display density setting " + "for display " + info.uniqueId); continue; } final IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); wm.setForcedDisplayDensityForUser(displayId, density, userId); wm.setForcedDisplayDensityForUser(displayId, mValuesPerDisplay.get(info.uniqueId)[index], userId); } } catch (RemoteException exc) { Log.w(LOG_TAG, "Unable to save forced display density setting"); } Loading
services/core/java/com/android/server/wm/DisplayContent.java +1 −1 Original line number Diff line number Diff line Loading @@ -2974,7 +2974,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (density == mInitialDisplayDensity) { density = 0; } mWmService.mDisplayWindowSettings.setForcedDensity(this, density, userId); mWmService.mDisplayWindowSettings.setForcedDensity(getDisplayInfo(), density, userId); } /** @param mode {@link #FORCE_SCALING_MODE_AUTO} or {@link #FORCE_SCALING_MODE_DISABLED}. */ Loading
services/core/java/com/android/server/wm/DisplayWindowSettings.java +3 −3 Original line number Diff line number Diff line Loading @@ -77,14 +77,14 @@ class DisplayWindowSettings { mSettingsProvider.updateOverrideSettings(displayInfo, overrideSettings); } void setForcedDensity(DisplayContent displayContent, int density, int userId) { if (displayContent.isDefaultDisplay) { void setForcedDensity(DisplayInfo info, int density, int userId) { if (info.displayId == Display.DEFAULT_DISPLAY) { final String densityString = density == 0 ? "" : Integer.toString(density); Settings.Secure.putStringForUser(mService.mContext.getContentResolver(), Settings.Secure.DISPLAY_DENSITY_FORCED, densityString, userId); } final DisplayInfo displayInfo = displayContent.getDisplayInfo(); final DisplayInfo displayInfo = info; final SettingsProvider.SettingsEntry overrideSettings = mSettingsProvider.getOverrideSettings(displayInfo); overrideSettings.mForcedDensity = density; Loading
services/core/java/com/android/server/wm/WindowManagerService.java +16 −2 Original line number Diff line number Diff line Loading @@ -167,7 +167,6 @@ import android.app.IActivityManager; import android.app.IAssistDataReceiver; import android.app.WindowConfiguration; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading @@ -177,7 +176,6 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.content.pm.TestUtilityService; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.database.ContentObserver; import android.graphics.Bitmap; Loading Loading @@ -5839,6 +5837,11 @@ public class WindowManagerService extends IWindowManager.Stub if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { return displayContent.mInitialDisplayDensity; } DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId); if (info != null && info.hasAccess(Binder.getCallingUid())) { return info.logicalDensityDpi; } } return -1; } Loading Loading @@ -5870,6 +5873,11 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent displayContent = mRoot.getDisplayContent(displayId); if (displayContent != null) { displayContent.setForcedDensity(density, targetUserId); } else { DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId); if (info != null) { mDisplayWindowSettings.setForcedDensity(info, density, userId); } } } } finally { Loading @@ -5894,6 +5902,12 @@ public class WindowManagerService extends IWindowManager.Stub if (displayContent != null) { displayContent.setForcedDensity(displayContent.mInitialDisplayDensity, callingUserId); } else { DisplayInfo info = mDisplayManagerInternal.getDisplayInfo(displayId); if (info != null) { mDisplayWindowSettings.setForcedDensity(info, info.logicalDensityDpi, userId); } } } } finally { Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -2064,7 +2064,8 @@ public class DisplayContentTests extends WindowTestsBase { // Update the forced size and density in settings and the unique id to simualate a display // remap. dc.mWmService.mDisplayWindowSettings.setForcedSize(dc, forcedWidth, forcedHeight); dc.mWmService.mDisplayWindowSettings.setForcedDensity(dc, forcedDensity, 0 /* userId */); dc.mWmService.mDisplayWindowSettings.setForcedDensity(displayInfo, forcedDensity, 0 /* userId */); dc.mCurrentUniqueDisplayId = mDisplayInfo.uniqueId + "-test"; // Trigger display changed. dc.onDisplayChanged(); Loading