diff --git a/api/current.xml b/api/current.xml index 1e79de5bd707f..f96eb1c83289c 100644 --- a/api/current.xml +++ b/api/current.xml @@ -3529,39 +3529,6 @@ visibility="public" > - - - - - - + + + + + + + + + + + + + + + + + + + + + + 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 : " @@ -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) { diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 1c9173694d2bc..5c7b01fa0ccb0 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -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. diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java index 179b9bd4c1c9d..4e6fe07b9bf03 100644 --- a/core/java/android/content/res/CompatibilityInfo.java +++ b/core/java/android/content/res/CompatibilityInfo.java @@ -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); diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index bb3486c205545..577aa600a19e1 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -116,6 +116,18 @@ public final class Configuration implements Parcelable, ComparablesetConfiguration(config, locale8); @@ -1567,7 +1568,7 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_setLocale }, { "getLocales", "()[Ljava/lang/String;", (void*) android_content_AssetManager_getLocales }, - { "setConfiguration", "(IILjava/lang/String;IIIIIIIII)V", + { "setConfiguration", "(IILjava/lang/String;IIIIIIIIII)V", (void*) android_content_AssetManager_setConfiguration }, { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*) android_content_AssetManager_getResourceIdentifier }, diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 91cd9fdd1b1b9..7571e24536279 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -512,6 +512,9 @@ + + @@ -829,8 +832,59 @@

This appears as a child tag of the {@link #AndroidManifest manifest} tag. --> - - + + + + + + + + + + + + + + + + + + + + + + DpiTest: Large Screen + diff --git a/tests/DpiTest/res/values-normalScreen/strings.xml b/tests/DpiTest/res/values-normalScreen/strings.xml new file mode 100644 index 0000000000000..256d696df80ed --- /dev/null +++ b/tests/DpiTest/res/values-normalScreen/strings.xml @@ -0,0 +1,19 @@ + + + + + DpiTest: Normal Screen + diff --git a/tests/DpiTest/res/values-smallScreen/strings.xml b/tests/DpiTest/res/values-smallScreen/strings.xml new file mode 100644 index 0000000000000..cdb4ac9f60bd8 --- /dev/null +++ b/tests/DpiTest/res/values-smallScreen/strings.xml @@ -0,0 +1,19 @@ + + + + + DpiTest: Small Screen + diff --git a/tests/DpiTest/res/values/strings.xml b/tests/DpiTest/res/values/strings.xml new file mode 100644 index 0000000000000..ef924ac85a632 --- /dev/null +++ b/tests/DpiTest/res/values/strings.xml @@ -0,0 +1,19 @@ + + + + + DpiTest: Unknown Screen + diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java index 3759622bbbec2..5a9f3f548c7d8 100644 --- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java +++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java @@ -34,6 +34,7 @@ public class DpiTestActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + this.setTitle(R.string.act_title); LinearLayout root = new LinearLayout(this); root.setOrientation(LinearLayout.VERTICAL); diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 6bc1ee6cbfbc5..67af116d372dc 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -187,6 +187,13 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value) return 0; } + // screen layout + if (getScreenLayoutName(part.string(), &config)) { + *axis = AXIS_SCREENLAYOUT; + *value = config.screenLayout; + return 0; + } + // version if (getVersionName(part.string(), &config)) { *axis = AXIS_VERSION; @@ -202,7 +209,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType) { Vector parts; - String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, vers; + String8 mcc, mnc, loc, orient, den, touch, key, keysHidden, nav, size, layout, vers; const char *p = dir; const char *q; @@ -378,6 +385,18 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType) //printf("not screen size: %s\n", part.string()); } + if (getScreenLayoutName(part.string())) { + layout = part; + + index++; + if (index == N) { + goto success; + } + part = parts[index]; + } else { + //printf("not screen layout: %s\n", part.string()); + } + if (getVersionName(part.string())) { vers = part; @@ -404,6 +423,7 @@ success: this->keyboard = key; this->navigation = nav; this->screenSize = size; + this->screenLayout = layout; this->version = vers; // what is this anyway? @@ -435,6 +455,8 @@ AaptGroupEntry::toString() const s += ","; s += screenSize; s += ","; + s += screenLayout; + s += ","; s += version; return s; } @@ -483,6 +505,10 @@ AaptGroupEntry::toDirName(const String8& resType) const s += "-"; s += screenSize; } + if (this->screenLayout != "") { + s += "-"; + s += screenLayout; + } if (this->version != "") { s += "-"; s += version; @@ -786,6 +812,26 @@ bool AaptGroupEntry::getScreenSizeName(const char* name, return true; } +bool AaptGroupEntry::getScreenLayoutName(const char* name, + ResTable_config* out) +{ + if (strcmp(name, kWildcardName) == 0) { + if (out) out->screenLayout = out->SCREENLAYOUT_ANY; + return true; + } else if (strcmp(name, "smallscreen") == 0) { + if (out) out->screenLayout = out->SCREENLAYOUT_SMALL; + return true; + } else if (strcmp(name, "normalscreen") == 0) { + if (out) out->screenLayout = out->SCREENLAYOUT_NORMAL; + return true; + } else if (strcmp(name, "largescreen") == 0) { + if (out) out->screenLayout = out->SCREENLAYOUT_LARGE; + return true; + } + + return false; +} + bool AaptGroupEntry::getVersionName(const char* name, ResTable_config* out) { @@ -828,6 +874,7 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const if (v == 0) v = keyboard.compare(o.keyboard); if (v == 0) v = navigation.compare(o.navigation); if (v == 0) v = screenSize.compare(o.screenSize); + if (v == 0) v = screenLayout.compare(o.screenLayout); if (v == 0) v = version.compare(o.version); return v; } @@ -846,6 +893,7 @@ ResTable_config AaptGroupEntry::toParams() const getKeyboardName(keyboard.string(), ¶ms); getNavigationName(navigation.string(), ¶ms); getScreenSizeName(screenSize.string(), ¶ms); + getScreenLayoutName(screenLayout.string(), ¶ms); getVersionName(version.string(), ¶ms); return params; } diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index 3f370696289a9..e8c739558a6bd 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -37,6 +37,7 @@ enum { AXIS_KEYBOARD, AXIS_NAVIGATION, AXIS_SCREENSIZE, + AXIS_SCREENLAYOUT, AXIS_VERSION }; @@ -62,6 +63,7 @@ public: String8 keyboard; String8 navigation; String8 screenSize; + String8 screenLayout; String8 version; bool initFromDirName(const char* dir, String8* resType); @@ -78,6 +80,7 @@ public: static bool getKeyboardName(const char* name, ResTable_config* out = NULL); static bool getNavigationName(const char* name, ResTable_config* out = NULL); static bool getScreenSizeName(const char* name, ResTable_config* out = NULL); + static bool getScreenLayoutName(const char* name, ResTable_config* out = NULL); static bool getVersionName(const char* name, ResTable_config* out = NULL); int compare(const AaptGroupEntry& o) const; diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index dcda379c7c18a..c0ae592f66926 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -331,6 +331,9 @@ enum { TARGET_SDK_VERSION_ATTR = 0x01010270, TEST_ONLY_ATTR = 0x01010272, DENSITY_ATTR = 0x0101026c, + SMALL_SCREEN_ATTR = 0x01010284, + NORMAL_SCREEN_ATTR = 0x01010285, + LARGE_SCREEN_ATTR = 0x01010286, }; const char *getComponentName(String8 &pkgName, String8 &componentName) { @@ -501,6 +504,10 @@ int doDump(Bundle* bundle) bool isLauncherActivity = false; bool withinApplication = false; bool withinReceiver = false; + int targetSdk = 0; + int smallScreen = 1; + int normalScreen = 1; + int largeScreen = 1; String8 pkg; String8 activityName; String8 activityLabel; @@ -574,8 +581,10 @@ int doDump(Bundle* bundle) error.string()); goto bail; } + if (name == "Donut") targetSdk = 4; printf("sdkVersion:'%s'\n", name.string()); } else if (code != -1) { + targetSdk = code; printf("sdkVersion:'%d'\n", code); } code = getIntegerAttribute(tree, TARGET_SDK_VERSION_ATTR, &error); @@ -587,8 +596,12 @@ int doDump(Bundle* bundle) error.string()); goto bail; } + if (name == "Donut" && targetSdk < 4) targetSdk = 4; printf("targetSdkVersion:'%s'\n", name.string()); } else if (code != -1) { + if (targetSdk < code) { + targetSdk = code; + } printf("targetSdkVersion:'%d'\n", code); } } else if (tag == "uses-configuration") { @@ -627,6 +640,13 @@ int doDump(Bundle* bundle) goto bail; } printf("supports-density:'%d'\n", dens); + } else if (tag == "supports-screens") { + smallScreen = getIntegerAttribute(tree, + SMALL_SCREEN_ATTR, NULL, 1); + normalScreen = getIntegerAttribute(tree, + NORMAL_SCREEN_ATTR, NULL, 1); + largeScreen = getIntegerAttribute(tree, + LARGE_SCREEN_ATTR, NULL, 1); } } else if (depth == 3 && withinApplication) { withinActivity = false; @@ -735,6 +755,25 @@ int doDump(Bundle* bundle) } } + // Determine default values for any unspecified screen sizes, + // based on the target SDK of the package. As of 4 (donut) + // the screen size support was introduced, so all default to + // enabled. + if (smallScreen > 0) { + smallScreen = targetSdk >= 4 ? -1 : 0; + } + if (normalScreen > 0) { + normalScreen = -1; + } + if (largeScreen > 0) { + largeScreen = targetSdk >= 4 ? -1 : 0; + } + printf("supports-screens:"); + if (smallScreen != 0) printf(" 'small'"); + if (normalScreen != 0) printf(" 'normal'"); + if (largeScreen != 0) printf(" 'large'"); + printf("\n"); + printf("locales:"); Vector locales; res.getLocales(&locales); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java index 1fa11af3f2299..06dd96f8e6288 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java @@ -59,7 +59,7 @@ public class BridgeAssetManager extends AssetManager { public 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 version) { + int screenLayout, int version) { Configuration c = new Configuration(); c.mcc = mcc; @@ -70,5 +70,6 @@ public class BridgeAssetManager extends AssetManager { c.keyboardHidden = keyboardHidden; c.navigation = navigation; c.orientation = orientation; + c.screenLayout = screenLayout; } }