Merge change 5483 into donut

* changes:
  Expand support for different screen sizes.
This commit is contained in:
Android (Google) Code Review
2009-06-26 13:46:07 -07:00
26 changed files with 603 additions and 102 deletions

View File

@@ -233,6 +233,12 @@ public class ActivityInfo extends ComponentInfo
* {@link android.R.attr#configChanges} attribute.
*/
public static final int CONFIG_ORIENTATION = 0x0080;
/**
* Bit in {@link #configChanges} that indicates that the activity
* can itself handle changes to the screen layout. Set from the
* {@link android.R.attr#configChanges} attribute.
*/
public static final int CONFIG_SCREEN_LAYOUT = 0x0100;
/**
* Bit in {@link #configChanges} that indicates that the activity
* can itself handle changes to the font scaling factor. Set from the
@@ -248,8 +254,8 @@ public class ActivityInfo extends ComponentInfo
* Contains any combination of {@link #CONFIG_FONT_SCALE},
* {@link #CONFIG_MCC}, {@link #CONFIG_MNC},
* {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN},
* {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION}, and
* {@link #CONFIG_ORIENTATION}. Set from the
* {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION},
* {@link #CONFIG_ORIENTATION}, and {@link #CONFIG_SCREEN_LAYOUT}. Set from the
* {@link android.R.attr#configChanges} attribute.
*/
public int configChanges;

View File

@@ -138,10 +138,27 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
/**
* Value for {@link #flags}: true when the application's window can be
* expanded over default window size in target density (320x480 for
* 1.0 density, 480x720 for 1.5 density etc)
* reduced in size for smaller screens. Corresponds to
* {@link android.R.styleable#AndroidManifestSupportsScreens_smallScreens
* android:smallScreens}.
*/
public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<9;
public static final int FLAG_SUPPORTS_SMALL_SCREENS = 1<<9;
/**
* Value for {@link #flags}: true when the application's window can be
* displayed on normal screens. Corresponds to
* {@link android.R.styleable#AndroidManifestSupportsScreens_normalScreens
* android:normalScreens}.
*/
public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1<<10;
/**
* Value for {@link #flags}: true when the application's window can be
* increased in size for larger screens. Corresponds to
* {@link android.R.styleable#AndroidManifestSupportsScreens_largeScreens
* android:smallScreens}.
*/
public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<11;
/**
* Value for {@link #flags}: this is false if the application has set
@@ -149,7 +166,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*
* {@hide}
*/
public static final int FLAG_ALLOW_BACKUP = 1<<10;
public static final int FLAG_ALLOW_BACKUP = 1<<12;
/**
* Indicates that the application supports any densities;
@@ -164,7 +181,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
* {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
* {@link #FLAG_ALLOW_TASK_REPARENTING}
* {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
* {@link #FLAG_TEST_ONLY}.
* {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
* {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
* {@link #FLAG_SUPPORTS_LARGE_SCREENS}.
*/
public int flags = 0;

View File

@@ -668,6 +668,11 @@ public class PackageParser {
}
sa.recycle();
// Resource boolean are -1, so 1 means we don't know the value.
int supportsSmallScreens = 1;
int supportsNormalScreens = 1;
int supportsLargeScreens = 1;
int outerDepth = parser.getDepth();
while ((type=parser.next()) != parser.END_DOCUMENT
&& (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -876,8 +881,24 @@ public class PackageParser {
XmlUtils.skipCurrentTag(parser);
} else if (tagName.equals("expandable")) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
} else if (tagName.equals("supports-screens")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestSupportsScreens);
// This is a trick to get a boolean and still able to detect
// if a value was actually set.
supportsSmallScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_smallScreens,
supportsSmallScreens);
supportsNormalScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_normalScreens,
supportsNormalScreens);
supportsLargeScreens = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
supportsLargeScreens);
sa.recycle();
XmlUtils.skipCurrentTag(parser);
} else {
Log.w(TAG, "Bad element under <manifest>: "
@@ -910,7 +931,20 @@ public class PackageParser {
pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
}
// TODO: enable all density & expandable if target sdk is higher than donut
if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
}
if (supportsNormalScreens != 0) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
}
if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
&& pkg.applicationInfo.targetSdkVersion
>= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
}
int size = pkg.supportsDensityList.size();
if (size > 0) {

View File

@@ -601,7 +601,7 @@ public final class AssetManager {
public native final void setConfiguration(int mcc, int mnc, String locale,
int orientation, int touchscreen, int density, int keyboard,
int keyboardHidden, int navigation, int screenWidth, int screenHeight,
int majorVersion);
int screenLayout, int majorVersion);
/**
* Retrieve the resource identifier for the given resource name.

View File

@@ -65,7 +65,7 @@ public class CompatibilityInfo {
/**
* A compatibility flags
*/
private int compatibilityFlags;
private int mCompatibilityFlags;
/**
* A flag mask to tell if the application needs scaling (when mApplicationScale != 1.0f)
@@ -101,7 +101,11 @@ public class CompatibilityInfo {
*/
public final float applicationInvertedScale;
/**
* The flags from ApplicationInfo.
*/
public final int appFlags;
/**
* Window size in Compatibility Mode, in real pixels. This is updated by
* {@link DisplayMetrics#updateMetrics}.
@@ -117,8 +121,10 @@ public class CompatibilityInfo {
private int mXOffset;
public CompatibilityInfo(ApplicationInfo appInfo) {
appFlags = appInfo.flags;
if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
}
float packageDensityScale = -1.0f;
@@ -149,13 +155,16 @@ public class CompatibilityInfo {
}
applicationInvertedScale = 1.0f / applicationScale;
if (applicationScale != 1.0f) {
compatibilityFlags |= SCALING_REQUIRED;
mCompatibilityFlags |= SCALING_REQUIRED;
}
}
private CompatibilityInfo() {
appFlags = ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
| ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
| ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
applicationScale = applicationInvertedScale = 1.0f;
compatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
}
/**
@@ -175,9 +184,9 @@ public class CompatibilityInfo {
*/
public void setExpandable(boolean expandable) {
if (expandable) {
compatibilityFlags |= CompatibilityInfo.EXPANDABLE;
mCompatibilityFlags |= CompatibilityInfo.EXPANDABLE;
} else {
compatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
mCompatibilityFlags &= ~CompatibilityInfo.EXPANDABLE;
}
}
@@ -185,20 +194,20 @@ public class CompatibilityInfo {
* @return true if the application is configured to be expandable.
*/
public boolean isConfiguredExpandable() {
return (compatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
return (mCompatibilityFlags & CompatibilityInfo.CONFIGURED_EXPANDABLE) != 0;
}
/**
* @return true if the scaling is required
*/
public boolean isScalingRequired() {
return (compatibilityFlags & SCALING_REQUIRED) != 0;
return (mCompatibilityFlags & SCALING_REQUIRED) != 0;
}
@Override
public String toString() {
return "CompatibilityInfo{scale=" + applicationScale +
", compatibility flag=" + compatibilityFlags + "}";
", compatibility flag=" + mCompatibilityFlags + "}";
}
/**
@@ -222,13 +231,13 @@ public class CompatibilityInfo {
* @param params the window's parameter
*/
public Translator getTranslator(WindowManager.LayoutParams params) {
if ( (compatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
if ( (mCompatibilityFlags & CompatibilityInfo.SCALING_EXPANDABLE_MASK)
== CompatibilityInfo.EXPANDABLE) {
if (DBG) Log.d(TAG, "no translation required");
return null;
}
if ((compatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
if ((mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
if ((params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
if (DBG) Log.d(TAG, "translation for surface view selected");
return new Translator(X_SHIFT_WINDOW, false, 1.0f, 1.0f);

View File

@@ -116,6 +116,18 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*/
public int orientation;
public static final int SCREENLAYOUT_UNDEFINED = 0;
public static final int SCREENLAYOUT_SMALL = 1;
public static final int SCREENLAYOUT_NORMAL = 2;
public static final int SCREENLAYOUT_LARGE = 3;
/**
* Overall layout of the screen. May be one of
* {@link #SCREENLAYOUT_SMALL}, {@link #SCREENLAYOUT_NORMAL},
* or {@link #SCREENLAYOUT_LARGE}.
*/
public int screenLayout;
/**
* Construct an invalid Configuration. You must call {@link #setToDefaults}
* for this object to be valid. {@more}
@@ -141,6 +153,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
hardKeyboardHidden = o.hardKeyboardHidden;
navigation = o.navigation;
orientation = o.orientation;
screenLayout = o.screenLayout;
}
public String toString() {
@@ -165,6 +178,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
sb.append(navigation);
sb.append(" orien=");
sb.append(orientation);
sb.append(" layout=");
sb.append(screenLayout);
sb.append('}');
return sb.toString();
}
@@ -183,6 +198,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
navigation = NAVIGATION_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_UNDEFINED;
}
/** {@hide} */
@@ -253,6 +269,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
changed |= ActivityInfo.CONFIG_ORIENTATION;
orientation = delta.orientation;
}
if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
&& screenLayout != delta.screenLayout) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
screenLayout = delta.screenLayout;
}
return changed;
}
@@ -276,9 +297,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
* {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD
* PackageManager.ActivityInfo.CONFIG_KEYBOARD},
* {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
* PackageManager.ActivityInfo.CONFIG_NAVIGATION}, or
* PackageManager.ActivityInfo.CONFIG_NAVIGATION},
* {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
* PackageManager.ActivityInfo.CONFIG_ORIENTATION}.
* PackageManager.ActivityInfo.CONFIG_ORIENTATION}, or
* {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
* PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}.
*/
public int diff(Configuration delta) {
int changed = 0;
@@ -319,6 +342,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
}
if (delta.screenLayout != SCREENLAYOUT_UNDEFINED
&& screenLayout != delta.screenLayout) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
}
return changed;
}
@@ -368,6 +395,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
dest.writeInt(hardKeyboardHidden);
dest.writeInt(navigation);
dest.writeInt(orientation);
dest.writeInt(screenLayout);
}
public static final Parcelable.Creator<Configuration> CREATOR
@@ -399,6 +427,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
hardKeyboardHidden = source.readInt();
navigation = source.readInt();
orientation = source.readInt();
screenLayout = source.readInt();
}
public int compareTo(Configuration that) {
@@ -428,6 +457,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
n = this.navigation - that.navigation;
if (n != 0) return n;
n = this.orientation - that.orientation;
if (n != 0) return n;
n = this.screenLayout - that.screenLayout;
//if (n != 0) return n;
return n;
}
@@ -450,6 +481,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
return ((int)this.fontScale) + this.mcc + this.mnc
+ this.locale.hashCode() + this.touchscreen
+ this.keyboard + this.keyboardHidden + this.hardKeyboardHidden
+ this.navigation + this.orientation;
+ this.navigation + this.orientation + this.screenLayout;
}
}

View File

@@ -1267,7 +1267,8 @@ public class Resources {
}
if (metrics != null) {
mMetrics.setTo(metrics);
mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration.orientation);
mMetrics.updateMetrics(mCompatibilityInfo,
mConfiguration.orientation, mConfiguration.screenLayout);
}
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
@@ -1299,7 +1300,7 @@ public class Resources {
mConfiguration.touchscreen,
(int)(mMetrics.density*160), mConfiguration.keyboard,
keyboardHidden, mConfiguration.navigation, width, height,
sSdkVersion);
mConfiguration.screenLayout, sSdkVersion);
int N = mDrawableCache.size();
if (DEBUG_CONFIG) {
Log.d(TAG, "Cleaning up drawables config changes: 0x"

View File

@@ -103,40 +103,43 @@ public class DisplayMetrics {
/**
* Update the display metrics based on the compatibility info and orientation
* NOTE: DO NOT EXPOSE THIS API! It is introducing a circular dependency
* with the higher-level android.res package.
* {@hide}
*/
public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) {
public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation,
int screenLayout) {
int xOffset = 0;
if (!compatibilityInfo.isConfiguredExpandable()) {
// Note: this assume that configuration is updated before calling
// updateMetrics method.
int defaultWidth;
int defaultHeight;
switch (orientation) {
case Configuration.ORIENTATION_LANDSCAPE: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
break;
}
case Configuration.ORIENTATION_PORTRAIT:
case Configuration.ORIENTATION_SQUARE:
default: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
break;
}
case Configuration.ORIENTATION_UNDEFINED: {
// don't change
return;
}
}
if (defaultWidth == widthPixels && defaultHeight == heightPixels) {
// the screen size is same as expected size. make it expandable
compatibilityInfo.setExpandable(true);
} else {
if (screenLayout == Configuration.SCREENLAYOUT_LARGE) {
// This is a large screen device and the app is not
// compatible with large screens, to diddle it.
compatibilityInfo.setExpandable(false);
// adjust the size only when the device's screen is bigger.
// Figure out the compatibility width and height of the screen.
int defaultWidth;
int defaultHeight;
switch (orientation) {
case Configuration.ORIENTATION_LANDSCAPE: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
break;
}
case Configuration.ORIENTATION_PORTRAIT:
case Configuration.ORIENTATION_SQUARE:
default: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
break;
}
case Configuration.ORIENTATION_UNDEFINED: {
// don't change
return;
}
}
if (defaultWidth < widthPixels) {
// content/window's x offset in original pixels
xOffset = ((widthPixels - defaultWidth) / 2);
@@ -145,6 +148,10 @@ public class DisplayMetrics {
if (defaultHeight < heightPixels) {
heightPixels = defaultHeight;
}
} else {
// the screen size is same as expected size. make it expandable
compatibilityInfo.setExpandable(true);
}
}
compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels);