summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-03-30 16:20:26 -0700
committerDianne Hackborn <hackbod@google.com>2011-04-06 11:00:37 -0700
commit3fc982f41fda1f254bfbc35490d81cd82a0ed90a (patch)
tree6f9ba92dc2c9001a156f298c37dcdef9c9552600
parentfb84ce0df6b2db84981e4efa4530397a85240d4a (diff)
downloadframeworks_base-3fc982f41fda1f254bfbc35490d81cd82a0ed90a.zip
frameworks_base-3fc982f41fda1f254bfbc35490d81cd82a0ed90a.tar.gz
frameworks_base-3fc982f41fda1f254bfbc35490d81cd82a0ed90a.tar.bz2
Add new resource configurations for screen width/height in "dp".
You can now specify resource configuration variants "wNNNdp" and "hNNNdp". These are the minimum screen width/height in "dp" units. This allows you to do things like have your app adjust its layout based only on the about of horizontal space available. This introduces a new configuration change flag for screen size. Note that this configuration change happens each time the orientation changes. Applications often say they handle the orientation change to avoid being restarted at a screen rotation, and this will now cause them to be restarted. To address this, we assume the app can handle this new config change if its target SDK version is < ICS. Change-Id: I22f8afa136b4f274423978c570fa7c9855040496
-rw-r--r--api/current.xml66
-rw-r--r--core/java/android/content/pm/ActivityInfo.java37
-rw-r--r--core/java/android/content/pm/PackageParser.java8
-rw-r--r--core/java/android/content/res/AssetManager.java3
-rw-r--r--core/java/android/content/res/Configuration.java57
-rwxr-xr-xcore/java/android/content/res/Resources.java3
-rw-r--r--core/java/android/os/Build.java5
-rw-r--r--core/jni/android_util_AssetManager.cpp5
-rw-r--r--core/res/res/values/attrs_manifest.xml5
-rw-r--r--docs/html/guide/topics/resources/providing-resources.jd40
-rw-r--r--include/utils/ResourceTypes.h67
-rw-r--r--libs/utils/ResourceTypes.cpp31
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--tools/aapt/AaptAssets.cpp115
-rw-r--r--tools/aapt/AaptAssets.h7
-rw-r--r--tools/aapt/ResourceTable.cpp24
16 files changed, 447 insertions, 29 deletions
diff --git a/api/current.xml b/api/current.xml
index 1f3b5fd..22d82ce 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -57955,6 +57955,17 @@
visibility="public"
>
</field>
+<field name="CONFIG_SCREEN_SIZE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="CONFIG_TOUCHSCREEN"
type="int"
transient="false"
@@ -64017,6 +64028,28 @@
visibility="public"
>
</field>
+<field name="SCREEN_HEIGHT_DP_UNDEFINED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREEN_WIDTH_DP_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"
@@ -64260,6 +64293,16 @@
visibility="public"
>
</field>
+<field name="screenHeightDp"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="screenLayout"
type="int"
transient="false"
@@ -64270,6 +64313,16 @@
visibility="public"
>
</field>
+<field name="screenWidthDp"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="touchscreen"
type="int"
transient="false"
@@ -144074,6 +144127,17 @@
visibility="public"
>
</field>
+<field name="ICE_CREAM_SANDWICH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10000"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Bundle"
extends="java.lang.Object"
@@ -267777,7 +267841,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 46f611f..64c437d 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -334,6 +334,12 @@ public class ActivityInfo extends ComponentInfo
public static final int CONFIG_UI_MODE = 0x0200;
/**
* Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle the screen size. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_SCREEN_SIZE = 0x0400;
+ /**
+ * 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
@@ -341,6 +347,37 @@ public class ActivityInfo extends ComponentInfo
*/
public static final int CONFIG_FONT_SCALE = 0x40000000;
+ /** @hide
+ * Unfortunately the constants for config changes in native code are
+ * different from ActivityInfo. :( Here are the values we should use for the
+ * native side given the bit we have assigned in ActivityInfo.
+ */
+ public static int[] CONFIG_NATIVE_BITS = new int[] {
+ 0x0001, // MNC
+ 0x0002, // MCC
+ 0x0004, // LOCALE
+ 0x0008, // TOUCH SCREEN
+ 0x0010, // KEYBOARD
+ 0x0020, // KEYBOARD HIDDEN
+ 0x0040, // NAVIGATION
+ 0x0080, // ORIENTATION
+ 0x0800, // SCREEN LAYOUT
+ 0x1000, // UI MODE
+ 0x0200, // SCREEN SIZE
+ };
+ /** @hide
+ * Convert Java change bits to native.
+ */
+ public static int activityInfoConfigToNative(int input) {
+ int output = 0;
+ for (int i=0; i<CONFIG_NATIVE_BITS.length; i++) {
+ if ((input&(1<<i)) != 0) {
+ output |= CONFIG_NATIVE_BITS[i];
+ }
+ }
+ return output;
+ }
+
/**
* Bit mask of kinds of configuration changes that this activity
* can handle itself (without being restarted by the system).
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 7ebfda4..8dfdaa8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -396,7 +396,7 @@ public class PackageParser {
int cookie = assmgr.addAssetPath(mArchiveSourcePath);
if (cookie != 0) {
res = new Resources(assmgr, metrics, null);
- assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Build.VERSION.RESOURCES_SDK_INT);
parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
assetError = false;
@@ -596,7 +596,7 @@ public class PackageParser {
AssetManager assmgr = null;
try {
assmgr = new AssetManager();
- assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Build.VERSION.RESOURCES_SDK_INT);
int cookie = assmgr.addAssetPath(packageFilePath);
parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
@@ -1931,6 +1931,10 @@ public class PackageParser {
a.info.configChanges = sa.getInt(
com.android.internal.R.styleable.AndroidManifestActivity_configChanges,
0);
+ if (owner.applicationInfo.targetSdkVersion
+ < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ a.info.configChanges |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ }
a.info.softInputMode = sa.getInt(
com.android.internal.R.styleable.AndroidManifestActivity_windowSoftInputMode,
0);
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index e279f64..afa68c3 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -652,7 +652,8 @@ 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 screenLayout, int uiMode, int majorVersion);
+ int screenWidthDp, int screenHeightDp, int screenLayout, int uiMode,
+ int majorVersion);
/**
* Retrieve the resource identifier for the given resource name.
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 72fa07c..28ba4e7 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -241,6 +241,20 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*/
public int uiMode;
+ public static final int SCREEN_WIDTH_DP_UNDEFINED = 0;
+
+ /**
+ * The current width of the available screen space, in dp units.
+ */
+ public int screenWidthDp;
+
+ public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0;
+
+ /**
+ * The current height of the available screen space, in dp units.
+ */
+ public int screenHeightDp;
+
/**
* @hide Internal book-keeping.
*/
@@ -278,6 +292,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
orientation = o.orientation;
screenLayout = o.screenLayout;
uiMode = o.uiMode;
+ screenWidthDp = o.screenWidthDp;
+ screenHeightDp = o.screenHeightDp;
seq = o.seq;
}
@@ -316,6 +332,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
sb.append(java.lang.Integer.toHexString(screenLayout));
sb.append(" uiMode=0x");
sb.append(java.lang.Integer.toHexString(uiMode));
+ sb.append(" wdp=");
+ sb.append(screenWidthDp);
+ sb.append(" hdp=");
+ sb.append(screenHeightDp);
if (seq != 0) {
sb.append(" seq=");
sb.append(seq);
@@ -341,6 +361,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
orientation = ORIENTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_SIZE_UNDEFINED;
uiMode = UI_MODE_TYPE_UNDEFINED;
+ screenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
+ screenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
seq = 0;
}
@@ -434,6 +456,16 @@ public final class Configuration implements Parcelable, Comparable<Configuration
| (delta.uiMode&UI_MODE_NIGHT_MASK);
}
}
+ if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
+ && screenWidthDp != delta.screenWidthDp) {
+ changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ screenWidthDp = delta.screenWidthDp;
+ }
+ if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
+ && screenHeightDp != delta.screenHeightDp) {
+ changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ screenHeightDp = delta.screenHeightDp;
+ }
if (delta.seq != 0) {
seq = delta.seq;
@@ -463,9 +495,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
* {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
* PackageManager.ActivityInfo.CONFIG_NAVIGATION},
* {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
- * PackageManager.ActivityInfo.CONFIG_ORIENTATION}, or
+ * PackageManager.ActivityInfo.CONFIG_ORIENTATION},
* {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_LAYOUT
- * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}.
+ * PackageManager.ActivityInfo.CONFIG_SCREEN_LAYOUT}, or
+ * {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE
+ * PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}.
*/
public int diff(Configuration delta) {
int changed = 0;
@@ -518,6 +552,14 @@ public final class Configuration implements Parcelable, Comparable<Configuration
&& uiMode != delta.uiMode) {
changed |= ActivityInfo.CONFIG_UI_MODE;
}
+ if (delta.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
+ && screenWidthDp != delta.screenWidthDp) {
+ changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ }
+ if (delta.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED
+ && screenHeightDp != delta.screenHeightDp) {
+ changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ }
return changed;
}
@@ -599,6 +641,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
dest.writeInt(orientation);
dest.writeInt(screenLayout);
dest.writeInt(uiMode);
+ dest.writeInt(screenWidthDp);
+ dest.writeInt(screenHeightDp);
dest.writeInt(seq);
}
@@ -620,6 +664,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
orientation = source.readInt();
screenLayout = source.readInt();
uiMode = source.readInt();
+ screenWidthDp = source.readInt();
+ screenHeightDp = source.readInt();
seq = source.readInt();
}
@@ -680,6 +726,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
n = this.screenLayout - that.screenLayout;
if (n != 0) return n;
n = this.uiMode - that.uiMode;
+ if (n != 0) return n;
+ n = this.screenWidthDp - that.screenWidthDp;
+ if (n != 0) return n;
+ n = this.screenHeightDp - that.screenHeightDp;
//if (n != 0) return n;
return n;
}
@@ -704,6 +754,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
+ this.touchscreen
+ this.keyboard + this.keyboardHidden + this.hardKeyboardHidden
+ this.navigation + this.navigationHidden
- + this.orientation + this.screenLayout + this.uiMode;
+ + this.orientation + this.screenLayout + this.uiMode
+ + this.screenWidthDp + this.screenHeightDp;
}
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 81eb09c..2e6ae70 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -21,6 +21,7 @@ import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.content.pm.ActivityInfo;
import android.graphics.Movie;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ColorDrawable;
@@ -1404,6 +1405,7 @@ public class Resources {
int configChanges = 0xfffffff;
if (config != null) {
configChanges = mConfiguration.updateFrom(config);
+ configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
}
if (mConfiguration.locale == null) {
mConfiguration.locale = Locale.getDefault();
@@ -1443,6 +1445,7 @@ public class Resources {
mConfiguration.touchscreen,
(int)(mMetrics.density*160), mConfiguration.keyboard,
keyboardHidden, mConfiguration.navigation, width, height,
+ mConfiguration.screenWidthDp, mConfiguration.screenHeightDp,
mConfiguration.screenLayout, mConfiguration.uiMode,
Build.VERSION.RESOURCES_SDK_INT);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 3bb0821..24d5369 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -230,6 +230,11 @@ public class Build {
* Newest version of Android, version 3.1.
*/
public static final int HONEYCOMB_MR1 = 12;
+
+ /**
+ * Current version under development.
+ */
+ public static final int ICE_CREAM_SANDWICH = CUR_DEVELOPMENT;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index fdb7fda..65b5990 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -532,6 +532,7 @@ static void android_content_AssetManager_setConfiguration(JNIEnv* env, jobject c
jint keyboard, jint keyboardHidden,
jint navigation,
jint screenWidth, jint screenHeight,
+ jint screenWidthDp, jint screenHeightDp,
jint screenLayout, jint uiMode,
jint sdkVersion)
{
@@ -555,6 +556,8 @@ 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.screenWidthDp = (uint16_t)screenWidthDp;
+ config.screenHeightDp = (uint16_t)screenHeightDp;
config.screenLayout = (uint8_t)screenLayout;
config.uiMode = (uint8_t)uiMode;
config.sdkVersion = (uint16_t)sdkVersion;
@@ -1693,7 +1696,7 @@ static JNINativeMethod gAssetManagerMethods[] = {
(void*) android_content_AssetManager_setLocale },
{ "getLocales", "()[Ljava/lang/String;",
(void*) android_content_AssetManager_getLocales },
- { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIII)V",
+ { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIII)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 e8f30ad..80beaa5 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -590,6 +590,11 @@
<!-- The global user interface mode has changed. For example,
going in or out of car mode, night mode changing, etc. -->
<flag name="uiMode" value="0x0200" />
+ <!-- The physical screen size has changed. If applications don't
+ target at least {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}
+ then the activity will always handle this itself (the change
+ will not result in a restart). -->
+ <flag name="screenSize" value="0x0400" />
<!-- The font scaling factor has changed, that is the user has
selected a new global font size. -->
<flag name="fontScale" value="0x40000000" />
diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd
index 1da2622..10d25bb 100644
--- a/docs/html/guide/topics/resources/providing-resources.jd
+++ b/docs/html/guide/topics/resources/providing-resources.jd
@@ -383,6 +383,46 @@ is not related to the screen orientation.</p>
which indicates whether the screen is long.</p>
</td>
</tr>
+ <tr id="ScreenWidthQualifier">
+ <td>Screen width</td>
+ <td>Examples:<br/>
+ <code>w720dp</code><br/>
+ <code>w1024dp</code><br/>
+ etc.
+ </td>
+ <td>
+ <p>Specifies a minimum screen width, in "dp" units, at which the resource
+ should be used. This configuration value will change when the orientation
+ changes between landscape and portrait to match the current actual width.
+ When multiple screen width configurations are available, the closest to
+ the current screen width will be used. The value specified here is
+ approximate; screen decorations like a status bar or system bar may cause
+ the actual space available in your UI to be slightly smaller.
+ <p><em>Added in API Level 13.</em></p>
+ <p>Also see the {@link android.content.res.Configuration#screenWidthDp}
+ configuration field, which holds the current screen width.</p>
+ </td>
+ </tr>
+ <tr id="ScreenHeightQualifier">
+ <td>Screen height</td>
+ <td>Examples:<br/>
+ <code>h720dp</code><br/>
+ <code>h1024dp</code><br/>
+ etc.
+ </td>
+ <td>
+ <p>Specifies a minimum screen height, in "dp" units, at which the resource
+ should be used. This configuration value will change when the orientation
+ changes between landscape and portrait to match the current actual height.
+ When multiple screen height configurations are available, the closest to
+ the current screen height will be used. The value specified here is
+ approximate; screen decorations like a status bar or system bar may cause
+ the actual space available in your UI to be slightly smaller.
+ <p><em>Added in API Level 13.</em></p>
+ <p>Also see the {@link android.content.res.Configuration#screenHeightDp}
+ configuration field, which holds the current screen width.</p>
+ </td>
+ </tr>
<tr id="OrientationQualifier">
<td>Screen orientation</td>
<td>
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 6227f3e..35792dc 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -972,6 +972,14 @@ struct ResTable_config
uint32_t screenConfig;
};
+ union {
+ struct {
+ uint16_t screenWidthDp;
+ uint16_t screenHeightDp;
+ };
+ uint32_t screenSizeDp;
+ };
+
inline void copyFromDeviceNoSwap(const ResTable_config& o) {
const size_t size = dtohl(o.size);
if (size >= sizeof(ResTable_config)) {
@@ -992,6 +1000,8 @@ struct ResTable_config
screenHeight = dtohs(screenHeight);
sdkVersion = dtohs(sdkVersion);
minorVersion = dtohs(minorVersion);
+ screenWidthDp = dtohs(screenWidthDp);
+ screenHeightDp = dtohs(screenHeightDp);
}
inline void swapHtoD() {
@@ -1003,6 +1013,8 @@ struct ResTable_config
screenHeight = htods(screenHeight);
sdkVersion = htods(sdkVersion);
minorVersion = htods(minorVersion);
+ screenWidthDp = htods(screenWidthDp);
+ screenHeightDp = htods(screenHeightDp);
}
inline int compare(const ResTable_config& o) const {
@@ -1021,6 +1033,8 @@ struct ResTable_config
diff = (int32_t)(screenLayout - o.screenLayout);
if (diff != 0) return diff;
diff = (int32_t)(uiMode - o.uiMode);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenSizeDp - o.screenSizeDp);
return (int)diff;
}
@@ -1061,6 +1075,7 @@ struct ResTable_config
if (version != o.version) diffs |= CONFIG_VERSION;
if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT;
if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE;
+ if (screenSizeDp != o.screenSizeDp) diffs |= CONFIG_SCREEN_SIZE;
return diffs;
}
@@ -1105,6 +1120,18 @@ struct ResTable_config
}
}
+ if (screenSizeDp || o.screenSizeDp) {
+ if (screenWidthDp != o.screenWidthDp) {
+ if (!screenWidthDp) return false;
+ if (!o.screenWidthDp) return true;
+ }
+
+ if (screenHeightDp != o.screenHeightDp) {
+ if (!screenHeightDp) return false;
+ if (!o.screenHeightDp) return true;
+ }
+ }
+
if (orientation != o.orientation) {
if (!orientation) return false;
if (!o.orientation) return true;
@@ -1243,6 +1270,30 @@ struct ResTable_config
}
}
+ if (screenSizeDp || o.screenSizeDp) {
+ // Better is based on the sum of the difference between both
+ // width and height from the requested dimensions. We are
+ // assuming the invalid configs (with smaller dimens) have
+ // already been filtered. Note that if a particular dimension
+ // is unspecified, we will end up with a large value (the
+ // difference between 0 and the requested dimension), which is
+ // good since we will prefer a config that has specified a
+ // dimension value.
+ int myDelta = 0, otherDelta = 0;
+ if (requested->screenWidthDp) {
+ myDelta += requested->screenWidthDp - screenWidthDp;
+ otherDelta += requested->screenWidthDp - o.screenWidthDp;
+ }
+ if (requested->screenHeightDp) {
+ myDelta += requested->screenHeightDp - screenHeightDp;
+ otherDelta += requested->screenHeightDp - o.screenHeightDp;
+ }
+ //LOGI("Comparing this %dx%d to other %dx%d in %dx%d: myDelta=%d otherDelta=%d",
+ // screenWidthDp, screenHeightDp, o.screenWidthDp, o.screenHeightDp,
+ // requested->screenWidthDp, requested->screenHeightDp, myDelta, otherDelta);
+ return (myDelta <= otherDelta);
+ }
+
if ((orientation != o.orientation) && requested->orientation) {
return (orientation);
}
@@ -1426,6 +1477,18 @@ struct ResTable_config
return false;
}
}
+ if (screenSizeDp != 0) {
+ if (settings.screenWidthDp != 0 && screenWidthDp != 0
+ && screenWidthDp > settings.screenWidthDp) {
+ //LOGI("Filtering out width %d in requested %d", screenWidthDp, settings.screenWidthDp);
+ return false;
+ }
+ if (settings.screenHeightDp != 0 && screenHeightDp != 0
+ && screenHeightDp > settings.screenHeightDp) {
+ //LOGI("Filtering out height %d in requested %d", screenHeightDp, settings.screenHeightDp);
+ return false;
+ }
+ }
if (screenType != 0) {
if (settings.orientation != 0 && orientation != 0
&& orientation != settings.orientation) {
@@ -1505,13 +1568,13 @@ struct ResTable_config
String8 toString() const {
char buf[200];
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 sz=%d long=%d "
+ "kbd=%d nav=%d input=%d ssz=%dx%d %ddp x %ddp sz=%d long=%d "
"ui=%d night=%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,
+ screenWidth, screenHeight, screenWidthDp, screenHeightDp,
screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG,
uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT,
sdkVersion, minorVersion);
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 7197ad7..ac9cdf9 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -2424,7 +2424,7 @@ void ResTable::setParameters(const ResTable_config* params)
{
mLock.lock();
TABLE_GETENTRY(LOGI("Setting parameters: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+ "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
params->mcc, params->mnc,
params->language[0] ? params->language[0] : '-',
params->language[1] ? params->language[1] : '-',
@@ -2437,7 +2437,9 @@ void ResTable::setParameters(const ResTable_config* params)
params->inputFlags,
params->navigation,
params->screenWidth,
- params->screenHeight));
+ params->screenHeight,
+ params->screenWidthDp,
+ params->screenHeightDp));
mParams = *params;
for (size_t i=0; i<mPackageGroups.size(); i++) {
TABLE_NOISY(LOGI("CLEARING BAGS FOR GROUP %d!", i));
@@ -3758,8 +3760,10 @@ ssize_t ResTable::getEntry(
ResTable_config thisConfig;
thisConfig.copyFromDtoH(thisType->config);
- TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c "
- "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n",
+ TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d "
+ "lang:%c%c=%c%c cnt:%c%c=%c%c orien:%d=%d touch:%d=%d "
+ "density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d "
+ "wdp:%d=%d hdp:%d=%d\n",
entryIndex, typeIndex+1, dtohl(thisType->config.size),
thisConfig.mcc, thisConfig.mnc,
config ? config->mcc : 0, config ? config->mnc : 0,
@@ -3786,7 +3790,11 @@ ssize_t ResTable::getEntry(
thisConfig.screenWidth,
config ? config->screenWidth : 0,
thisConfig.screenHeight,
- config ? config->screenHeight : 0));
+ config ? config->screenHeight : 0,
+ thisConfig.screenWidthDp,
+ config ? config->screenWidthDp : 0,
+ thisConfig.screenHeightDp,
+ config ? config->screenHeightDp : 0));
// Check to make sure this one is valid for the current parameters.
if (config && !thisConfig.match(*config)) {
@@ -4067,7 +4075,8 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
ResTable_config thisConfig;
thisConfig.copyFromDtoH(type->config);
LOGI("Adding config to type %d: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+ "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d "
+ "wdp:%d hdp:%d\n",
type->id,
thisConfig.mcc, thisConfig.mnc,
thisConfig.language[0] ? thisConfig.language[0] : '-',
@@ -4081,7 +4090,9 @@ status_t ResTable::parsePackage(const ResTable_package* const pkg,
thisConfig.inputFlags,
thisConfig.navigation,
thisConfig.screenWidth,
- thisConfig.screenHeight));
+ thisConfig.screenHeight,
+ thisConfig.screenWidthDp,
+ thisConfig.screenHeightDp));
t->configs.add(type);
} else {
status_t err = validate_chunk(chunk, sizeof(ResChunk_header),
@@ -4444,6 +4455,12 @@ void ResTable::print(bool inclValues) const
if (type->config.screenHeight != 0) {
printf(" h=%d", dtohs(type->config.screenHeight));
}
+ if (type->config.screenWidthDp != 0) {
+ printf(" wdp=%d", dtohs(type->config.screenWidthDp));
+ }
+ if (type->config.screenHeightDp != 0) {
+ printf(" hdp=%d", dtohs(type->config.screenHeightDp));
+ }
if (type->config.sdkVersion != 0) {
printf(" sdk=%d", dtohs(type->config.sdkVersion));
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 79c4518..e2874f8 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5453,6 +5453,9 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplay.getMetrics(dm);
CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
+ config.screenWidthDp = (int)(dm.widthPixels / dm.density);
+ config.screenHeightDp = (int)(dm.heightPixels / dm.density);
+
if (mScreenLayout == Configuration.SCREENLAYOUT_SIZE_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
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 2b2ec7b..a2271d9 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -156,6 +156,20 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value)
return 0;
}
+ // screen dp width
+ if (getScreenWidthDpName(part.string(), &config)) {
+ *axis = AXIS_SCREENWIDTHDP;
+ *value = config.screenWidthDp;
+ return 0;
+ }
+
+ // screen dp height
+ if (getScreenHeightDpName(part.string(), &config)) {
+ *axis = AXIS_SCREENHEIGHTDP;
+ *value = config.screenHeightDp;
+ return 0;
+ }
+
// orientation
if (getOrientationName(part.string(), &config)) {
*axis = AXIS_ORIENTATION;
@@ -243,7 +257,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
String8 touch, key, keysHidden, nav, navHidden, size, vers;
- String8 uiModeType, uiModeNight;
+ String8 uiModeType, uiModeNight, widthdp, heightdp;
const char *p = dir;
const char *q;
@@ -354,6 +368,30 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
//printf("not screen layout long: %s\n", part.string());
}
+ if (getScreenWidthDpName(part.string())) {
+ widthdp = part;
+
+ index++;
+ if (index == N) {
+ goto success;
+ }
+ part = parts[index];
+ } else {
+ //printf("not screen width dp: %s\n", part.string());
+ }
+
+ if (getScreenHeightDpName(part.string())) {
+ heightdp = part;
+
+ index++;
+ if (index == N) {
+ goto success;
+ }
+ part = parts[index];
+ } else {
+ //printf("not screen height dp: %s\n", part.string());
+ }
+
// orientation
if (getOrientationName(part.string())) {
orient = part;
@@ -503,6 +541,8 @@ success:
this->locale = loc;
this->screenLayoutSize = layoutsize;
this->screenLayoutLong = layoutlong;
+ this->screenWidthDp = widthdp;
+ this->screenHeightDp = heightdp;
this->orientation = orient;
this->uiModeType = uiModeType;
this->uiModeNight = uiModeNight;
@@ -534,6 +574,10 @@ AaptGroupEntry::toString() const
s += ",";
s += screenLayoutLong;
s += ",";
+ s += screenWidthDp;
+ s += ",";
+ s += screenHeightDp;
+ s += ",";
s += this->orientation;
s += ",";
s += uiModeType;
@@ -582,6 +626,14 @@ AaptGroupEntry::toDirName(const String8& resType) const
s += "-";
s += screenLayoutLong;
}
+ if (this->screenWidthDp != "") {
+ s += "-";
+ s += screenWidthDp;
+ }
+ if (this->screenHeightDp != "") {
+ s += "-";
+ s += screenHeightDp;
+ }
if (this->orientation != "") {
s += "-";
s += orientation;
@@ -1039,8 +1091,7 @@ bool AaptGroupEntry::getNavigationName(const char* name,
return false;
}
-bool AaptGroupEntry::getScreenSizeName(const char* name,
- ResTable_config* out)
+bool AaptGroupEntry::getScreenSizeName(const char* name, ResTable_config* out)
{
if (strcmp(name, kWildcardName) == 0) {
if (out) {
@@ -1075,8 +1126,53 @@ bool AaptGroupEntry::getScreenSizeName(const char* name,
return true;
}
-bool AaptGroupEntry::getVersionName(const char* name,
- ResTable_config* out)
+bool AaptGroupEntry::getScreenWidthDpName(const char* name, ResTable_config* out)
+{
+ if (strcmp(name, kWildcardName) == 0) {
+ if (out) {
+ out->screenWidthDp = out->SCREENWIDTH_ANY;
+ }
+ return true;
+ }
+
+ if (*name != 'w') return false;
+ name++;
+ const char* x = name;
+ while (*x >= '0' && *x <= '9') x++;
+ if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+ String8 xName(name, x-name);
+
+ if (out) {
+ out->screenWidthDp = (uint16_t)atoi(xName.string());
+ }
+
+ return true;
+}
+
+bool AaptGroupEntry::getScreenHeightDpName(const char* name, ResTable_config* out)
+{
+ if (strcmp(name, kWildcardName) == 0) {
+ if (out) {
+ out->screenHeightDp = out->SCREENWIDTH_ANY;
+ }
+ return true;
+ }
+
+ if (*name != 'h') return false;
+ name++;
+ const char* x = name;
+ while (*x >= '0' && *x <= '9') x++;
+ if (x == name || x[0] != 'd' || x[1] != 'p' || x[2] != 0) return false;
+ String8 xName(name, x-name);
+
+ if (out) {
+ out->screenHeightDp = (uint16_t)atoi(xName.string());
+ }
+
+ return true;
+}
+
+bool AaptGroupEntry::getVersionName(const char* name, ResTable_config* out)
{
if (strcmp(name, kWildcardName) == 0) {
if (out) {
@@ -1112,6 +1208,8 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const
if (v == 0) v = vendor.compare(o.vendor);
if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize);
if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong);
+ if (v == 0) v = screenWidthDp.compare(o.screenWidthDp);
+ if (v == 0) v = screenHeightDp.compare(o.screenHeightDp);
if (v == 0) v = orientation.compare(o.orientation);
if (v == 0) v = uiModeType.compare(o.uiModeType);
if (v == 0) v = uiModeNight.compare(o.uiModeNight);
@@ -1135,6 +1233,8 @@ ResTable_config AaptGroupEntry::toParams() const
getLocaleName(locale.string(), &params);
getScreenLayoutSizeName(screenLayoutSize.string(), &params);
getScreenLayoutLongName(screenLayoutLong.string(), &params);
+ getScreenWidthDpName(screenWidthDp.string(), &params);
+ getScreenHeightDpName(screenHeightDp.string(), &params);
getOrientationName(orientation.string(), &params);
getUiModeTypeName(uiModeType.string(), &params);
getUiModeNightName(uiModeNight.string(), &params);
@@ -1149,7 +1249,10 @@ ResTable_config AaptGroupEntry::toParams() const
// Fix up version number based on specified parameters.
int minSdk = 0;
- if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE)
+ if (params.screenWidthDp != ResTable_config::SCREENWIDTH_ANY
+ || params.screenHeightDp != ResTable_config::SCREENHEIGHT_ANY) {
+ minSdk = SDK_ICS;
+ } else if ((params.uiMode&ResTable_config::MASK_UI_MODE_TYPE)
!= ResTable_config::UI_MODE_TYPE_ANY
|| (params.uiMode&ResTable_config::MASK_UI_MODE_NIGHT)
!= ResTable_config::UI_MODE_NIGHT_ANY) {
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index eeb00c0..e5afd1b 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -42,6 +42,8 @@ enum {
AXIS_NAVHIDDEN,
AXIS_NAVIGATION,
AXIS_SCREENSIZE,
+ AXIS_SCREENWIDTHDP,
+ AXIS_SCREENHEIGHTDP,
AXIS_VERSION
};
@@ -52,6 +54,7 @@ enum {
SDK_ECLAIR_0_1 = 6,
SDK_MR1 = 7,
SDK_FROYO = 8,
+ SDK_ICS = 13,
};
/**
@@ -71,6 +74,8 @@ public:
String8 vendor;
String8 screenLayoutSize;
String8 screenLayoutLong;
+ String8 screenWidthDp;
+ String8 screenHeightDp;
String8 orientation;
String8 uiModeType;
String8 uiModeNight;
@@ -102,6 +107,8 @@ public:
static bool getNavigationName(const char* name, ResTable_config* out = NULL);
static bool getNavHiddenName(const char* name, ResTable_config* out = NULL);
static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
+ static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL);
+ static bool getScreenHeightDpName(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/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 10815a1..3dcc093 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2607,6 +2607,12 @@ ResourceFilter::match(const ResTable_config& config) const
if (!match(AXIS_SCREENSIZE, config.screenSize)) {
return false;
}
+ if (!match(AXIS_SCREENWIDTHDP, config.screenWidthDp)) {
+ return false;
+ }
+ if (!match(AXIS_SCREENHEIGHTDP, config.screenHeightDp)) {
+ return false;
+ }
if (!match(AXIS_SCREENLAYOUTSIZE, config.screenLayout&ResTable_config::MASK_SCREENSIZE)) {
return false;
}
@@ -2803,7 +2809,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
ConfigDescription config = t->getUniqueConfigs().itemAt(ci);
NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+ "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
ti+1,
config.mcc, config.mnc,
config.language[0] ? config.language[0] : '-',
@@ -2818,7 +2824,9 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
config.inputFlags,
config.navigation,
config.screenWidth,
- config.screenHeight));
+ config.screenHeight,
+ config.screenWidthDp,
+ config.screenHeightDp));
if (filterable && !filter.match(config)) {
continue;
@@ -2841,7 +2849,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
tHeader->entriesStart = htodl(typeSize);
tHeader->config = config;
NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+ "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
ti+1,
tHeader->config.mcc, tHeader->config.mnc,
tHeader->config.language[0] ? tHeader->config.language[0] : '-',
@@ -2856,7 +2864,9 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
tHeader->config.inputFlags,
tHeader->config.navigation,
tHeader->config.screenWidth,
- tHeader->config.screenHeight));
+ tHeader->config.screenHeight,
+ tHeader->config.screenWidthDp,
+ tHeader->config.screenHeightDp));
tHeader->config.swapHtoD();
// Build the entries inside of this type.
@@ -3438,7 +3448,7 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
if (e == NULL) {
if (config != NULL) {
NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c "
- "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n",
+ "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d %ddp x %ddp\n",
sourcePos.file.string(), sourcePos.line,
config->mcc, config->mnc,
config->language[0] ? config->language[0] : '-',
@@ -3452,7 +3462,9 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
config->inputFlags,
config->navigation,
config->screenWidth,
- config->screenHeight));
+ config->screenHeight,
+ config->screenWidthDp,
+ config->screenHeightDp));
} else {
NOISY(printf("New entry at %s:%d: NULL config\n",
sourcePos.file.string(), sourcePos.line));