diff options
author | Fabrice Di Meglio <fdimeglio@google.com> | 2012-06-15 20:16:41 -0700 |
---|---|---|
committer | Fabrice Di Meglio <fdimeglio@google.com> | 2012-08-23 14:55:33 -0700 |
commit | 5f7979993979466c79ab4f38d83c6f2aca361662 (patch) | |
tree | 90c8b098b3c9a53a90c039641b0b7ba379d6b4eb | |
parent | 5e8e41e41aecd2a4951659a1f3507f3371e0cc47 (diff) | |
download | frameworks_base-5f7979993979466c79ab4f38d83c6f2aca361662.zip frameworks_base-5f7979993979466c79ab4f38d83c6f2aca361662.tar.gz frameworks_base-5f7979993979466c79ab4f38d83c6f2aca361662.tar.bz2 |
Add support for "-rtl" in resources
- fix bug #7035019 Need to have "-rtl" support for Resource
Change-Id: Ic82145c2ac672729d8a6c695a5f343276a1a0a2c
-rw-r--r-- | api/current.txt | 12 | ||||
-rw-r--r-- | core/java/android/content/pm/ActivityInfo.java | 12 | ||||
-rw-r--r-- | core/java/android/content/res/Configuration.java | 123 | ||||
-rwxr-xr-x | core/java/android/content/res/Resources.java | 2 | ||||
-rw-r--r-- | core/java/android/widget/Toast.java | 2 | ||||
-rw-r--r-- | core/java/com/android/internal/app/LocalePicker.java | 7 | ||||
-rw-r--r-- | core/res/res/values/attrs_manifest.xml | 2 | ||||
-rw-r--r-- | include/androidfw/ResourceTypes.h | 12 | ||||
-rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 40 | ||||
-rw-r--r-- | native/android/configuration.cpp | 10 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindow.java | 2 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 4 | ||||
-rwxr-xr-x | services/java/com/android/server/wm/WindowManagerService.java | 3 | ||||
-rw-r--r-- | tools/aapt/AaptAssets.cpp | 56 | ||||
-rw-r--r-- | tools/aapt/AaptAssets.h | 3 | ||||
-rw-r--r-- | tools/aapt/ResourceTable.cpp | 15 |
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(), ¶ms); getMncName(mnc.string(), ¶ms); getLocaleName(locale.string(), ¶ms); + getLayoutDirectionName(layoutDirection.string(), ¶ms); getSmallestScreenWidthDpName(smallestScreenWidthDp.string(), ¶ms); getScreenWidthDpName(screenWidthDp.string(), ¶ms); getScreenHeightDpName(screenHeightDp.string(), ¶ms); 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)); |