diff options
26 files changed, 603 insertions, 102 deletions
| diff --git a/api/current.xml b/api/current.xml index 66bdb28..3c58ded 100644 --- a/api/current.xml +++ b/api/current.xml @@ -3452,39 +3452,6 @@   visibility="public"  >  </field> -<field name="donut_resource_pad26" - type="int" - transient="false" - volatile="false" - value="16843398" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> -<field name="donut_resource_pad27" - type="int" - transient="false" - volatile="false" - value="16843397" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> -<field name="donut_resource_pad28" - type="int" - transient="false" - volatile="false" - value="16843396" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field>  <field name="donut_resource_pad3"   type="int"   transient="false" @@ -5311,6 +5278,17 @@   visibility="public"  >  </field> +<field name="largeScreens" + type="int" + transient="false" + volatile="false" + value="16843398" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field>  <field name="launchMode"   type="int"   transient="false" @@ -6191,6 +6169,17 @@   visibility="public"  >  </field> +<field name="normalScreens" + type="int" + transient="false" + volatile="false" + value="16843397" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field>  <field name="numColumns"   type="int"   transient="false" @@ -7577,6 +7566,17 @@   visibility="public"  >  </field> +<field name="smallScreens" + type="int" + transient="false" + volatile="false" + value="16843396" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field>  <field name="smoothScrollbar"   type="int"   transient="false" @@ -34821,6 +34821,17 @@   visibility="public"  >  </field> +<field name="CONFIG_SCREEN_LAYOUT" + type="int" + transient="false" + volatile="false" + value="256" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field>  <field name="CONFIG_TOUCHSCREEN"   type="int"   transient="false" @@ -35289,6 +35300,28 @@   type="int"   transient="false"   volatile="false" + value="2048" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_SUPPORTS_NORMAL_SCREENS" + type="int" + transient="false" + volatile="false" + value="1024" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_SUPPORTS_SMALL_SCREENS" + type="int" + transient="false" + volatile="false"   value="512"   static="true"   final="true" @@ -39488,6 +39521,50 @@   visibility="public"  >  </field> +<field name="SCREENLAYOUT_LARGE" + type="int" + transient="false" + volatile="false" + value="3" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SCREENLAYOUT_NORMAL" + type="int" + transient="false" + volatile="false" + value="2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SCREENLAYOUT_SMALL" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SCREENLAYOUT_UNDEFINED" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field>  <field name="TOUCHSCREEN_FINGER"   type="int"   transient="false" @@ -39622,6 +39699,16 @@   visibility="public"  >  </field> +<field name="screenLayout" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field>  <field name="touchscreen"   type="int"   transient="false" diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 85d877a..27783ef 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -235,6 +235,12 @@ public class ActivityInfo extends ComponentInfo      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       * {@link android.R.attr#configChanges} attribute.  This is       * not a core resource configutation, but a higher-level value, so its @@ -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; diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 2a2cf93..bcf95b6 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -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; diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ab9518e..558b0c3 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -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) { diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 1c91736..5c7b01f 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 179b9bd..4e6fe07 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 bb3486c..577aa60 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, 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;      }  } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index cb9d46e..d7512bb 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -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" diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index d89ada0..4179edb 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -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); diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index d147bcc..2d90ba4 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -535,7 +535,7 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c                                                            jint keyboard, jint keyboardHidden,                                                            jint navigation,                                                            jint screenWidth, jint screenHeight, -                                                          jint sdkVersion) +                                                          jint screenLayout, jint sdkVersion)  {      AssetManager* am = assetManagerForJavaObject(env, clazz);      if (am == NULL) { @@ -557,6 +557,7 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c      config.navigation = (uint8_t)navigation;      config.screenWidth = (uint16_t)screenWidth;      config.screenHeight = (uint16_t)screenHeight; +    config.screenLayout = (uint8_t)screenLayout;      config.sdkVersion = (uint16_t)sdkVersion;      config.minorVersion = 0;      am->setConfiguration(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 91cd9fd..7571e24 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -512,6 +512,9 @@          <!-- The screen orientation has changed, that is the user has               rotated the device. -->          <flag name="orientation" value="0x0080" /> +        <!-- The screen orientation has changed, that is the user has +             rotated the device. --> +        <flag name="screenLayout" value="0x0100" />          <!-- The font scaling factor has changed, that is the user has               selected a new global font size. -->          <flag name="fontScale" value="0x40000000" /> @@ -829,8 +832,59 @@           <p>This appears as a child tag of the           {@link #AndroidManifest manifest} tag. -->      <declare-styleable name="AndroidManifestSupportsDensity" parent="AndroidManifest"> -        <!-- Required value of the density in dip (device independent pixel). --> -        <attr name="density" format="integer" /> +        <!-- Required value of the density in dip (device independent pixel). +             You should use one of the pre-defined constants for the standard +             screen densities defined here. +        --> +        <attr name="density" format="integer"> +            <!-- A low density screen, such as a QVGA or WQVGA screen in a +                 typical hand-held phone.  The constant for this is 120. --> +            <enum name="low" value="120" /> +            <!-- A medium density screen, such as an HVGA screen in a +                 typical hand-held phone.  The constant for this is 160. --> +            <enum name="medium" value="160" /> +            <!-- A high density screen, such as a VGA or WVGA screen in a +                 typical hand-held phone.  The constant for this is 240. --> +            <enum name="high" value="240" /> +        </attr> +    </declare-styleable> + +    <!-- The <code>supports-screens</code> specifies the screen dimensions an +         application supports.  By default a modern application supports all +         screen sizes and must explicitly disable certain screen sizes here; +         older applications are assumed to only support the traditional normal +         (HVGA) screen size.  Note that screen size is a separate axis from +         density, and is determined as the available pixels to an application +         after density scaling has been applied. +          +         <p>This appears as a child tag of the +         {@link #AndroidManifest manifest} tag. --> +    <declare-styleable name="AndroidManifestSupportsScreens" parent="AndroidManifest"> +        <!-- 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 +             tall than an HVGA screen.  In practice, this means a QVGA low +             density or VGA high density screen.  An application that does +             not support small screens <em>will not be available</em> for +             small screen devices, since there is little the platform can do +             to make such an application work on a smaller screen. --> +        <attr name="smallScreens" format="boolean" /> +        <!-- Indicates whether an application supports the normal screen +             form-factors.  Traditionally this is an HVGA normal density +             screen, but WQVGA low density and WVGA high density are also +             considered to be normal.  This attribute is true by default, +             and applications currently should leave it that way. --> +        <attr name="normalScreens" format="boolean" /> +        <!-- Indicates whether the application supports larger screen form-factors. +             A large screen is defined as a screen that is significantly larger +             than a normal phone screen, and thus may require some special care +             on the application's part to make good use of it.  An example would +             be a VGA <em>normal density</em> screen, though even larger screens +             are certainly possible.  An application that does not support +             large screens will be placed as a postage stamp on such a +             screen, so that it retains the dimensions it was originally +             designed for. --> +        <attr name="largeScreens" format="boolean" />      </declare-styleable>      <!-- The <code>expandable</code> specifies if this package supports screen metrics diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 4634b50..14d8dbe 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1117,6 +1117,9 @@    <public type="attr" name="glEsVersion" />    <public type="attr" name="queryAfterZeroResults" />    <public type="attr" name="dropDownHeight" /> +  <public type="attr" name="smallScreens" /> +  <public type="attr" name="normalScreens" /> +  <public type="attr" name="largeScreens" />    <public-padding type="attr" name="donut_resource_pad" end="0x0101029f" /> diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index f1029b7..5c41ead 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -866,7 +866,7 @@ struct ResTable_config              uint8_t keyboard;              uint8_t navigation;              uint8_t inputFlags; -            uint8_t pad0; +            uint8_t inputPad0;          };          uint32_t input;      }; @@ -905,6 +905,23 @@ struct ResTable_config          uint32_t version;      }; +    enum { +        SCREENLAYOUT_ANY  = 0x0000, +        SCREENLAYOUT_SMALL = 0x0001, +        SCREENLAYOUT_NORMAL = 0x0002, +        SCREENLAYOUT_LARGE = 0x0003, +    }; +     +    union { +        struct { +            uint8_t screenLayout; +            uint8_t screenConfigPad0; +            uint8_t screenConfigPad1; +            uint8_t screenConfigPad2; +        }; +        uint32_t screenConfig; +    }; +          inline void copyFromDeviceNoSwap(const ResTable_config& o) {          const size_t size = dtohl(o.size);          if (size >= sizeof(ResTable_config)) { @@ -950,6 +967,8 @@ struct ResTable_config          diff = (int32_t)(screenSize - o.screenSize);          if (diff != 0) return diff;          diff = (int32_t)(version - o.version); +        if (diff != 0) return diff; +        diff = (int32_t)(screenLayout - o.screenLayout);          return (int)diff;      } @@ -967,7 +986,8 @@ struct ResTable_config          CONFIG_ORIENTATION = 0x0080,          CONFIG_DENSITY = 0x0100,          CONFIG_SCREEN_SIZE = 0x0200, -        CONFIG_VERSION = 0x0400 +        CONFIG_VERSION = 0x0400, +        CONFIG_SCREEN_LAYOUT = 0x0800      };      // Compare two configuration, returning CONFIG_* flags set for each value @@ -985,6 +1005,7 @@ struct ResTable_config          if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;          if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;          if (version != o.version) diffs |= CONFIG_VERSION; +        if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;          return diffs;      } @@ -1062,6 +1083,13 @@ struct ResTable_config              }          } +        if (screenConfig || o.screenConfig) { +            if (screenLayout != o.screenLayout) { +                if (!screenLayout) return false; +                if (!o.screenLayout) return true; +            } +        } +          if (version || o.version) {              if (sdkVersion != o.sdkVersion) {                  if (!sdkVersion) return false; @@ -1191,6 +1219,12 @@ struct ResTable_config                  }              } +            if (screenConfig || o.screenConfig) { +                if ((screenLayout != o.screenLayout) && requested->screenLayout) { +                    return (screenLayout); +                } +            } +              if (version || o.version) {                  if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {                      return (sdkVersion); @@ -1282,6 +1316,12 @@ struct ResTable_config                  return false;              }          } +        if (screenConfig != 0) { +            if (settings.screenLayout != 0 && screenLayout != 0 +                && screenLayout != settings.screenLayout) { +                return false; +            } +        }          if (version != 0) {              if (settings.sdkVersion != 0 && sdkVersion != 0                  && sdkVersion != settings.sdkVersion) { @@ -1310,13 +1350,13 @@ struct ResTable_config      String8 toString() const {          char buf[200]; -        sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=0x%02x touch=0x%02x dens=0x%02x " -                "kbd=0x%02x nav=0x%02x input=0x%02x screenW=0x%04x screenH=0x%04x vers=%d.%d", +        sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=%d touch=%d dens=%d " +                "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d layout=%d vers=%d.%d",                  mcc, mnc,                  language[0] ? language[0] : '-', language[1] ? language[1] : '-',                  country[0] ? country[0] : '-', country[1] ? country[1] : '-',                  orientation, touchscreen, density, keyboard, navigation, inputFlags, -                screenWidth, screenHeight, sdkVersion, minorVersion); +                screenWidth, screenHeight, screenLayout, sdkVersion, minorVersion);          return String8(buf);      }  }; diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index e4f9f0f..7a33220 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -3919,7 +3919,7 @@ void ResTable::print(bool inclValues) const                          printf("      NON-INTEGER ResTable_type ADDRESS: %p\n", type);                          continue;                      } -                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d\n", +                    printf("      config %d lang=%c%c cnt=%c%c orien=%d touch=%d density=%d key=%d infl=%d nav=%d w=%d h=%d lyt=%d\n",                             (int)configIndex,                             type->config.language[0] ? type->config.language[0] : '-',                             type->config.language[1] ? type->config.language[1] : '-', @@ -3932,7 +3932,8 @@ void ResTable::print(bool inclValues) const                             type->config.inputFlags,                             type->config.navigation,                             dtohs(type->config.screenWidth), -                           dtohs(type->config.screenHeight)); +                           dtohs(type->config.screenHeight), +                           type->config.screenLayout);                      size_t entryCount = dtohl(type->entryCount);                      uint32_t entriesStart = dtohl(type->entriesStart);                      if ((entriesStart&0x3) != 0) { diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java index fef3598..68bf4fb 100644 --- a/services/java/com/android/server/Watchdog.java +++ b/services/java/com/android/server/Watchdog.java @@ -504,6 +504,7 @@ public class Watchdog extends Thread {                  if (mPhoneMemMonitor.checkLocked(curTime, mPhonePid,                          mPhonePss)) {                      // Just kill the phone process and let it restart. +                    Log.i(TAG, "Watchdog is killing the phone process");                      Process.killProcess(mPhonePid);                  }              } else { @@ -848,6 +849,7 @@ public class Watchdog extends Thread {              // Only kill the process if the debugger is not attached.              if (!Debug.isDebuggerConnected()) { +                Log.i(TAG, "Watchdog is killing the system process");                  Process.killProcess(Process.myPid());              }          } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 3b47ae7..5ea7504 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -77,6 +77,7 @@ import android.os.SystemClock;  import android.os.SystemProperties;  import android.os.TokenWatcher;  import android.provider.Settings; +import android.util.DisplayMetrics;  import android.util.EventLog;  import android.util.Log;  import android.util.SparseIntArray; @@ -415,7 +416,8 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo      final Rect mTempRect = new Rect();      final Configuration mTempConfiguration = new Configuration(); - +    int screenLayout = Configuration.SCREENLAYOUT_UNDEFINED; +          public static WindowManagerService main(Context context,              PowerManagerService pm, boolean haveInputMethods) {          WMThread thr = new WMThread(context, pm, haveInputMethods); @@ -3724,6 +3726,40 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo              orientation = Configuration.ORIENTATION_LANDSCAPE;          }          config.orientation = orientation; +         +        if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) { +            // Note we only do this once because at this point we don't +            // expect the screen to change in this way at runtime, and want +            // to avoid all of this computation for every config change. +            DisplayMetrics dm = new DisplayMetrics(); +            mDisplay.getMetrics(dm); +            int longSize = dw; +            int shortSize = dh; +            if (longSize < shortSize) { +                int tmp = longSize; +                longSize = shortSize; +                shortSize = tmp; +            } +            longSize = (int)(longSize/dm.density); +            shortSize = (int)(shortSize/dm.density); +             +            // These semi-magic numbers define our compatibility modes for +            // applications with different screens.  Don't change unless you +            // make sure to test lots and lots of apps! +            if (longSize < 470) { +                // This is shorter than an HVGA normal density screen (which +                // is 480 pixels on its long side). +                screenLayout = Configuration.SCREENLAYOUT_SMALL; +            } else if (longSize > 490 && shortSize > 330) { +                // This is larger than an HVGA normal density screen (which +                // is 480x320 pixels). +                screenLayout = Configuration.SCREENLAYOUT_LARGE; +            } else { +                screenLayout = Configuration.SCREENLAYOUT_NORMAL; +            } +        } +        config.screenLayout = screenLayout; +                  config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;          config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;          mPolicy.adjustConfigurationLw(config); diff --git a/tests/DpiTest/AndroidManifest.xml b/tests/DpiTest/AndroidManifest.xml index f71cff2..64ad7be 100644 --- a/tests/DpiTest/AndroidManifest.xml +++ b/tests/DpiTest/AndroidManifest.xml @@ -16,6 +16,8 @@  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.google.android.test.dpi"> +    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="3" /> +    <supports-screens android:smallScreens="true" />      <application android:label="DpiTest">          <activity android:name="DpiTestActivity" android:label="DpiTest">              <intent-filter> diff --git a/tests/DpiTest/res/values-largeScreen/strings.xml b/tests/DpiTest/res/values-largeScreen/strings.xml new file mode 100644 index 0000000..f4dd543 --- /dev/null +++ b/tests/DpiTest/res/values-largeScreen/strings.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + +     Licensed under the Apache License, Version 2.0 (the "License"); +     you may not use this file except in compliance with the License. +     You may obtain a copy of the License at +   +          http://www.apache.org/licenses/LICENSE-2.0 +   +     Unless required by applicable law or agreed to in writing, software +     distributed under the License is distributed on an "AS IS" BASIS, +     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +     See the License for the specific language governing permissions and +     limitations under the License. +--> + +<resources> +    <string name="act_title">DpiTest: Large Screen</string> +</resources> diff --git a/tests/DpiTest/res/values-normalScreen/strings.xml b/tests/DpiTest/res/values-normalScreen/strings.xml new file mode 100644 index 0000000..256d696 --- /dev/null +++ b/tests/DpiTest/res/values-normalScreen/strings.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + +     Licensed under the Apache License, Version 2.0 (the "License"); +     you may not use this file except in compliance with the License. +     You may obtain a copy of the License at +   +          http://www.apache.org/licenses/LICENSE-2.0 +   +     Unless required by applicable law or agreed to in writing, software +     distributed under the License is distributed on an "AS IS" BASIS, +     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +     See the License for the specific language governing permissions and +     limitations under the License. +--> + +<resources> +    <string name="act_title">DpiTest: Normal Screen</string> +</resources> diff --git a/tests/DpiTest/res/values-smallScreen/strings.xml b/tests/DpiTest/res/values-smallScreen/strings.xml new file mode 100644 index 0000000..cdb4ac9 --- /dev/null +++ b/tests/DpiTest/res/values-smallScreen/strings.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + +     Licensed under the Apache License, Version 2.0 (the "License"); +     you may not use this file except in compliance with the License. +     You may obtain a copy of the License at +   +          http://www.apache.org/licenses/LICENSE-2.0 +   +     Unless required by applicable law or agreed to in writing, software +     distributed under the License is distributed on an "AS IS" BASIS, +     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +     See the License for the specific language governing permissions and +     limitations under the License. +--> + +<resources> +    <string name="act_title">DpiTest: Small Screen</string> +</resources> diff --git a/tests/DpiTest/res/values/strings.xml b/tests/DpiTest/res/values/strings.xml new file mode 100644 index 0000000..ef924ac --- /dev/null +++ b/tests/DpiTest/res/values/strings.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + +     Licensed under the Apache License, Version 2.0 (the "License"); +     you may not use this file except in compliance with the License. +     You may obtain a copy of the License at +   +          http://www.apache.org/licenses/LICENSE-2.0 +   +     Unless required by applicable law or agreed to in writing, software +     distributed under the License is distributed on an "AS IS" BASIS, +     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +     See the License for the specific language governing permissions and +     limitations under the License. +--> + +<resources> +    <string name="act_title">DpiTest: Unknown Screen</string> +</resources> 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 3759622..5a9f3f5 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 6bc1ee6..67af116 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<String8> 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 01c8140..3b96412 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 503f661..e04491d 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -329,6 +329,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) { @@ -499,6 +502,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; @@ -572,8 +579,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); @@ -585,8 +594,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") { @@ -625,6 +638,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; @@ -733,6 +753,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<String8> 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 1fa11af..06dd96f 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;      }  } | 
