From 27b28b3f62bd3b54fa13acd5d035940b9be464f3 Mon Sep 17 00:00:00 2001 From: Tobias Haamel Date: Tue, 9 Feb 2010 23:09:17 +0100 Subject: [PATCH] Introduce special UI modes for night and car usage. The device mode is now called ui mode. Furthermore is the order of precedence for the resources now in such a way that the ui mode needs to be specified after the orientation and before the density. The ui mode can be set, like it is done for the locale, as follows: IActivityManager am = ActivityManagerNative.getDefault(); Configuration config = am.getConfiguration(); config.uiMode = Configuration.UI_MODE_TYPE_CAR | Configuration.UI_MODE_NIGHT_ANY; am.updateConfiguration(config); To allow users to disable the car mode and set the night mode the IUiModeManager interface is used. The automatic night mode switching will be added in a separate change. --- Android.mk | 1 + api/current.xml | 11 ++ core/java/android/app/IUiModeManager.aidl | 49 +++++++ core/java/android/content/Intent.java | 10 +- .../java/android/content/pm/ActivityInfo.java | 7 + .../android/content/res/AssetManager.java | 2 +- .../android/content/res/Configuration.java | 51 +++++++- core/java/android/content/res/Resources.java | 2 +- core/jni/android_util_AssetManager.cpp | 6 +- core/res/AndroidManifest.xml | 8 ++ core/res/res/values/strings.xml | 6 + include/utils/ResourceTypes.h | 89 ++++++++++--- .../java/com/android/server/DockObserver.java | 120 ++++++++++++++++-- tools/aapt/AaptAssets.cpp | 100 +++++++++++++++ tools/aapt/AaptAssets.h | 6 + tools/aapt/Resource.cpp | 4 +- tools/aapt/ResourceTable.cpp | 12 +- .../layoutlib/bridge/BridgeAssetManager.java | 3 +- 18 files changed, 446 insertions(+), 41 deletions(-) create mode 100644 core/java/android/app/IUiModeManager.aidl diff --git a/Android.mk b/Android.mk index 7fc121d196af2..4ecf5bd651979 100644 --- a/Android.mk +++ b/Android.mk @@ -90,6 +90,7 @@ LOCAL_SRC_FILES += \ core/java/android/app/IStatusBar.aidl \ core/java/android/app/IThumbnailReceiver.aidl \ core/java/android/app/ITransientNotification.aidl \ + core/java/android/app/IUiModeManager.aidl \ core/java/android/app/IWallpaperManager.aidl \ core/java/android/app/IWallpaperManagerCallback.aidl \ core/java/android/backup/IBackupManager.aidl \ diff --git a/api/current.xml b/api/current.xml index ab5a1142008b6..b2a2bc1d376f4 100644 --- a/api/current.xml +++ b/api/current.xml @@ -38037,6 +38037,17 @@ visibility="public" > + + The {@link #UI_MODE_TYPE_MASK} bits define the overall ui mode of the + * device. They may be one of + * {@link #UI_MODE_TYPE_NORMAL} or {@link #UI_MODE_TYPE_CAR}. + * + *

The {@link #UI_MODE_NIGHT_MASK} defines whether the screen + * is in a special mode. They may be one of + * {@link #UI_MODE_NIGHT_NO} or {@link #UI_MODE_NIGHT_YES}. + * + * @hide (UIMODE) Pending API council approval + */ + public int uiMode; + /** * Construct an invalid Configuration. You must call {@link #setToDefaults} * for this object to be valid. {@more} @@ -189,6 +219,7 @@ public final class Configuration implements Parcelable, ComparablesetConfiguration(config, locale8); @@ -1614,7 +1616,7 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_setLocale }, { "getLocales", "()[Ljava/lang/String;", (void*) android_content_AssetManager_getLocales }, - { "setConfiguration", "(IILjava/lang/String;IIIIIIIIII)V", + { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIII)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/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1ae736ebb1d3f..f5f5a27274dc7 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -564,6 +564,14 @@ android:label="@string/permlab_changeConfiguration" android:description="@string/permdesc_changeConfiguration" /> + + + + + enable car mode + + Allows an application to + enable the car mode. + kill background processes diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index 6090f6001a3a1..13ea27e4db943 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -939,10 +939,23 @@ struct ResTable_config SCREENLONG_YES = 0x20, }; + enum { + // uiMode bits for the mode type. + MASK_UI_MODE_TYPE = 0x0f, + UI_MODE_TYPE_NORMAL = 0x00, + UI_MODE_TYPE_CAR = 0x01, + + // uiMode bits for the night switch. + MASK_UI_MODE_NIGHT = 0x30, + UI_MODE_NIGHT_ANY = 0x00, + UI_MODE_NIGHT_NO = 0x10, + UI_MODE_NIGHT_YES = 0x20, + }; + union { struct { uint8_t screenLayout; - uint8_t screenConfigPad0; + uint8_t uiMode; uint8_t screenConfigPad1; uint8_t screenConfigPad2; }; @@ -996,6 +1009,8 @@ struct ResTable_config diff = (int32_t)(version - o.version); if (diff != 0) return diff; diff = (int32_t)(screenLayout - o.screenLayout); + if (diff != 0) return diff; + diff = (int32_t)(uiMode - o.uiMode); return (int)diff; } @@ -1014,7 +1029,8 @@ struct ResTable_config CONFIG_DENSITY = 0x0100, CONFIG_SCREEN_SIZE = 0x0200, CONFIG_VERSION = 0x0400, - CONFIG_SCREEN_LAYOUT = 0x0800 + CONFIG_SCREEN_LAYOUT = 0x0800, + CONFIG_UI_MODE = 0x1000 }; // Compare two configuration, returning CONFIG_* flags set for each value @@ -1034,6 +1050,7 @@ struct ResTable_config if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE; if (version != o.version) diffs |= CONFIG_VERSION; if (screenLayout != o.screenLayout) diffs |= CONFIG_SCREEN_LAYOUT; + if (uiMode != o.uiMode) diffs |= CONFIG_UI_MODE; return diffs; } @@ -1078,19 +1095,28 @@ struct ResTable_config } } - if (screenType || o.screenType) { - if (orientation != o.orientation) { - if (!orientation) return false; - if (!o.orientation) return true; - } + if (orientation != o.orientation) { + if (!orientation) return false; + if (!o.orientation) return true; + } - // density is never 'more specific' - // as the default just equals 160 - - if (touchscreen != o.touchscreen) { - if (!touchscreen) return false; - if (!o.touchscreen) return true; + if (screenConfig || o.screenConfig) { + if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0) { + if (!(uiMode & MASK_UI_MODE_TYPE)) return false; + if (!(o.uiMode & MASK_UI_MODE_TYPE)) return true; } + if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0) { + if (!(uiMode & MASK_UI_MODE_NIGHT)) return false; + if (!(o.uiMode & MASK_UI_MODE_NIGHT)) return true; + } + } + + // density is never 'more specific' + // as the default just equals 160 + + if (touchscreen != o.touchscreen) { + if (!touchscreen) return false; + if (!o.touchscreen) return true; } if (input || o.input) { @@ -1186,11 +1212,22 @@ struct ResTable_config } } - if (screenType || o.screenType) { - if ((orientation != o.orientation) && requested->orientation) { - return (orientation); - } + if ((orientation != o.orientation) && requested->orientation) { + return (orientation); + } + if (screenConfig || o.screenConfig) { + if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0 + && (requested->uiMode & MASK_UI_MODE_TYPE)) { + return (uiMode & MASK_UI_MODE_TYPE); + } + if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0 + && (requested->uiMode & MASK_UI_MODE_NIGHT)) { + return (uiMode & MASK_UI_MODE_NIGHT); + } + } + + if (screenType || o.screenType) { if (density != o.density) { // density is tough. Any density is potentially useful // because the system will scale it. Scaling down @@ -1340,6 +1377,20 @@ struct ResTable_config && screenLong != setScreenLong) { return false; } + + const int uiModeType = uiMode&MASK_UI_MODE_TYPE; + const int setUiModeType = settings.uiMode&MASK_UI_MODE_TYPE; + if (setUiModeType != 0 && uiModeType != 0 + && uiModeType != setUiModeType) { + return false; + } + + const int uiModeNight = uiMode&MASK_UI_MODE_NIGHT; + const int setUiModeNight = settings.uiMode&MASK_UI_MODE_NIGHT; + if (setUiModeNight != 0 && uiModeNight != 0 + && uiModeNight != setUiModeNight) { + return false; + } } if (screenType != 0) { if (settings.orientation != 0 && orientation != 0 @@ -1420,13 +1471,15 @@ 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 vers=%d.%d", + "kbd=%d nav=%d input=%d scrnW=%d scrnH=%d 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, screenLayout&MASK_SCREENSIZE, screenLayout&MASK_SCREENLONG, + uiMode&MASK_UI_MODE_TYPE, uiMode&MASK_UI_MODE_NIGHT, sdkVersion, minorVersion); return String8(buf); } diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java index 363e93e6af1a9..742a7d8c802e5 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -17,6 +17,9 @@ package com.android.server; import android.app.Activity; +import android.app.ActivityManagerNative; +import android.app.IActivityManager; +import android.app.IUiModeManager; import android.app.KeyguardManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -24,8 +27,12 @@ import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; +import android.os.Binder; import android.os.Handler; import android.os.Message; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; import android.os.UEventObserver; import android.provider.Settings; @@ -47,7 +54,13 @@ class DockObserver extends UEventObserver { private static final String DOCK_UEVENT_MATCH = "DEVPATH=/devices/virtual/switch/dock"; private static final String DOCK_STATE_PATH = "/sys/class/switch/dock/state"; + public static final int MODE_NIGHT_AUTO = Configuration.UI_MODE_NIGHT_MASK >> 4; + public static final int MODE_NIGHT_NO = Configuration.UI_MODE_NIGHT_NO >> 4; + public static final int MODE_NIGHT_YES = Configuration.UI_MODE_NIGHT_YES >> 4; + private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; + private int mNightMode = MODE_NIGHT_NO; + private boolean mCarModeEnabled = false; private boolean mSystemReady; private final Context mContext; @@ -71,16 +84,12 @@ class DockObserver extends UEventObserver { // Launch a dock activity String category; - switch (mDockState) { - case Intent.EXTRA_DOCK_STATE_CAR: - category = Intent.CATEGORY_CAR_DOCK; - break; - case Intent.EXTRA_DOCK_STATE_DESK: - category = Intent.CATEGORY_DESK_DOCK; - break; - default: - category = null; - break; + if (mCarModeEnabled || mDockState == Intent.EXTRA_DOCK_STATE_CAR) { + category = Intent.CATEGORY_CAR_DOCK; + } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { + category = Intent.CATEGORY_DESK_DOCK; + } else { + category = null; } if (category != null) { intent = new Intent(Intent.ACTION_MAIN); @@ -101,6 +110,9 @@ class DockObserver extends UEventObserver { mPowerManager = pm; mLockPatternUtils = new LockPatternUtils(context); init(); // set initial status + + ServiceManager.addService("uimode", mBinder); + startObserving(DOCK_UEVENT_MATCH); } @@ -116,6 +128,14 @@ class DockObserver extends UEventObserver { if (newState != mDockState) { int oldState = mDockState; mDockState = newState; + boolean carModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; + if (mCarModeEnabled != carModeEnabled) { + try { + setCarMode(carModeEnabled); + } catch (RemoteException e1) { + Log.w(TAG, "Unable to change car mode.", e1); + } + } if (mSystemReady) { // Don't force screen on when undocking from the desk dock. // The change in power state will do this anyway. @@ -180,7 +200,13 @@ class DockObserver extends UEventObserver { // Pack up the values and broadcast them to everyone Intent intent = new Intent(Intent.ACTION_DOCK_EVENT); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); + if (mCarModeEnabled && mDockState != Intent.EXTRA_DOCK_STATE_CAR) { + // Pretend to be in DOCK_STATE_CAR. + intent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_CAR); + } else { + intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); + } + intent.putExtra(Intent.EXTRA_CAR_MODE_ENABLED, mCarModeEnabled); // Check if this is Bluetooth Dock String address = BluetoothService.readDockBluetoothAddress(); @@ -199,4 +225,76 @@ class DockObserver extends UEventObserver { } } }; + + private void setCarMode(boolean enabled) throws RemoteException { + mCarModeEnabled = enabled; + if (enabled) { + setMode(Configuration.UI_MODE_TYPE_CAR, mNightMode); + } else { + // Disabling the car mode clears the night mode. + setMode(Configuration.UI_MODE_TYPE_NORMAL, MODE_NIGHT_NO); + } + } + + private void setMode(int modeType, int modeNight) throws RemoteException { + final IActivityManager am = ActivityManagerNative.getDefault(); + Configuration config = am.getConfiguration(); + + if (config.uiMode != (modeType | modeNight)) { + config.uiMode = modeType | modeNight; + long ident = Binder.clearCallingIdentity(); + am.updateConfiguration(config); + Binder.restoreCallingIdentity(ident); + } + } + + private void setNightMode(int mode) throws RemoteException { + mNightMode = mode; + switch (mode) { + case MODE_NIGHT_NO: + case MODE_NIGHT_YES: + setMode(Configuration.UI_MODE_TYPE_CAR, mode << 4); + break; + case MODE_NIGHT_AUTO: + // FIXME: not yet supported, this functionality will be + // added in a separate change. + break; + default: + setMode(Configuration.UI_MODE_TYPE_CAR, MODE_NIGHT_NO << 4); + break; + } + } + + /** + * Wrapper class implementing the IUiModeManager interface. + */ + private final IUiModeManager.Stub mBinder = new IUiModeManager.Stub() { + + public void disableCarMode() throws RemoteException { + if (mCarModeEnabled) { + setCarMode(false); + update(); + } + } + + public void enableCarMode() throws RemoteException { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.ENABLE_CAR_MODE, + "Need ENABLE_CAR_MODE permission"); + if (!mCarModeEnabled) { + setCarMode(true); + update(); + } + } + + public void setNightMode(int mode) throws RemoteException { + if (mCarModeEnabled) { + DockObserver.this.setNightMode(mode); + } + } + + public int getNightMode() throws RemoteException { + return mNightMode; + } + }; } diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index c346b90d5a84a..663a33a9701bb 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -163,6 +163,20 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value) return 0; } + // ui mode type + if (getUiModeTypeName(part.string(), &config)) { + *axis = AXIS_UIMODETYPE; + *value = (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE); + return 0; + } + + // ui mode night + if (getUiModeNightName(part.string(), &config)) { + *axis = AXIS_UIMODENIGHT; + *value = (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT); + return 0; + } + // density if (getDensityName(part.string(), &config)) { *axis = AXIS_DENSITY; @@ -229,6 +243,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; const char *p = dir; const char *q; @@ -352,6 +367,32 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType) //printf("not orientation: %s\n", part.string()); } + // ui mode type + if (getUiModeTypeName(part.string())) { + uiModeType = part; + + index++; + if (index == N) { + goto success; + } + part = parts[index]; + } else { + //printf("not ui mode type: %s\n", part.string()); + } + + // ui mode night + if (getUiModeNightName(part.string())) { + uiModeNight = part; + + index++; + if (index == N) { + goto success; + } + part = parts[index]; + } else { + //printf("not ui mode night: %s\n", part.string()); + } + // density if (getDensityName(part.string())) { den = part; @@ -463,6 +504,8 @@ success: this->screenLayoutSize = layoutsize; this->screenLayoutLong = layoutlong; this->orientation = orient; + this->uiModeType = uiModeType; + this->uiModeNight = uiModeNight; this->density = den; this->touchscreen = touch; this->keysHidden = keysHidden; @@ -493,6 +536,10 @@ AaptGroupEntry::toString() const s += ","; s += this->orientation; s += ","; + s += uiModeType; + s += ","; + s += uiModeNight; + s += ","; s += density; s += ","; s += touchscreen; @@ -539,6 +586,14 @@ AaptGroupEntry::toDirName(const String8& resType) const s += "-"; s += orientation; } + if (this->uiModeType != "") { + s += "-"; + s += uiModeType; + } + if (this->uiModeNight != "") { + s += "-"; + s += uiModeNight; + } if (this->density != "") { s += "-"; s += density; @@ -759,6 +814,47 @@ bool AaptGroupEntry::getOrientationName(const char* name, return false; } +bool AaptGroupEntry::getUiModeTypeName(const char* name, + ResTable_config* out) +{ + if (strcmp(name, kWildcardName) == 0) { + if (out) out->uiMode = + (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE) + | ResTable_config::UI_MODE_TYPE_NORMAL; + return true; + } else if (strcmp(name, "car") == 0) { + if (out) out->uiMode = + (out->uiMode&~ResTable_config::MASK_UI_MODE_TYPE) + | ResTable_config::UI_MODE_TYPE_CAR; + return true; + } + + return false; +} + +bool AaptGroupEntry::getUiModeNightName(const char* name, + ResTable_config* out) +{ + if (strcmp(name, kWildcardName) == 0) { + if (out) out->uiMode = + (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT) + | ResTable_config::UI_MODE_NIGHT_ANY; + return true; + } else if (strcmp(name, "night") == 0) { + if (out) out->uiMode = + (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT) + | ResTable_config::UI_MODE_NIGHT_YES; + return true; + } else if (strcmp(name, "notnight") == 0) { + if (out) out->uiMode = + (out->uiMode&~ResTable_config::MASK_UI_MODE_NIGHT) + | ResTable_config::UI_MODE_NIGHT_NO; + return true; + } + + return false; +} + bool AaptGroupEntry::getDensityName(const char* name, ResTable_config* out) { @@ -1004,6 +1100,8 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const if (v == 0) v = screenLayoutSize.compare(o.screenLayoutSize); if (v == 0) v = screenLayoutLong.compare(o.screenLayoutLong); if (v == 0) v = orientation.compare(o.orientation); + if (v == 0) v = uiModeType.compare(o.uiModeType); + if (v == 0) v = uiModeNight.compare(o.uiModeNight); if (v == 0) v = density.compare(o.density); if (v == 0) v = touchscreen.compare(o.touchscreen); if (v == 0) v = keysHidden.compare(o.keysHidden); @@ -1025,6 +1123,8 @@ ResTable_config AaptGroupEntry::toParams() const getScreenLayoutSizeName(screenLayoutSize.string(), ¶ms); getScreenLayoutLongName(screenLayoutLong.string(), ¶ms); getOrientationName(orientation.string(), ¶ms); + getUiModeTypeName(uiModeType.string(), ¶ms); + getUiModeNightName(uiModeNight.string(), ¶ms); getDensityName(density.string(), ¶ms); getTouchscreenName(touchscreen.string(), ¶ms); getKeysHiddenName(keysHidden.string(), ¶ms); diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index 26500a34886d4..9a848e4c8b36c 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -33,6 +33,8 @@ enum { AXIS_SCREENLAYOUTSIZE, AXIS_SCREENLAYOUTLONG, AXIS_ORIENTATION, + AXIS_UIMODETYPE, + AXIS_UIMODENIGHT, AXIS_DENSITY, AXIS_TOUCHSCREEN, AXIS_KEYSHIDDEN, @@ -61,6 +63,8 @@ public: String8 screenLayoutSize; String8 screenLayoutLong; String8 orientation; + String8 uiModeType; + String8 uiModeNight; String8 density; String8 touchscreen; String8 keysHidden; @@ -80,6 +84,8 @@ public: static bool getScreenLayoutSizeName(const char* name, ResTable_config* out = NULL); static bool getScreenLayoutLongName(const char* name, ResTable_config* out = NULL); static bool getOrientationName(const char* name, ResTable_config* out = NULL); + static bool getUiModeTypeName(const char* name, ResTable_config* out = NULL); + static bool getUiModeNightName(const char* name, ResTable_config* out = NULL); static bool getDensityName(const char* name, ResTable_config* out = NULL); static bool getTouchscreenName(const char* name, ResTable_config* out = NULL); static bool getKeysHiddenName(const char* name, ResTable_config* out = NULL); diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 0d2ea60ad9af7..88c5441c26d34 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -101,13 +101,13 @@ public: String8 leaf(group->getLeaf()); mLeafName = String8(leaf); mParams = file->getGroupEntry().toParams(); - NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d density=%d touch=%d key=%d inp=%d nav=%d\n", + NOISY(printf("Dir %s: mcc=%d mnc=%d lang=%c%c cnt=%c%c orient=%d ui=%d density=%d touch=%d key=%d inp=%d nav=%d\n", group->getPath().string(), mParams.mcc, mParams.mnc, mParams.language[0] ? mParams.language[0] : '-', mParams.language[1] ? mParams.language[1] : '-', mParams.country[0] ? mParams.country[0] : '-', mParams.country[1] ? mParams.country[1] : '-', - mParams.orientation, + mParams.orientation, mParams.uiMode, mParams.density, mParams.touchscreen, mParams.keyboard, mParams.inputFlags, mParams.navigation)); mPath = "res"; diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index b682702e7ed1b..a389bfb52f61f 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -2472,6 +2472,12 @@ ResourceFilter::match(const ResTable_config& config) if (!match(AXIS_ORIENTATION, config.orientation)) { return false; } + if (!match(AXIS_UIMODETYPE, (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE))) { + return false; + } + if (!match(AXIS_UIMODENIGHT, (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT))) { + return false; + } if (!match(AXIS_DENSITY, config.density)) { return false; } @@ -2674,7 +2680,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) ConfigDescription config = t->getUniqueConfigs().itemAt(ci); NOISY(printf("Writing config %d config: 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 ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", ti+1, config.mcc, config.mnc, config.language[0] ? config.language[0] : '-', @@ -2682,6 +2688,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) config.country[0] ? config.country[0] : '-', config.country[1] ? config.country[1] : '-', config.orientation, + config.uiMode, config.touchscreen, config.density, config.keyboard, @@ -2711,7 +2718,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& 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 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 w:%d h:%d\n", ti+1, tHeader->config.mcc, tHeader->config.mnc, tHeader->config.language[0] ? tHeader->config.language[0] : '-', @@ -2719,6 +2726,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) tHeader->config.country[0] ? tHeader->config.country[0] : '-', tHeader->config.country[1] ? tHeader->config.country[1] : '-', tHeader->config.orientation, + tHeader->config.uiMode, tHeader->config.touchscreen, tHeader->config.density, tHeader->config.keyboard, diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java index 6c1b5b3e7f3ff..43ff424891b4a 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java @@ -59,7 +59,7 @@ public class BridgeAssetManager extends AssetManager { public void setConfiguration(int mcc, int mnc, String locale, int orientation, int touchscreen, int density, int keyboard, int keyboardHidden, int navigation, int screenWidth, int screenHeight, - int screenLayout, int version) { + int screenLayout, int uiMode, int version) { Configuration c = new Configuration(); c.mcc = mcc; @@ -71,5 +71,6 @@ public class BridgeAssetManager extends AssetManager { c.navigation = navigation; c.orientation = orientation; c.screenLayout = screenLayout; + c.uiMode = uiMode; } }