diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-05-26 14:20:23 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-05-26 14:48:04 -0700 |
commit | df6e980e3f63eb0f6f9eb437fa925d5009cd9c44 (patch) | |
tree | 5440eeb979427cf2d0be09e067b0dd5c0d62a943 /core | |
parent | 7a09f72b8850ec22e4ca7fd50aba20ead7666f67 (diff) | |
download | frameworks_base-df6e980e3f63eb0f6f9eb437fa925d5009cd9c44.zip frameworks_base-df6e980e3f63eb0f6f9eb437fa925d5009cd9c44.tar.gz frameworks_base-df6e980e3f63eb0f6f9eb437fa925d5009cd9c44.tar.bz2 |
Add new supports-screens attributes for declaring the compatible screens.
Change-Id: I40d57e4354e48accc1027c9f90916ea73eb5190d
android:requiresSmallestWidthDp provides the smallest supported width.
android:compatibleWidthLimitDp provides the largest compatible width.
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/app/ActivityThread.java | 2 | ||||
-rw-r--r-- | core/java/android/content/pm/ApplicationInfo.java | 24 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 7 | ||||
-rw-r--r-- | core/java/android/content/res/CompatibilityInfo.java | 160 | ||||
-rw-r--r-- | core/res/res/values/attrs_manifest.xml | 24 | ||||
-rw-r--r-- | core/res/res/values/public.xml | 12 |
6 files changed, 159 insertions, 70 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 6c8f85f..d30010a 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1525,7 +1525,7 @@ public final class ActivityThread { synchronized (this) { ContextImpl context = getSystemContext(); context.init(new LoadedApk(this, "android", context, info, - new CompatibilityInfo(info, 0, false)), null, this); + new CompatibilityInfo(info, 0, 0, false)), null, this); } } diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 92b2c3b..ab31865 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -321,6 +321,22 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public int flags = 0; /** + * The required smallest screen width the application can run on. If 0, + * nothing has been specified. Comes from + * {@link android.R.styleable#AndroidManifestSupportsScreens_requiresSmallestWidthDp + * android:requiresSmallestWidthDp} attribute of the <supports-screens> tag. + */ + public int requiresSmallestWidthDp = 0; + + /** + * The maximum smallest screen width the application is designed for. If 0, + * nothing has been specified. Comes from + * {@link android.R.styleable#AndroidManifestSupportsScreens_compatibleWidthLimitDp + * android:compatibleWidthLimitDp} attribute of the <supports-screens> tag. + */ + public int compatibleWidthLimitDp = 0; + + /** * Full path to the location of this package. */ public String sourceDir; @@ -401,6 +417,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { pw.println(prefix + "taskAffinity=" + taskAffinity); pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags) + " theme=0x" + Integer.toHexString(theme)); + pw.println(prefix + "requiresSmallestWidthDp=" + requiresSmallestWidthDp + + " compatibleWidthLimitDp=" + compatibleWidthLimitDp); pw.println(prefix + "sourceDir=" + sourceDir); if (sourceDir == null) { if (publicSourceDir != null) { @@ -460,6 +478,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { className = orig.className; theme = orig.theme; flags = orig.flags; + requiresSmallestWidthDp = orig.requiresSmallestWidthDp; + compatibleWidthLimitDp = orig.compatibleWidthLimitDp; sourceDir = orig.sourceDir; publicSourceDir = orig.publicSourceDir; nativeLibraryDir = orig.nativeLibraryDir; @@ -493,6 +513,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString(className); dest.writeInt(theme); dest.writeInt(flags); + dest.writeInt(requiresSmallestWidthDp); + dest.writeInt(compatibleWidthLimitDp); dest.writeString(sourceDir); dest.writeString(publicSourceDir); dest.writeString(nativeLibraryDir); @@ -526,6 +548,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { className = source.readString(); theme = source.readInt(); flags = source.readInt(); + requiresSmallestWidthDp = source.readInt(); + compatibleWidthLimitDp = source.readInt(); sourceDir = source.readString(); publicSourceDir = source.readString(); nativeLibraryDir = source.readString(); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 10799a4..42e24f9 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -993,6 +993,13 @@ public class PackageParser { sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestSupportsScreens); + pkg.applicationInfo.requiresSmallestWidthDp = sa.getInteger( + com.android.internal.R.styleable.AndroidManifestSupportsScreens_requiresSmallestWidthDp, + 0); + pkg.applicationInfo.compatibleWidthLimitDp = sa.getInteger( + com.android.internal.R.styleable.AndroidManifestSupportsScreens_compatibleWidthLimitDp, + 0); + // This is a trick to get a boolean and still able to detect // if a value was actually set. supportsSmallScreens = sa.getInteger( diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 8d725cd..c151e32 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -110,86 +110,112 @@ public class CompatibilityInfo implements Parcelable { */ public final float applicationInvertedScale; - public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, boolean forceCompat) { + public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw, + boolean forceCompat) { int compatFlags = 0; - // We can't rely on the application always setting - // FLAG_RESIZEABLE_FOR_SCREENS so will compute it based on various input. - boolean anyResizeable = false; - - if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { - compatFlags |= LARGE_SCREENS; - anyResizeable = true; - if (!forceCompat) { - // If we aren't forcing the app into compatibility mode, then - // assume if it supports large screens that we should allow it - // to use the full space of an xlarge screen as well. - compatFlags |= XLARGE_SCREENS | EXPANDABLE; + if (appInfo.requiresSmallestWidthDp != 0 || appInfo.compatibleWidthLimitDp != 0) { + // New style screen requirements spec. + int required = appInfo.requiresSmallestWidthDp != 0 + ? appInfo.requiresSmallestWidthDp + : appInfo.compatibleWidthLimitDp; + int compat = appInfo.compatibleWidthLimitDp != 0 + ? appInfo.compatibleWidthLimitDp + : appInfo.requiresSmallestWidthDp; + if (compat < required) { + compat = required; } - } - if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { - anyResizeable = true; - if (!forceCompat) { - compatFlags |= XLARGE_SCREENS | EXPANDABLE; + + if (compat >= sw) { + compatFlags |= NEVER_COMPAT; + } else if (forceCompat) { + compatFlags |= NEEDS_SCREEN_COMPAT; } - } - if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { - anyResizeable = true; - compatFlags |= EXPANDABLE; - } - if (forceCompat) { - // If we are forcing compatibility mode, then ignore an app that - // just says it is resizable for screens. We'll only have it fill - // the screen if it explicitly says it supports the screen size we - // are running in. - compatFlags &= ~EXPANDABLE; - } + // Modern apps always support densities. + applicationDensity = DisplayMetrics.DENSITY_DEVICE; + applicationScale = 1.0f; + applicationInvertedScale = 1.0f; - boolean supportsScreen = false; - switch (screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) { - case Configuration.SCREENLAYOUT_SIZE_XLARGE: - if ((compatFlags&XLARGE_SCREENS) != 0) { - supportsScreen = true; + } else { + // We can't rely on the application always setting + // FLAG_RESIZEABLE_FOR_SCREENS so will compute it based on various input. + boolean anyResizeable = false; + + if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { + compatFlags |= LARGE_SCREENS; + anyResizeable = true; + if (!forceCompat) { + // If we aren't forcing the app into compatibility mode, then + // assume if it supports large screens that we should allow it + // to use the full space of an xlarge screen as well. + compatFlags |= XLARGE_SCREENS | EXPANDABLE; } - if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { - compatFlags |= NEVER_COMPAT; + } + if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { + anyResizeable = true; + if (!forceCompat) { + compatFlags |= XLARGE_SCREENS | EXPANDABLE; } - break; - case Configuration.SCREENLAYOUT_SIZE_LARGE: - if ((compatFlags&LARGE_SCREENS) != 0) { + } + if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) { + anyResizeable = true; + compatFlags |= EXPANDABLE; + } + + if (forceCompat) { + // If we are forcing compatibility mode, then ignore an app that + // just says it is resizable for screens. We'll only have it fill + // the screen if it explicitly says it supports the screen size we + // are running in. + compatFlags &= ~EXPANDABLE; + } + + boolean supportsScreen = false; + switch (screenLayout&Configuration.SCREENLAYOUT_SIZE_MASK) { + case Configuration.SCREENLAYOUT_SIZE_XLARGE: + if ((compatFlags&XLARGE_SCREENS) != 0) { + supportsScreen = true; + } + if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { + compatFlags |= NEVER_COMPAT; + } + break; + case Configuration.SCREENLAYOUT_SIZE_LARGE: + if ((compatFlags&LARGE_SCREENS) != 0) { + supportsScreen = true; + } + if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { + compatFlags |= NEVER_COMPAT; + } + break; + } + + if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) { + if ((compatFlags&EXPANDABLE) != 0) { supportsScreen = true; + } else if (!anyResizeable) { + compatFlags |= ALWAYS_COMPAT; } - if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { - compatFlags |= NEVER_COMPAT; - } - break; - } + } - if ((screenLayout&Configuration.SCREENLAYOUT_COMPAT_NEEDED) != 0) { - if ((compatFlags&EXPANDABLE) != 0) { - supportsScreen = true; - } else if (!anyResizeable) { - compatFlags |= ALWAYS_COMPAT; + if (supportsScreen) { + compatFlags &= ~NEEDS_SCREEN_COMPAT; + } else { + compatFlags |= NEEDS_SCREEN_COMPAT; } - } - if (supportsScreen) { - compatFlags &= ~NEEDS_SCREEN_COMPAT; - } else { - compatFlags |= NEEDS_SCREEN_COMPAT; - } - - if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { - applicationDensity = DisplayMetrics.DENSITY_DEVICE; - applicationScale = 1.0f; - applicationInvertedScale = 1.0f; - } else { - applicationDensity = DisplayMetrics.DENSITY_DEFAULT; - applicationScale = DisplayMetrics.DENSITY_DEVICE - / (float) DisplayMetrics.DENSITY_DEFAULT; - applicationInvertedScale = 1.0f / applicationScale; - compatFlags |= SCALING_REQUIRED; + if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) { + applicationDensity = DisplayMetrics.DENSITY_DEVICE; + applicationScale = 1.0f; + applicationInvertedScale = 1.0f; + } else { + applicationDensity = DisplayMetrics.DENSITY_DEFAULT; + applicationScale = DisplayMetrics.DENSITY_DEVICE + / (float) DisplayMetrics.DENSITY_DEFAULT; + applicationInvertedScale = 1.0f / applicationScale; + compatFlags |= SCALING_REQUIRED; + } } mCompatibilityFlags = compatFlags; diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index ceb7752..41c4c29 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -1011,6 +1011,30 @@ <p>This appears as a child tag of the {@link #AndroidManifest manifest} tag. --> <declare-styleable name="AndroidManifestSupportsScreens" parent="AndroidManifest"> + <!-- Starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB_MR2}, + this is the new way to specify the screens an application is + compatible with. This attribute provides the required minimum + "smallest screen width" (as per the -swNNNdp resource configuration) + that the application can run on. For example, a typical phone + screen is 320, a 7" tablet 600, and a 10" tablet 720. If the + smallest screen width of the device is below the value supplied here, + then the application is considered incompatible with that device. + If not supplied, then any old smallScreens, normalScreens, largeScreens, + or xlargeScreens attributes will be used instead. --> + <attr name="requiresSmallestWidthDp" format="integer" /> + <!-- Starting with {@link android.os.Build.VERSION_CODES#HONEYCOMB_MR2}, + this is the new way to specify the screens an application is + compatible with. This attribute provides the maximum + "smallest screen width" (as per the -swNNNdp resource configuration) + that the application is designed for. If this value is smaller than + the "smallest screen width" of the device it is running on, the user + will of offered to run it in a compatibility mode that emulates a + smaller screen. Currently the compatibility mode only emulates + phone screens, so it will not be used it the application provides + a requiresSmallestWidthDp that is larger than 320. Typical values + used with this attribute are 320 for a phone screen, 600 for a + 7" tablet, and 720 for a 10" tablet. --> + <attr name="compatibleWidthLimitDp" format="integer" /> <!-- Indicates whether the application supports smaller screen form-factors. A small screen is defined as one with a smaller aspect ratio than the traditional HVGA screen; that is, for a portrait screen, less diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index f1ec398..27ca952 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1643,9 +1643,17 @@ <public type="mipmap" name="sym_def_app_icon" id="0x010d0000" /> <!-- =============================================================== - Resources added in version 12 of the platform (Honeycomb / 3.1) + Resources added in version 12 of the platform (Honeycomb MR 1 / 3.1) =============================================================== --> <eat-comment /> <public type="attr" name="textCursorDrawable" id="0x01010362" /> - <public type="attr" name="resizeMode" /> + <public type="attr" name="resizeMode" id="0x01010363" /> + + +<!-- =============================================================== + Resources added in version 13 of the platform (Honeycomb MR 2) + =============================================================== --> + <eat-comment /> + <public type="attr" name="requiresSmallestWidthDp" id="0x01010364" /> + <public type="attr" name="compatibleWidthLimitDp" /> </resources> |