summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt12
-rw-r--r--core/java/android/content/pm/ActivityInfo.java12
-rw-r--r--core/java/android/content/res/Configuration.java123
-rwxr-xr-xcore/java/android/content/res/Resources.java2
-rw-r--r--core/java/android/widget/Toast.java2
-rw-r--r--core/java/com/android/internal/app/LocalePicker.java7
-rw-r--r--core/res/res/values/attrs_manifest.xml2
-rw-r--r--include/androidfw/ResourceTypes.h12
-rw-r--r--libs/androidfw/ResourceTypes.cpp40
-rw-r--r--native/android/configuration.cpp10
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java2
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java4
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java3
-rw-r--r--tools/aapt/AaptAssets.cpp56
-rw-r--r--tools/aapt/AaptAssets.h3
-rw-r--r--tools/aapt/ResourceTable.cpp15
16 files changed, 262 insertions, 43 deletions
diff --git a/api/current.txt b/api/current.txt
index e1d07e2..625d11c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6227,6 +6227,7 @@ package android.content.pm {
field public static final int CONFIG_FONT_SCALE = 1073741824; // 0x40000000
field public static final int CONFIG_KEYBOARD = 16; // 0x10
field public static final int CONFIG_KEYBOARD_HIDDEN = 32; // 0x20
+ field public static final int CONFIG_LAYOUT_DIRECTION = 8192; // 0x2000
field public static final int CONFIG_LOCALE = 4; // 0x4
field public static final int CONFIG_MCC = 1; // 0x1
field public static final int CONFIG_MNC = 2; // 0x2
@@ -6814,9 +6815,12 @@ package android.content.res {
method public int describeContents();
method public int diff(android.content.res.Configuration);
method public boolean equals(android.content.res.Configuration);
+ method public int getLayoutDirection();
method public boolean isLayoutSizeAtLeast(int);
method public static boolean needNewResources(int, int);
method public void readFromParcel(android.os.Parcel);
+ method public void setLayoutDirection(java.util.Locale);
+ method public void setLocale(java.util.Locale);
method public void setTo(android.content.res.Configuration);
method public void setToDefaults();
method public int updateFrom(android.content.res.Configuration);
@@ -6845,6 +6849,11 @@ package android.content.res {
field public static final int ORIENTATION_PORTRAIT = 1; // 0x1
field public static final deprecated int ORIENTATION_SQUARE = 3; // 0x3
field public static final int ORIENTATION_UNDEFINED = 0; // 0x0
+ field public static final int SCREENLAYOUT_LAYOUTDIR_LTR = 64; // 0x40
+ field public static final int SCREENLAYOUT_LAYOUTDIR_MASK = 192; // 0xc0
+ field public static final int SCREENLAYOUT_LAYOUTDIR_RTL = 128; // 0x80
+ field public static final int SCREENLAYOUT_LAYOUTDIR_SHIFT = 6; // 0x6
+ field public static final int SCREENLAYOUT_LAYOUTDIR_UNDEFINED = 0; // 0x0
field public static final int SCREENLAYOUT_LONG_MASK = 48; // 0x30
field public static final int SCREENLAYOUT_LONG_NO = 16; // 0x10
field public static final int SCREENLAYOUT_LONG_UNDEFINED = 0; // 0x0
@@ -6855,6 +6864,7 @@ package android.content.res {
field public static final int SCREENLAYOUT_SIZE_SMALL = 1; // 0x1
field public static final int SCREENLAYOUT_SIZE_UNDEFINED = 0; // 0x0
field public static final int SCREENLAYOUT_SIZE_XLARGE = 4; // 0x4
+ field public static final int SCREENLAYOUT_UNDEFINED = 0; // 0x0
field public static final int SCREEN_HEIGHT_DP_UNDEFINED = 0; // 0x0
field public static final int SCREEN_WIDTH_DP_UNDEFINED = 0; // 0x0
field public static final int SMALLEST_SCREEN_WIDTH_DP_UNDEFINED = 0; // 0x0
@@ -26919,6 +26929,7 @@ package android.webkit {
method public synchronized int getDefaultFixedFontSize();
method public synchronized int getDefaultFontSize();
method public synchronized java.lang.String getDefaultTextEncodingName();
+ method public static java.lang.String getDefaultUserAgent(android.content.Context);
method public android.webkit.WebSettings.ZoomDensity getDefaultZoom();
method public boolean getDisplayZoomControls();
method public synchronized boolean getDomStorageEnabled();
@@ -26949,7 +26960,6 @@ package android.webkit {
method public synchronized boolean getUseWideViewPort();
method public deprecated synchronized int getUserAgent();
method public synchronized java.lang.String getUserAgentString();
- method public static java.lang.String getDefaultUserAgent(android.content.Context);
method public void setAllowContentAccess(boolean);
method public void setAllowFileAccess(boolean);
method public abstract void setAllowFileAccessFromFileURLs(boolean);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 3035729..0b320f0 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -372,6 +372,12 @@ public class ActivityInfo extends ComponentInfo
public static final int CONFIG_DENSITY = 0x1000;
/**
* Bit in {@link #configChanges} that indicates that the activity
+ * can itself handle the change to layout direction. Set from the
+ * {@link android.R.attr#configChanges} attribute.
+ */
+ public static final int CONFIG_LAYOUT_DIRECTION = 0x2000;
+ /**
+ * 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
@@ -398,6 +404,7 @@ public class ActivityInfo extends ComponentInfo
0x0200, // SCREEN SIZE
0x2000, // SMALLEST SCREEN SIZE
0x0100, // DENSITY
+ 0x4000, // LAYOUT DIRECTION
};
/** @hide
* Convert Java change bits to native.
@@ -434,8 +441,9 @@ public class ActivityInfo extends ComponentInfo
* {@link #CONFIG_MCC}, {@link #CONFIG_MNC},
* {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN},
* {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION},
- * {@link #CONFIG_ORIENTATION}, and {@link #CONFIG_SCREEN_LAYOUT}. Set from the
- * {@link android.R.attr#configChanges} attribute.
+ * {@link #CONFIG_ORIENTATION}, {@link #CONFIG_SCREEN_LAYOUT} and
+ * {@link #CONFIG_LAYOUT_DIRECTION}. Set from the {@link android.R.attr#configChanges}
+ * attribute.
*/
public int configChanges;
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 52b6498..0b77842 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -125,7 +125,25 @@ public final class Configuration implements Parcelable, Comparable<Configuration
* <a href="{@docRoot}guide/topics/resources/providing-resources.html#ScreenAspectQualifier">long</a>
* resource qualifier. */
public static final int SCREENLAYOUT_LONG_YES = 0x20;
-
+
+ /** Constant for {@link #screenLayout}: bits that encode the layout direction. */
+ public static final int SCREENLAYOUT_LAYOUTDIR_MASK = 0xC0;
+ /** Constant for {@link #screenLayout}: bits shift to get the layout direction. */
+ public static final int SCREENLAYOUT_LAYOUTDIR_SHIFT = 6;
+ /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
+ * value indicating that no layout dir has been set. */
+ public static final int SCREENLAYOUT_LAYOUTDIR_UNDEFINED = 0x00;
+ /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
+ * value indicating that a layout dir has been set to LTR. */
+ public static final int SCREENLAYOUT_LAYOUTDIR_LTR = 0x01 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
+ /** Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_LAYOUTDIR_MASK}
+ * value indicating that a layout dir has been set to RTL. */
+ public static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x02 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
+
+ /** Constant for {@link #screenLayout}: a value indicating that screenLayout is undefined */
+ public static final int SCREENLAYOUT_UNDEFINED = SCREENLAYOUT_SIZE_UNDEFINED |
+ SCREENLAYOUT_LONG_UNDEFINED | SCREENLAYOUT_LAYOUTDIR_UNDEFINED;
+
/**
* Special flag we generate to indicate that the screen layout requires
* us to use a compatibility mode for apps that are not modern layout
@@ -146,6 +164,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
* is wider/taller than normal. They may be one of
* {@link #SCREENLAYOUT_LONG_NO} or {@link #SCREENLAYOUT_LONG_YES}.
*
+ * <p>The {@link #SCREENLAYOUT_LAYOUTDIR_MASK} defines whether the screen layout
+ * is either LTR or RTL. They may be one of
+ * {@link #SCREENLAYOUT_LAYOUTDIR_LTR} or {@link #SCREENLAYOUT_LAYOUTDIR_RTL}.
+ *
* <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
* Multiple Screens</a> for more information.
*/
@@ -442,11 +464,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
public int compatSmallestScreenWidthDp;
/**
- * @hide The layout direction associated to the current Locale
- */
- public int layoutDirection;
-
- /**
* @hide Internal book-keeping.
*/
public int seq;
@@ -472,7 +489,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
mnc = o.mnc;
if (o.locale != null) {
locale = (Locale) o.locale.clone();
- layoutDirection = o.layoutDirection;
}
userSetLocale = o.userSetLocale;
touchscreen = o.touchscreen;
@@ -517,10 +533,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration
} else {
sb.append(" ?locale");
}
- switch (layoutDirection) {
- case View.LAYOUT_DIRECTION_LTR: /* ltr not interesting */ break;
- case View.LAYOUT_DIRECTION_RTL: sb.append(" rtl"); break;
- default: sb.append(" layoutDir="); sb.append(layoutDirection); break;
+ int layoutDir = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK);
+ switch (layoutDir) {
+ case SCREENLAYOUT_LAYOUTDIR_UNDEFINED: sb.append(" ?layoutDir"); break;
+ case SCREENLAYOUT_LAYOUTDIR_LTR: sb.append(" ltr"); break;
+ case SCREENLAYOUT_LAYOUTDIR_RTL: sb.append(" rtl"); break;
+ default: sb.append(" layoutDir=");
+ sb.append(layoutDir >> SCREENLAYOUT_LAYOUTDIR_SHIFT); break;
}
if (smallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
sb.append(" sw"); sb.append(smallestScreenWidthDp); sb.append("dp");
@@ -643,13 +662,12 @@ public final class Configuration implements Parcelable, Comparable<Configuration
navigation = NAVIGATION_UNDEFINED;
navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
- screenLayout = SCREENLAYOUT_SIZE_UNDEFINED;
+ screenLayout = SCREENLAYOUT_UNDEFINED;
uiMode = UI_MODE_TYPE_UNDEFINED;
screenWidthDp = compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED;
screenHeightDp = compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED;
smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
densityDpi = DENSITY_DPI_UNDEFINED;
- layoutDirection = View.LAYOUT_DIRECTION_LTR;
seq = 0;
}
@@ -685,7 +703,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
changed |= ActivityInfo.CONFIG_LOCALE;
locale = delta.locale != null
? (Locale) delta.locale.clone() : null;
- layoutDirection = LocaleUtil.getLayoutDirectionFromLocale(locale);
+ // If locale has changed, then layout direction is also changed ...
+ changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+ // ... and we need to update the layout direction (represented by the first
+ // 2 most significant bits in screenLayout).
+ setLayoutDirection(locale);
}
if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
{
@@ -727,10 +749,17 @@ public final class Configuration implements Parcelable, Comparable<Configuration
changed |= ActivityInfo.CONFIG_ORIENTATION;
orientation = delta.orientation;
}
- if (delta.screenLayout != SCREENLAYOUT_SIZE_UNDEFINED
- && screenLayout != delta.screenLayout) {
+ if (getScreenLayoutNoDirection(delta.screenLayout) !=
+ (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED)
+ && (getScreenLayoutNoDirection(screenLayout) !=
+ getScreenLayoutNoDirection(delta.screenLayout))) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
- screenLayout = delta.screenLayout;
+ // We need to preserve the previous layout dir bits if they were defined
+ if ((delta.screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) == 0) {
+ screenLayout = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK)|delta.screenLayout;
+ } else {
+ screenLayout = delta.screenLayout;
+ }
}
if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED)
&& uiMode != delta.uiMode) {
@@ -771,7 +800,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
}
-
if (delta.seq != 0) {
seq = delta.seq;
}
@@ -807,6 +835,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
* PackageManager.ActivityInfo.CONFIG_SCREEN_SIZE}, or
* {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE
* PackageManager.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE}.
+ * {@link android.content.pm.ActivityInfo#CONFIG_LAYOUT_DIRECTION
+ * PackageManager.ActivityInfo.CONFIG_LAYOUT_DIRECTION}.
*/
public int diff(Configuration delta) {
int changed = 0;
@@ -822,6 +852,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
if (delta.locale != null
&& (locale == null || !locale.equals(delta.locale))) {
changed |= ActivityInfo.CONFIG_LOCALE;
+ changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
}
if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
&& touchscreen != delta.touchscreen) {
@@ -851,8 +882,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
}
- if (delta.screenLayout != SCREENLAYOUT_SIZE_UNDEFINED
- && screenLayout != delta.screenLayout) {
+ if (getScreenLayoutNoDirection(delta.screenLayout) !=
+ (SCREENLAYOUT_SIZE_UNDEFINED | SCREENLAYOUT_LONG_UNDEFINED)
+ && getScreenLayoutNoDirection(screenLayout) !=
+ getScreenLayoutNoDirection(delta.screenLayout)) {
changed |= ActivityInfo.CONFIG_SCREEN_LAYOUT;
}
if (delta.uiMode != (UI_MODE_TYPE_UNDEFINED|UI_MODE_NIGHT_UNDEFINED)
@@ -875,7 +908,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
&& densityDpi != delta.densityDpi) {
changed |= ActivityInfo.CONFIG_DENSITY;
}
-
+
return changed;
}
@@ -963,7 +996,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
dest.writeInt(compatScreenWidthDp);
dest.writeInt(compatScreenHeightDp);
dest.writeInt(compatSmallestScreenWidthDp);
- dest.writeInt(layoutDirection);
dest.writeInt(seq);
}
@@ -992,7 +1024,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration
compatScreenWidthDp = source.readInt();
compatScreenHeightDp = source.readInt();
compatSmallestScreenWidthDp = source.readInt();
- layoutDirection = source.readInt();
seq = source.readInt();
}
@@ -1100,4 +1131,50 @@ public final class Configuration implements Parcelable, Comparable<Configuration
result = 31 * result + densityDpi;
return result;
}
+
+ /**
+ * Set the locale. This is the preferred way for setting up the locale (instead of using the
+ * direct accessor). This will also set the userLocale and layout direction according to
+ * the locale.
+ *
+ * @param loc The locale. Can be null.
+ */
+ public void setLocale(Locale loc) {
+ locale = loc;
+ userSetLocale = true;
+ setLayoutDirection(locale);
+ }
+
+ /**
+ * Return the layout direction. Will be either {@link View#LAYOUT_DIRECTION_LTR} or
+ * {@link View#LAYOUT_DIRECTION_RTL}.
+ *
+ * @return the layout direction
+ */
+ public int getLayoutDirection() {
+ // We need to substract one here as the configuration values are using "0" as undefined thus
+ // having LRT set to "1" and RTL set to "2"
+ return ((screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK) >> SCREENLAYOUT_LAYOUTDIR_SHIFT) - 1;
+ }
+
+ /**
+ * Set the layout direction from the Locale.
+ *
+ * @param locale The Locale. If null will set the layout direction to
+ * {@link View#LAYOUT_DIRECTION_LTR}. If not null will set it to the layout direction
+ * corresponding to the Locale.
+ *
+ * @see {@link View#LAYOUT_DIRECTION_LTR} and {@link View#LAYOUT_DIRECTION_RTL}
+ */
+ public void setLayoutDirection(Locale locale) {
+ // There is a "1" difference between the configuration values for
+ // layout direction and View constants for layout direction, just add "1".
+ final int layoutDirection = 1 + LocaleUtil.getLayoutDirectionFromLocale(locale);
+ screenLayout = (screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK)|
+ (layoutDirection << SCREENLAYOUT_LAYOUTDIR_SHIFT);
+ }
+
+ private static int getScreenLayoutNoDirection(int screenLayout) {
+ return screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK;
+ }
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 7559f1e..42a6bdc 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1444,12 +1444,14 @@ public class Resources {
}
if (mTmpConfig.locale == null) {
mTmpConfig.locale = Locale.getDefault();
+ mTmpConfig.setLayoutDirection(mTmpConfig.locale);
}
configChanges = mConfiguration.updateFrom(mTmpConfig);
configChanges = ActivityInfo.activityInfoConfigToNative(configChanges);
}
if (mConfiguration.locale == null) {
mConfiguration.locale = Locale.getDefault();
+ mConfiguration.setLayoutDirection(mConfiguration.locale);
}
if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) {
mMetrics.densityDpi = mConfiguration.densityDpi;
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 053ade7..8df160a 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -374,7 +374,7 @@ public class Toast {
// We can resolve the Gravity here by using the Locale for getting
// the layout direction
final Configuration config = mView.getContext().getResources().getConfiguration();
- final int gravity = Gravity.getAbsoluteGravity(mGravity, config.layoutDirection);
+ final int gravity = Gravity.getAbsoluteGravity(mGravity, config.getLayoutDirection());
mParams.gravity = gravity;
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
mParams.horizontalWeight = 1.0f;
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 52cb679..4fba7e8 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -218,10 +218,9 @@ public class LocalePicker extends ListFragment {
IActivityManager am = ActivityManagerNative.getDefault();
Configuration config = am.getConfiguration();
- config.locale = locale;
-
- // indicate this isn't some passing default - the user wants this remembered
- config.userSetLocale = true;
+ // Will set userSetLocale to indicate this isn't some passing default - the user
+ // wants this remembered
+ config.setLocale(locale);
am.updateConfiguration(config);
// Trigger the dirty bit for the Settings Provider.
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1c3318d..3a69937 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -639,6 +639,8 @@
physical screen size has changed such as switching to an external
display. -->
<flag name="smallestScreenSize" value="0x0800" />
+ <!-- The layout direction has changed. For example going from LTR to RTL. -->
+ <flag name="layoutDirection" value="0x2000" />
<!-- 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/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 23bca3e..48f5bf3 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -957,6 +957,13 @@ struct ResTable_config
SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,
SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,
SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,
+
+ // screenLayout bits for layout direction.
+ MASK_LAYOUTDIR = 0xC0,
+ SHIFT_LAYOUTDIR = 6,
+ LAYOUTDIR_ANY = ACONFIGURATION_LAYOUTDIR_ANY << SHIFT_LAYOUTDIR,
+ LAYOUTDIR_LTR = ACONFIGURATION_LAYOUTDIR_LTR << SHIFT_LAYOUTDIR,
+ LAYOUTDIR_RTL = ACONFIGURATION_LAYOUTDIR_RTL << SHIFT_LAYOUTDIR,
};
enum {
@@ -1020,7 +1027,8 @@ struct ResTable_config
CONFIG_SMALLEST_SCREEN_SIZE = ACONFIGURATION_SMALLEST_SCREEN_SIZE,
CONFIG_VERSION = ACONFIGURATION_VERSION,
CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
- CONFIG_UI_MODE = ACONFIGURATION_UI_MODE
+ CONFIG_UI_MODE = ACONFIGURATION_UI_MODE,
+ CONFIG_LAYOUTDIR = ACONFIGURATION_LAYOUTDIR,
};
// Compare two configuration, returning CONFIG_* flags set for each value
@@ -1061,7 +1069,7 @@ struct ResTable_config
* There should be one of these chunks for each resource type.
*
* This structure is followed by an array of integers providing the set of
- * configuation change flags (ResTable_config::CONFIG_*) that have multiple
+ * configuration change flags (ResTable_config::CONFIG_*) that have multiple
* resources for that configuration. In addition, the high bit is set if that
* resource has been made public.
*/
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 8cce191..069dfa3 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1470,6 +1470,9 @@ int ResTable_config::compareLogical(const ResTable_config& o) const {
if (country[1] != o.country[1]) {
return country[1] < o.country[1] ? -1 : 1;
}
+ if ((screenLayout & MASK_LAYOUTDIR) != (o.screenLayout & MASK_LAYOUTDIR)) {
+ return (screenLayout & MASK_LAYOUTDIR) < (o.screenLayout & MASK_LAYOUTDIR) ? -1 : 1;
+ }
if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
return smallestScreenWidthDp < o.smallestScreenWidthDp ? -1 : 1;
}
@@ -1558,6 +1561,13 @@ bool ResTable_config::isMoreSpecificThan(const ResTable_config& o) const {
}
}
+ if (screenLayout || o.screenLayout) {
+ if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0) {
+ if (!(screenLayout & MASK_LAYOUTDIR)) return false;
+ if (!(o.screenLayout & MASK_LAYOUTDIR)) return true;
+ }
+ }
+
if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
if (!smallestScreenWidthDp) return false;
@@ -1683,6 +1693,15 @@ bool ResTable_config::isBetterThan(const ResTable_config& o,
}
}
+ if (screenLayout || o.screenLayout) {
+ if (((screenLayout^o.screenLayout) & MASK_LAYOUTDIR) != 0
+ && (requested->screenLayout & MASK_LAYOUTDIR)) {
+ int myLayoutDir = screenLayout & MASK_LAYOUTDIR;
+ int oLayoutDir = o.screenLayout & MASK_LAYOUTDIR;
+ return (myLayoutDir > oLayoutDir);
+ }
+ }
+
if (smallestScreenWidthDp || o.smallestScreenWidthDp) {
// The configuration closest to the actual size is best.
// We assume that larger configs have already been filtered
@@ -1906,6 +1925,12 @@ bool ResTable_config::match(const ResTable_config& settings) const {
}
}
if (screenConfig != 0) {
+ const int layoutDir = screenLayout&MASK_LAYOUTDIR;
+ const int setLayoutDir = settings.screenLayout&MASK_LAYOUTDIR;
+ if (layoutDir != 0 && layoutDir != setLayoutDir) {
+ return false;
+ }
+
const int screenSize = screenLayout&MASK_SCREENSIZE;
const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
// Any screen sizes for larger screens than the setting do not
@@ -2032,6 +2057,21 @@ String8 ResTable_config::toString() const {
if (res.size() > 0) res.append("-");
res.append(country, 2);
}
+ if ((screenLayout&MASK_LAYOUTDIR) != 0) {
+ if (res.size() > 0) res.append("-");
+ switch (screenLayout&ResTable_config::MASK_LAYOUTDIR) {
+ case ResTable_config::LAYOUTDIR_LTR:
+ res.append("ltr");
+ break;
+ case ResTable_config::LAYOUTDIR_RTL:
+ res.append("rtl");
+ break;
+ default:
+ res.appendFormat("layoutDir=%d",
+ dtohs(screenLayout&ResTable_config::MASK_LAYOUTDIR));
+ break;
+ }
+ }
if (smallestScreenWidthDp != 0) {
if (res.size() > 0) res.append("-");
res.appendFormat("sw%ddp", dtohs(smallestScreenWidthDp));
diff --git a/native/android/configuration.cpp b/native/android/configuration.cpp
index 7eb51dd..74cf80e 100644
--- a/native/android/configuration.cpp
+++ b/native/android/configuration.cpp
@@ -123,6 +123,11 @@ int32_t AConfiguration_getSmallestScreenWidthDp(AConfiguration* config) {
return config->smallestScreenWidthDp;
}
+int32_t AConfiguration_getLayoutDirection(AConfiguration* config) {
+ return (config->screenLayout&ResTable_config::MASK_LAYOUTDIR)
+ >> ResTable_config::SHIFT_LAYOUTDIR;
+}
+
// ----------------------------------------------------------------------
void AConfiguration_setMcc(AConfiguration* config, int32_t mcc) {
@@ -210,6 +215,11 @@ void AConfiguration_setSmallestScreenWidthDp(AConfiguration* config, int32_t val
config->smallestScreenWidthDp = value;
}
+void AConfiguration_setLayoutDirection(AConfiguration* config, int32_t value) {
+ config->screenLayout = (config->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
+ | ((value<<ResTable_config::SHIFT_LAYOUTDIR)&ResTable_config::MASK_LAYOUTDIR);
+}
+
// ----------------------------------------------------------------------
int32_t AConfiguration_diff(AConfiguration* config1, AConfiguration* config2) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 3e96f9b..e761847 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2841,7 +2841,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
mDecor.setIsRootNamespace(true);
mDecor.setLayoutDirection(
- getContext().getResources().getConfiguration().layoutDirection);
+ getContext().getResources().getConfiguration().getLayoutDirection());
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 7f2b69f..1bb144c 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -114,6 +114,7 @@ import android.os.UserManager;
import android.provider.Settings;
import android.text.format.Time;
import android.util.EventLog;
+import android.util.LocaleUtil;
import android.util.Log;
import android.util.Pair;
import android.util.PrintWriterPrinter;
@@ -1509,7 +1510,8 @@ public final class ActivityManagerService extends ActivityManagerNative
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
mConfiguration.setToDefaults();
- mConfiguration.locale = Locale.getDefault();
+ mConfiguration.setLocale(Locale.getDefault());
+
mConfigurationSeq = mConfiguration.seq = 1;
mProcessStats.init();
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 98adf38..a52af9d 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -6527,7 +6527,8 @@ public class WindowManagerService extends IWindowManager.Stub
sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
- outConfig.screenLayout = sl;
+ outConfig.screenLayout =
+ sl|(outConfig.screenLayout&Configuration.SCREENLAYOUT_LAYOUTDIR_MASK);
}
private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 46b8a27..438a670 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -183,6 +183,13 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value)
return 0;
}
+ // layout direction
+ if (getLayoutDirectionName(part.string(), &config)) {
+ *axis = AXIS_LAYOUTDIR;
+ *value = (config.screenLayout&ResTable_config::MASK_LAYOUTDIR);
+ return 0;
+ }
+
// smallest screen dp width
if (getSmallestScreenWidthDpName(part.string(), &config)) {
*axis = AXIS_SMALLESTSCREENWIDTHDP;
@@ -309,6 +316,8 @@ AaptGroupEntry::getConfigValueForAxis(const ResTable_config& config, int axis)
case AXIS_LANGUAGE:
return (((uint32_t)config.country[1]) << 24) | (((uint32_t)config.country[0]) << 16)
| (((uint32_t)config.language[1]) << 8) | (config.language[0]);
+ case AXIS_LAYOUTDIR:
+ return config.screenLayout&ResTable_config::MASK_LAYOUTDIR;
case AXIS_SCREENLAYOUTSIZE:
return config.screenLayout&ResTable_config::MASK_SCREENSIZE;
case AXIS_ORIENTATION:
@@ -364,7 +373,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
Vector<String8> parts;
String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
- String8 touch, key, keysHidden, nav, navHidden, size, vers;
+ String8 touch, key, keysHidden, nav, navHidden, size, layoutDir, vers;
String8 uiModeType, uiModeNight, smallestwidthdp, widthdp, heightdp;
const char *p = dir;
@@ -452,6 +461,18 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
//printf("not region: %s\n", part.string());
}
+ if (getLayoutDirectionName(part.string())) {
+ layoutDir = part;
+
+ index++;
+ if (index == N) {
+ goto success;
+ }
+ part = parts[index];
+ } else {
+ //printf("not layout direction: %s\n", part.string());
+ }
+
if (getSmallestScreenWidthDpName(part.string())) {
smallestwidthdp = part;
@@ -674,6 +695,7 @@ success:
this->navHidden = navHidden;
this->navigation = nav;
this->screenSize = size;
+ this->layoutDirection = layoutDir;
this->version = vers;
// what is this anyway?
@@ -691,6 +713,8 @@ AaptGroupEntry::toString() const
s += ",";
s += this->locale;
s += ",";
+ s += layoutDirection;
+ s += ",";
s += smallestScreenWidthDp;
s += ",";
s += screenWidthDp;
@@ -747,6 +771,12 @@ AaptGroupEntry::toDirName(const String8& resType) const
}
s += locale;
}
+ if (this->layoutDirection != "") {
+ if (s.length() > 0) {
+ s += "-";
+ }
+ s += layoutDirection;
+ }
if (this->smallestScreenWidthDp != "") {
if (s.length() > 0) {
s += "-";
@@ -958,6 +988,28 @@ bool AaptGroupEntry::getLocaleName(const char* fileName,
return false;
}
+bool AaptGroupEntry::getLayoutDirectionName(const char* name, ResTable_config* out)
+{
+ if (strcmp(name, kWildcardName) == 0) {
+ if (out) out->screenLayout =
+ (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
+ | ResTable_config::LAYOUTDIR_ANY;
+ return true;
+ } else if (strcmp(name, "ltr") == 0) {
+ if (out) out->screenLayout =
+ (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
+ | ResTable_config::LAYOUTDIR_LTR;
+ return true;
+ } else if (strcmp(name, "rtl") == 0) {
+ if (out) out->screenLayout =
+ (out->screenLayout&~ResTable_config::MASK_LAYOUTDIR)
+ | ResTable_config::LAYOUTDIR_RTL;
+ return true;
+ }
+
+ return false;
+}
+
bool AaptGroupEntry::getScreenLayoutSizeName(const char* name,
ResTable_config* out)
{
@@ -1415,6 +1467,7 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const
int v = mcc.compare(o.mcc);
if (v == 0) v = mnc.compare(o.mnc);
if (v == 0) v = locale.compare(o.locale);
+ if (v == 0) v = layoutDirection.compare(o.layoutDirection);
if (v == 0) v = vendor.compare(o.vendor);
if (v == 0) v = smallestScreenWidthDp.compare(o.smallestScreenWidthDp);
if (v == 0) v = screenWidthDp.compare(o.screenWidthDp);
@@ -1447,6 +1500,7 @@ const ResTable_config& AaptGroupEntry::toParams() const
getMccName(mcc.string(), &params);
getMncName(mnc.string(), &params);
getLocaleName(locale.string(), &params);
+ getLayoutDirectionName(layoutDirection.string(), &params);
getSmallestScreenWidthDpName(smallestScreenWidthDp.string(), &params);
getScreenWidthDpName(screenWidthDp.string(), &params);
getScreenHeightDpName(screenHeightDp.string(), &params);
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index d5f296c..5cfa913 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -51,6 +51,7 @@ enum {
AXIS_SMALLESTSCREENWIDTHDP,
AXIS_SCREENWIDTHDP,
AXIS_SCREENHEIGHTDP,
+ AXIS_LAYOUTDIR,
AXIS_VERSION,
AXIS_START = AXIS_MCC,
@@ -95,6 +96,7 @@ public:
static bool getSmallestScreenWidthDpName(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 getLayoutDirectionName(const char* name, ResTable_config* out = NULL);
static bool getVersionName(const char* name, ResTable_config* out = NULL);
int compare(const AaptGroupEntry& o) const;
@@ -133,6 +135,7 @@ private:
String8 navHidden;
String8 navigation;
String8 screenSize;
+ String8 layoutDirection;
String8 version;
mutable bool mParamsChanged;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index d98fe65..3d7b088 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2811,7 +2811,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
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 sz:%dx%d "
- "sw%ddp w%ddp h%ddp\n",
+ "sw%ddp w%ddp h%ddp dir:%d\n",
ti+1,
config.mcc, config.mnc,
config.language[0] ? config.language[0] : '-',
@@ -2829,7 +2829,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
config.screenHeight,
config.smallestScreenWidthDp,
config.screenWidthDp,
- config.screenHeightDp));
+ config.screenHeightDp,
+ config.layoutDirection));
if (filterable && !filter.match(config)) {
continue;
@@ -2853,7 +2854,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
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 sz:%dx%d "
- "sw%ddp w%ddp h%ddp\n",
+ "sw%ddp w%ddp h%ddp dir:%d\n",
ti+1,
tHeader->config.mcc, tHeader->config.mnc,
tHeader->config.language[0] ? tHeader->config.language[0] : '-',
@@ -2871,7 +2872,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp<AaptFile>& dest)
tHeader->config.screenHeight,
tHeader->config.smallestScreenWidthDp,
tHeader->config.screenWidthDp,
- tHeader->config.screenHeightDp));
+ tHeader->config.screenHeightDp,
+ tHeader->config.layoutDirection));
tHeader->config.swapHtoD();
// Build the entries inside of this type.
@@ -3489,7 +3491,7 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
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 sz:%dx%d "
- "sw%ddp w%ddp h%ddp\n",
+ "sw%ddp w%ddp h%ddp dir:%d\n",
sourcePos.file.string(), sourcePos.line,
config->mcc, config->mnc,
config->language[0] ? config->language[0] : '-',
@@ -3506,7 +3508,8 @@ sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
config->screenHeight,
config->smallestScreenWidthDp,
config->screenWidthDp,
- config->screenHeightDp));
+ config->screenHeightDp,
+ config->layoutDirection));
} else {
NOISY(printf("New entry at %s:%d: NULL config\n",
sourcePos.file.string(), sourcePos.line));