Loading core/java/android/content/res/Configuration.java +68 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ package android.content.res; import android.graphics.Point; import android.graphics.Rect; import android.util.DisplayMetrics; import android.view.Display; import android.view.DisplayInfo; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -293,6 +298,16 @@ public final class Configuration implements Parcelable, Comparable<Configuration */ public int screenLayout; /** * @hide * {@link android.graphics.Rect} defining app bounds. The dimensions override usages of * {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at * the display level. Lower levels can override these values to provide custom bounds to enforce * features such as a max aspect ratio. * TODO(b/36812336): Move appBounds out of {@link Configuration}. */ public Rect appBounds; /** @hide */ static public int resetScreenLayout(int curLayout) { return (curLayout&~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK Loading Loading @@ -882,6 +897,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration compatScreenWidthDp = o.compatScreenWidthDp; compatScreenHeightDp = o.compatScreenHeightDp; compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp; setAppBounds(o.appBounds); assetsSeq = o.assetsSeq; seq = o.seq; } Loading Loading @@ -1032,6 +1048,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration case NAVIGATIONHIDDEN_YES: sb.append("/h"); break; default: sb.append("/"); sb.append(navigationHidden); break; } if (appBounds != null) { sb.append(" appBounds="); sb.append(appBounds); } if (assetsSeq != 0) { sb.append(" as.").append(assetsSeq); } Loading Loading @@ -1066,6 +1085,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; densityDpi = DENSITY_DPI_UNDEFINED; assetsSeq = ASSETS_SEQ_UNDEFINED; appBounds = null; seq = 0; } Loading Loading @@ -1253,6 +1273,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp; } if (delta.appBounds != null && !delta.appBounds.equals(appBounds)) { changed |= ActivityInfo.CONFIG_SCREEN_SIZE; setAppBounds(delta.appBounds); } if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED) { changed |= ActivityInfo.CONFIG_ASSETS_PATHS; assetsSeq = delta.assetsSeq; Loading Loading @@ -1399,6 +1423,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration changed |= ActivityInfo.CONFIG_ASSETS_PATHS; } // Make sure that one of the values is not null and that they are not equal. if ((compareUndefined || delta.appBounds != null) && appBounds != delta.appBounds && (appBounds == null || !appBounds.equals(delta.appBounds))) { changed |= ActivityInfo.CONFIG_SCREEN_SIZE; } return changed; } Loading Loading @@ -1494,6 +1525,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration dest.writeInt(compatScreenWidthDp); dest.writeInt(compatScreenHeightDp); dest.writeInt(compatSmallestScreenWidthDp); dest.writeValue(appBounds); dest.writeInt(assetsSeq); dest.writeInt(seq); } Loading Loading @@ -1529,6 +1561,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration compatScreenWidthDp = source.readInt(); compatScreenHeightDp = source.readInt(); compatSmallestScreenWidthDp = source.readInt(); appBounds = (Rect) source.readValue(null); assetsSeq = source.readInt(); seq = source.readInt(); } Loading Loading @@ -1703,6 +1736,33 @@ public final class Configuration implements Parcelable, Comparable<Configuration setLocales(loc == null ? LocaleList.getEmptyLocaleList() : new LocaleList(loc)); } /** * @hide * * Helper method for setting the app bounds. */ public void setAppBounds(Rect rect) { if (rect == null) { appBounds = null; return; } setAppBounds(rect.left, rect.top, rect.right, rect.bottom); } /** * @hide * * Helper method for setting the app bounds. */ public void setAppBounds(int left, int top, int right, int bottom) { if (appBounds == null) { appBounds = new Rect(); } appBounds.set(left, top, right, bottom); } /** * @hide * Loading Loading @@ -2212,6 +2272,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration private static final String XML_ATTR_SCREEN_HEIGHT = "height"; private static final String XML_ATTR_SMALLEST_WIDTH = "sw"; private static final String XML_ATTR_DENSITY = "density"; private static final String XML_ATTR_APP_BOUNDS = "app_bounds"; /** * Reads the attributes corresponding to Configuration member fields from the Xml parser. Loading Loading @@ -2261,6 +2322,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration SMALLEST_SCREEN_WIDTH_DP_UNDEFINED); configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY, DENSITY_DPI_UNDEFINED); configOut.appBounds = Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS)); // For persistence, we don't care about assetsSeq, so do not read it out. } Loading Loading @@ -2332,6 +2395,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi); } if (config.appBounds != null) { XmlUtils.writeStringAttribute(xml, XML_ATTR_APP_BOUNDS, config.appBounds.flattenToString()); } // For persistence, we do not care about assetsSeq, so do not write it out. } } core/java/android/view/DisplayInfo.java +4 −6 Original line number Diff line number Diff line Loading @@ -562,12 +562,10 @@ public final class DisplayInfo implements Parcelable { outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi; outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi; width = (configuration != null && configuration.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) ? (int)((configuration.screenWidthDp * outMetrics.density) + 0.5f) : width; height = (configuration != null && configuration.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) ? (int)((configuration.screenHeightDp * outMetrics.density) + 0.5f) : height; width = configuration != null && configuration.appBounds != null ? configuration.appBounds.width() : width; height = configuration != null && configuration.appBounds != null ? configuration.appBounds.height() : height; outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width; outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; Loading graphics/java/android/graphics/Rect.java +6 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.CheckResult; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import java.io.PrintWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -170,6 +171,10 @@ public final class Rect implements Parcelable { * or null if the string is not of that form. */ public static Rect unflattenFromString(String str) { if (TextUtils.isEmpty(str)) { return null; } Matcher matcher = UnflattenHelper.getMatcher(str); if (!matcher.matches()) { return null; Loading services/core/java/com/android/server/am/ActivityRecord.java +22 −8 Original line number Diff line number Diff line Loading @@ -2122,23 +2122,31 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return true; } /** Computes the override configuration for this activity */ /** * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}. */ // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer. private void computeBounds(Rect outBounds) { outBounds.setEmpty(); final float maxAspectRatio = info.maxAspectRatio; final ActivityStack stack = getStack(); if ((task != null && !task.mFullscreen) || maxAspectRatio == 0 || stack == null) { if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0) { // We don't set override configuration if that activity task isn't fullscreen. I.e. the // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for // the activity. // the activity. This is indicated by an empty {@link outBounds}. return; } stack.getDisplaySize(mTmpPoint); int maxActivityWidth = mTmpPoint.x; int maxActivityHeight = mTmpPoint.y; if (mTmpPoint.x < mTmpPoint.y) { // We must base this on the parent configuration, because we set our override // configuration's appBounds based on the result of this method. If we used our own // configuration, it would be influenced by past invocations. final Configuration configuration = getParent().getConfiguration(); final int containingAppWidth = configuration.appBounds.width(); final int containingAppHeight = configuration.appBounds.height(); int maxActivityWidth = containingAppWidth; int maxActivityHeight = containingAppHeight; if (containingAppWidth < containingAppHeight) { // Width is the shorter side, so we use that to figure-out what the max. height should // be given the aspect ratio. maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f); Loading @@ -2148,8 +2156,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f); } if (mTmpPoint.x <= maxActivityWidth && mTmpPoint.y <= maxActivityHeight) { if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) { // The display matches or is less than the activity aspect ratio, so nothing else to do. // Return the existing bounds. If this method is running for the first time, // {@link mBounds} will be empty (representing no override). If the method has run // before, then effect of {@link mBounds} will already have been applied to the // value returned from {@link getConfiguration}. Refer to // {@link TaskRecord#computeOverrideConfiguration}. outBounds.set(mBounds); return; } Loading services/core/java/com/android/server/am/TaskRecord.java +2 −5 Original line number Diff line number Diff line Loading @@ -2044,6 +2044,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta config.unset(); final Configuration parentConfig = getParent().getConfiguration(); final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; if (mStack != null) { Loading @@ -2052,11 +2053,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density, config, parentConfig); } else { // No stack, give some default values config.smallestScreenWidthDp = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask; config.screenWidthDp = config.screenHeightDp = config.smallestScreenWidthDp; Slog.wtf(TAG, "Expected stack when calculating override config"); throw new IllegalArgumentException("Expected stack when calculating override config"); } config.orientation = (config.screenWidthDp <= config.screenHeightDp) Loading Loading
core/java/android/content/res/Configuration.java +68 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,11 @@ package android.content.res; import android.graphics.Point; import android.graphics.Rect; import android.util.DisplayMetrics; import android.view.Display; import android.view.DisplayInfo; import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -293,6 +298,16 @@ public final class Configuration implements Parcelable, Comparable<Configuration */ public int screenLayout; /** * @hide * {@link android.graphics.Rect} defining app bounds. The dimensions override usages of * {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at * the display level. Lower levels can override these values to provide custom bounds to enforce * features such as a max aspect ratio. * TODO(b/36812336): Move appBounds out of {@link Configuration}. */ public Rect appBounds; /** @hide */ static public int resetScreenLayout(int curLayout) { return (curLayout&~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK Loading Loading @@ -882,6 +897,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration compatScreenWidthDp = o.compatScreenWidthDp; compatScreenHeightDp = o.compatScreenHeightDp; compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp; setAppBounds(o.appBounds); assetsSeq = o.assetsSeq; seq = o.seq; } Loading Loading @@ -1032,6 +1048,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration case NAVIGATIONHIDDEN_YES: sb.append("/h"); break; default: sb.append("/"); sb.append(navigationHidden); break; } if (appBounds != null) { sb.append(" appBounds="); sb.append(appBounds); } if (assetsSeq != 0) { sb.append(" as.").append(assetsSeq); } Loading Loading @@ -1066,6 +1085,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; densityDpi = DENSITY_DPI_UNDEFINED; assetsSeq = ASSETS_SEQ_UNDEFINED; appBounds = null; seq = 0; } Loading Loading @@ -1253,6 +1273,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp; } if (delta.appBounds != null && !delta.appBounds.equals(appBounds)) { changed |= ActivityInfo.CONFIG_SCREEN_SIZE; setAppBounds(delta.appBounds); } if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED) { changed |= ActivityInfo.CONFIG_ASSETS_PATHS; assetsSeq = delta.assetsSeq; Loading Loading @@ -1399,6 +1423,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration changed |= ActivityInfo.CONFIG_ASSETS_PATHS; } // Make sure that one of the values is not null and that they are not equal. if ((compareUndefined || delta.appBounds != null) && appBounds != delta.appBounds && (appBounds == null || !appBounds.equals(delta.appBounds))) { changed |= ActivityInfo.CONFIG_SCREEN_SIZE; } return changed; } Loading Loading @@ -1494,6 +1525,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration dest.writeInt(compatScreenWidthDp); dest.writeInt(compatScreenHeightDp); dest.writeInt(compatSmallestScreenWidthDp); dest.writeValue(appBounds); dest.writeInt(assetsSeq); dest.writeInt(seq); } Loading Loading @@ -1529,6 +1561,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration compatScreenWidthDp = source.readInt(); compatScreenHeightDp = source.readInt(); compatSmallestScreenWidthDp = source.readInt(); appBounds = (Rect) source.readValue(null); assetsSeq = source.readInt(); seq = source.readInt(); } Loading Loading @@ -1703,6 +1736,33 @@ public final class Configuration implements Parcelable, Comparable<Configuration setLocales(loc == null ? LocaleList.getEmptyLocaleList() : new LocaleList(loc)); } /** * @hide * * Helper method for setting the app bounds. */ public void setAppBounds(Rect rect) { if (rect == null) { appBounds = null; return; } setAppBounds(rect.left, rect.top, rect.right, rect.bottom); } /** * @hide * * Helper method for setting the app bounds. */ public void setAppBounds(int left, int top, int right, int bottom) { if (appBounds == null) { appBounds = new Rect(); } appBounds.set(left, top, right, bottom); } /** * @hide * Loading Loading @@ -2212,6 +2272,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration private static final String XML_ATTR_SCREEN_HEIGHT = "height"; private static final String XML_ATTR_SMALLEST_WIDTH = "sw"; private static final String XML_ATTR_DENSITY = "density"; private static final String XML_ATTR_APP_BOUNDS = "app_bounds"; /** * Reads the attributes corresponding to Configuration member fields from the Xml parser. Loading Loading @@ -2261,6 +2322,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration SMALLEST_SCREEN_WIDTH_DP_UNDEFINED); configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY, DENSITY_DPI_UNDEFINED); configOut.appBounds = Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS)); // For persistence, we don't care about assetsSeq, so do not read it out. } Loading Loading @@ -2332,6 +2395,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi); } if (config.appBounds != null) { XmlUtils.writeStringAttribute(xml, XML_ATTR_APP_BOUNDS, config.appBounds.flattenToString()); } // For persistence, we do not care about assetsSeq, so do not write it out. } }
core/java/android/view/DisplayInfo.java +4 −6 Original line number Diff line number Diff line Loading @@ -562,12 +562,10 @@ public final class DisplayInfo implements Parcelable { outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi; outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi; width = (configuration != null && configuration.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) ? (int)((configuration.screenWidthDp * outMetrics.density) + 0.5f) : width; height = (configuration != null && configuration.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) ? (int)((configuration.screenHeightDp * outMetrics.density) + 0.5f) : height; width = configuration != null && configuration.appBounds != null ? configuration.appBounds.width() : width; height = configuration != null && configuration.appBounds != null ? configuration.appBounds.height() : height; outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width; outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; Loading
graphics/java/android/graphics/Rect.java +6 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.CheckResult; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import java.io.PrintWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -170,6 +171,10 @@ public final class Rect implements Parcelable { * or null if the string is not of that form. */ public static Rect unflattenFromString(String str) { if (TextUtils.isEmpty(str)) { return null; } Matcher matcher = UnflattenHelper.getMatcher(str); if (!matcher.matches()) { return null; Loading
services/core/java/com/android/server/am/ActivityRecord.java +22 −8 Original line number Diff line number Diff line Loading @@ -2122,23 +2122,31 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo return true; } /** Computes the override configuration for this activity */ /** * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}. */ // TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer. private void computeBounds(Rect outBounds) { outBounds.setEmpty(); final float maxAspectRatio = info.maxAspectRatio; final ActivityStack stack = getStack(); if ((task != null && !task.mFullscreen) || maxAspectRatio == 0 || stack == null) { if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0) { // We don't set override configuration if that activity task isn't fullscreen. I.e. the // activity is in multi-window mode. Or, there isn't a max aspect ratio specified for // the activity. // the activity. This is indicated by an empty {@link outBounds}. return; } stack.getDisplaySize(mTmpPoint); int maxActivityWidth = mTmpPoint.x; int maxActivityHeight = mTmpPoint.y; if (mTmpPoint.x < mTmpPoint.y) { // We must base this on the parent configuration, because we set our override // configuration's appBounds based on the result of this method. If we used our own // configuration, it would be influenced by past invocations. final Configuration configuration = getParent().getConfiguration(); final int containingAppWidth = configuration.appBounds.width(); final int containingAppHeight = configuration.appBounds.height(); int maxActivityWidth = containingAppWidth; int maxActivityHeight = containingAppHeight; if (containingAppWidth < containingAppHeight) { // Width is the shorter side, so we use that to figure-out what the max. height should // be given the aspect ratio. maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f); Loading @@ -2148,8 +2156,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f); } if (mTmpPoint.x <= maxActivityWidth && mTmpPoint.y <= maxActivityHeight) { if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) { // The display matches or is less than the activity aspect ratio, so nothing else to do. // Return the existing bounds. If this method is running for the first time, // {@link mBounds} will be empty (representing no override). If the method has run // before, then effect of {@link mBounds} will already have been applied to the // value returned from {@link getConfiguration}. Refer to // {@link TaskRecord#computeOverrideConfiguration}. outBounds.set(mBounds); return; } Loading
services/core/java/com/android/server/am/TaskRecord.java +2 −5 Original line number Diff line number Diff line Loading @@ -2044,6 +2044,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta config.unset(); final Configuration parentConfig = getParent().getConfiguration(); final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; if (mStack != null) { Loading @@ -2052,11 +2053,7 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density, config, parentConfig); } else { // No stack, give some default values config.smallestScreenWidthDp = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask; config.screenWidthDp = config.screenHeightDp = config.smallestScreenWidthDp; Slog.wtf(TAG, "Expected stack when calculating override config"); throw new IllegalArgumentException("Expected stack when calculating override config"); } config.orientation = (config.screenWidthDp <= config.screenHeightDp) Loading