am 8fcbfb52: am 94250ac6: Merge "Add new supports-screens attributes for declaring the compatible screens." into honeycomb-mr2

* commit '8fcbfb52607263754b6d3895a112f792c5c3a12e':
  Add new supports-screens attributes for declaring the compatible screens.
This commit is contained in:
Dianne Hackborn
2011-05-26 17:12:36 -07:00
committed by Android Git Automerger
9 changed files with 214 additions and 78 deletions

View File

@ -3128,6 +3128,17 @@
visibility="public" visibility="public"
> >
</field> </field>
<field name="compatibleWidthLimitDp"
type="int"
transient="false"
volatile="false"
value="16843621"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="completionHint" <field name="completionHint"
type="int" type="int"
transient="false" transient="false"
@ -7913,6 +7924,17 @@
visibility="public" visibility="public"
> >
</field> </field>
<field name="requiresSmallestWidthDp"
type="int"
transient="false"
volatile="false"
value="16843620"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="resizeMode" <field name="resizeMode"
type="int" type="int"
transient="false" transient="false"
@ -58670,6 +58692,16 @@
visibility="public" visibility="public"
> >
</field> </field>
<field name="compatibleWidthLimitDp"
type="int"
transient="false"
volatile="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="dataDir" <field name="dataDir"
type="java.lang.String" type="java.lang.String"
transient="false" transient="false"
@ -58760,6 +58792,16 @@
visibility="public" visibility="public"
> >
</field> </field>
<field name="requiresSmallestWidthDp"
type="int"
transient="false"
volatile="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="sharedLibraryFiles" <field name="sharedLibraryFiles"
type="java.lang.String[]" type="java.lang.String[]"
transient="false" transient="false"
@ -221202,7 +221244,7 @@
deprecated="not deprecated" deprecated="not deprecated"
visibility="public" visibility="public"
> >
<parameter name="ev" type="android.view.MotionEvent"> <parameter name="event" type="android.view.MotionEvent">
</parameter> </parameter>
</method> </method>
<method name="clear" <method name="clear"

View File

@ -1525,7 +1525,7 @@ public final class ActivityThread {
synchronized (this) { synchronized (this) {
ContextImpl context = getSystemContext(); ContextImpl context = getSystemContext();
context.init(new LoadedApk(this, "android", context, info, context.init(new LoadedApk(this, "android", context, info,
new CompatibilityInfo(info, 0, false)), null, this); new CompatibilityInfo(info, 0, 0, false)), null, this);
} }
} }

View File

@ -320,6 +320,22 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/ */
public int flags = 0; 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 &lt;supports-screens&gt; 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 &lt;supports-screens&gt; tag.
*/
public int compatibleWidthLimitDp = 0;
/** /**
* Full path to the location of this package. * Full path to the location of this package.
*/ */
@ -401,6 +417,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
pw.println(prefix + "taskAffinity=" + taskAffinity); pw.println(prefix + "taskAffinity=" + taskAffinity);
pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags) pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags)
+ " theme=0x" + Integer.toHexString(theme)); + " theme=0x" + Integer.toHexString(theme));
pw.println(prefix + "requiresSmallestWidthDp=" + requiresSmallestWidthDp
+ " compatibleWidthLimitDp=" + compatibleWidthLimitDp);
pw.println(prefix + "sourceDir=" + sourceDir); pw.println(prefix + "sourceDir=" + sourceDir);
if (sourceDir == null) { if (sourceDir == null) {
if (publicSourceDir != null) { if (publicSourceDir != null) {
@ -460,6 +478,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
className = orig.className; className = orig.className;
theme = orig.theme; theme = orig.theme;
flags = orig.flags; flags = orig.flags;
requiresSmallestWidthDp = orig.requiresSmallestWidthDp;
compatibleWidthLimitDp = orig.compatibleWidthLimitDp;
sourceDir = orig.sourceDir; sourceDir = orig.sourceDir;
publicSourceDir = orig.publicSourceDir; publicSourceDir = orig.publicSourceDir;
nativeLibraryDir = orig.nativeLibraryDir; nativeLibraryDir = orig.nativeLibraryDir;
@ -493,6 +513,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeString(className); dest.writeString(className);
dest.writeInt(theme); dest.writeInt(theme);
dest.writeInt(flags); dest.writeInt(flags);
dest.writeInt(requiresSmallestWidthDp);
dest.writeInt(compatibleWidthLimitDp);
dest.writeString(sourceDir); dest.writeString(sourceDir);
dest.writeString(publicSourceDir); dest.writeString(publicSourceDir);
dest.writeString(nativeLibraryDir); dest.writeString(nativeLibraryDir);
@ -526,6 +548,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
className = source.readString(); className = source.readString();
theme = source.readInt(); theme = source.readInt();
flags = source.readInt(); flags = source.readInt();
requiresSmallestWidthDp = source.readInt();
compatibleWidthLimitDp = source.readInt();
sourceDir = source.readString(); sourceDir = source.readString();
publicSourceDir = source.readString(); publicSourceDir = source.readString();
nativeLibraryDir = source.readString(); nativeLibraryDir = source.readString();

View File

@ -993,6 +993,13 @@ public class PackageParser {
sa = res.obtainAttributes(attrs, sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestSupportsScreens); 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 // This is a trick to get a boolean and still able to detect
// if a value was actually set. // if a value was actually set.
supportsSmallScreens = sa.getInteger( supportsSmallScreens = sa.getInteger(

View File

@ -110,86 +110,112 @@ public class CompatibilityInfo implements Parcelable {
*/ */
public final float applicationInvertedScale; 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; int compatFlags = 0;
// We can't rely on the application always setting if (appInfo.requiresSmallestWidthDp != 0 || appInfo.compatibleWidthLimitDp != 0) {
// FLAG_RESIZEABLE_FOR_SCREENS so will compute it based on various input. // New style screen requirements spec.
boolean anyResizeable = false; int required = appInfo.requiresSmallestWidthDp != 0
? appInfo.requiresSmallestWidthDp
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) { : appInfo.compatibleWidthLimitDp;
compatFlags |= LARGE_SCREENS; int compat = appInfo.compatibleWidthLimitDp != 0
anyResizeable = true; ? appInfo.compatibleWidthLimitDp
if (!forceCompat) { : appInfo.requiresSmallestWidthDp;
// If we aren't forcing the app into compatibility mode, then if (compat < required) {
// assume if it supports large screens that we should allow it compat = required;
// to use the full space of an xlarge screen as well.
compatFlags |= XLARGE_SCREENS | EXPANDABLE;
} }
}
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) { if (compat >= sw) {
anyResizeable = true; compatFlags |= NEVER_COMPAT;
if (!forceCompat) { } else if (forceCompat) {
compatFlags |= XLARGE_SCREENS | EXPANDABLE; compatFlags |= NEEDS_SCREEN_COMPAT;
} }
}
if ((appInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
anyResizeable = true;
compatFlags |= EXPANDABLE;
}
if (forceCompat) { // Modern apps always support densities.
// 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 (supportsScreen) {
compatFlags &= ~NEEDS_SCREEN_COMPAT;
} else {
compatFlags |= NEEDS_SCREEN_COMPAT;
}
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
applicationDensity = DisplayMetrics.DENSITY_DEVICE; applicationDensity = DisplayMetrics.DENSITY_DEVICE;
applicationScale = 1.0f; applicationScale = 1.0f;
applicationInvertedScale = 1.0f; applicationInvertedScale = 1.0f;
} else { } else {
applicationDensity = DisplayMetrics.DENSITY_DEFAULT; // We can't rely on the application always setting
applicationScale = DisplayMetrics.DENSITY_DEVICE // FLAG_RESIZEABLE_FOR_SCREENS so will compute it based on various input.
/ (float) DisplayMetrics.DENSITY_DEFAULT; boolean anyResizeable = false;
applicationInvertedScale = 1.0f / applicationScale;
compatFlags |= SCALING_REQUIRED; 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) {
anyResizeable = true;
if (!forceCompat) {
compatFlags |= XLARGE_SCREENS | EXPANDABLE;
}
}
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 (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;
}
} }
mCompatibilityFlags = compatFlags; mCompatibilityFlags = compatFlags;

View File

@ -1011,6 +1011,30 @@
<p>This appears as a child tag of the <p>This appears as a child tag of the
{@link #AndroidManifest manifest} tag. --> {@link #AndroidManifest manifest} tag. -->
<declare-styleable name="AndroidManifestSupportsScreens" parent="AndroidManifest"> <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. <!-- Indicates whether the application supports smaller screen form-factors.
A small screen is defined as one with a smaller aspect ratio than A small screen is defined as one with a smaller aspect ratio than
the traditional HVGA screen; that is, for a portrait screen, less the traditional HVGA screen; that is, for a portrait screen, less

View File

@ -1643,9 +1643,17 @@
<public type="mipmap" name="sym_def_app_icon" id="0x010d0000" /> <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 /> <eat-comment />
<public type="attr" name="textCursorDrawable" id="0x01010362" /> <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> </resources>

View File

@ -119,13 +119,15 @@ public class CompatModePackages {
public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
return new CompatibilityInfo(ai, mService.mConfiguration.screenLayout, return new CompatibilityInfo(ai, mService.mConfiguration.screenLayout,
mService.mConfiguration.smallestScreenWidthDp,
(getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0); (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0);
} }
public int computeCompatModeLocked(ApplicationInfo ai) { public int computeCompatModeLocked(ApplicationInfo ai) {
boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0; boolean enabled = (getPackageFlags(ai.packageName)&COMPAT_FLAG_ENABLED) != 0;
CompatibilityInfo info = new CompatibilityInfo(ai, CompatibilityInfo info = new CompatibilityInfo(ai,
mService.mConfiguration.screenLayout, enabled); mService.mConfiguration.screenLayout,
mService.mConfiguration.smallestScreenWidthDp, enabled);
if (info.alwaysSupportsScreen()) { if (info.alwaysSupportsScreen()) {
return ActivityManager.COMPAT_MODE_NEVER; return ActivityManager.COMPAT_MODE_NEVER;
} }
@ -315,6 +317,7 @@ public class CompatModePackages {
final IPackageManager pm = AppGlobals.getPackageManager(); final IPackageManager pm = AppGlobals.getPackageManager();
final int screenLayout = mService.mConfiguration.screenLayout; final int screenLayout = mService.mConfiguration.screenLayout;
final int smallestScreenWidthDp = mService.mConfiguration.smallestScreenWidthDp;
final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator(); final Iterator<Map.Entry<String, Integer>> it = pkgs.entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry<String, Integer> entry = it.next(); Map.Entry<String, Integer> entry = it.next();
@ -331,7 +334,8 @@ public class CompatModePackages {
if (ai == null) { if (ai == null) {
continue; continue;
} }
CompatibilityInfo info = new CompatibilityInfo(ai, screenLayout, false); CompatibilityInfo info = new CompatibilityInfo(ai, screenLayout,
smallestScreenWidthDp, false);
if (info.alwaysSupportsScreen()) { if (info.alwaysSupportsScreen()) {
continue; continue;
} }

View File

@ -63,7 +63,8 @@ public class DpiTestActivity extends Activity {
| ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS | ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS
| ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES; | ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai, app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai,
getResources().getConfiguration().screenLayout, false)); getResources().getConfiguration().screenLayout,
getResources().getConfiguration().smallestScreenWidthDp, false));
} }
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("ouch", e); throw new RuntimeException("ouch", e);