From 93e462b79d6896da10e15e74c5aec6beb098dddf Mon Sep 17 00:00:00 2001
From: Dianne Hackborn
Date: Tue, 15 Sep 2009 22:50:40 -0700
Subject: [PATCH] Implement issue #1780928: Need support hiding nav keys.
This implements support for devices whose hardware can hide
their navigation keys. It works much like the existing keyboardHidden
configuration, and for compatibility uses the same configuration
change bit.
Also add FLAG_TURN_ON_SCREEN for windows, which has the system
cause the screen to be turned on when the window is displayed.
Great fun when used with FLAG_SHOW_WHEN_LOCKED!
Change-Id: I0b867f19af85cfd8786a14cea194b34f7bdd9b7a
---
api/current.xml | 54 ++++++++++++++++++
.../java/android/content/pm/ActivityInfo.java | 4 +-
.../android/content/res/Configuration.java | 32 ++++++++++-
core/java/android/view/WindowManager.java | 6 ++
core/res/res/values/attrs_manifest.xml | 6 +-
core/res/res/values/config.xml | 32 ++++++++---
.../guide/topics/resources/resources-i18n.jd | 10 +++-
include/utils/ResourceTypes.h | 33 ++++++++++-
.../android/server/WindowManagerService.java | 22 +++++++-
tools/aapt/AaptAssets.cpp | 55 ++++++++++++++++++-
tools/aapt/AaptAssets.h | 3 +
11 files changed, 241 insertions(+), 16 deletions(-)
diff --git a/api/current.xml b/api/current.xml
index 6174bff7fbeb2..3c6eb9b7ca49d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -43786,6 +43786,39 @@
visibility="public"
>
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 117e1398e6ea9..b84a0d9f21f40 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -35,6 +35,9 @@
300
+
+
@@ -53,6 +56,16 @@
- "wifi,1,1"
- "mobile,0,1"
+
+
+ true
+
+
+ false
+
+
90
@@ -60,11 +73,18 @@
90
-
- true
-
+
+ 1
+
+
+ 0
+
- 0
@@ -81,6 +101,4 @@
- 30
-
- false
diff --git a/docs/html/guide/topics/resources/resources-i18n.jd b/docs/html/guide/topics/resources/resources-i18n.jd
index 85b89d1c409c5..ff9579fff2afe 100755
--- a/docs/html/guide/topics/resources/resources-i18n.jd
+++ b/docs/html/guide/topics/resources/resources-i18n.jd
@@ -441,7 +441,7 @@ resources for a fully specified configuration would look like this:
MyApp/
res/
- drawable-en-rUS-large-long-port-mdpi-finger-keysexposed-qwerty-dpad-480x320/
+ drawable-en-rUS-large-long-port-mdpi-finger-keysexposed-qwerty-navexposed-dpad-480x320/
More typically, you will only specify a few specific configuration options. You may drop any of the values from the
@@ -574,6 +574,14 @@ MyApp/
Primary text input method |
nokeys, qwerty, 12key |
+
+ | Whether the navigation keys are available to the user |
+ navexposed, navhidden
+
+ If the hardware's navigation keys are currently available to
+ the user, the navexposed resources will be used; if they are not
+ available (such as behind a closed lid), navhidden will be used. |
+
Primary non-touchscreen
navigation method |
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index e524e2a31ed92..17ccad6f987b1 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -864,6 +864,13 @@ struct ResTable_config
KEYSHIDDEN_SOFT = 0x0003,
};
+ enum {
+ MASK_NAVHIDDEN = 0x000c,
+ NAVHIDDEN_ANY = 0x0000,
+ NAVHIDDEN_NO = 0x0004,
+ NAVHIDDEN_YES = 0x0008,
+ };
+
union {
struct {
uint8_t keyboard;
@@ -1011,7 +1018,8 @@ struct ResTable_config
if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
if (density != o.density) diffs |= CONFIG_DENSITY;
if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
- if (((inputFlags^o.inputFlags)&MASK_KEYSHIDDEN) != 0) diffs |= CONFIG_KEYBOARD_HIDDEN;
+ if (((inputFlags^o.inputFlags)&(MASK_KEYSHIDDEN|MASK_NAVHIDDEN)) != 0)
+ diffs |= CONFIG_KEYBOARD_HIDDEN;
if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
@@ -1082,6 +1090,11 @@ struct ResTable_config
if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
}
+ if (((inputFlags^o.inputFlags) & MASK_NAVHIDDEN) != 0) {
+ if (!(inputFlags & MASK_NAVHIDDEN)) return false;
+ if (!(o.inputFlags & MASK_NAVHIDDEN)) return true;
+ }
+
if (keyboard != o.keyboard) {
if (!keyboard) return false;
if (!o.keyboard) return true;
@@ -1225,6 +1238,18 @@ struct ResTable_config
}
}
+ const int navHidden = inputFlags & MASK_NAVHIDDEN;
+ const int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
+ if (navHidden != oNavHidden) {
+ const int reqNavHidden =
+ requested->inputFlags & MASK_NAVHIDDEN;
+ if (reqNavHidden) {
+
+ if (!navHidden) return false;
+ if (!oNavHidden) return true;
+ }
+ }
+
if ((keyboard != o.keyboard) && requested->keyboard) {
return (keyboard);
}
@@ -1332,6 +1357,12 @@ struct ResTable_config
return false;
}
}
+ const int navHidden = inputFlags&MASK_NAVHIDDEN;
+ const int setNavHidden = settings.inputFlags&MASK_NAVHIDDEN;
+ if (setNavHidden != 0 && navHidden != 0
+ && navHidden != setNavHidden) {
+ return false;
+ }
if (settings.keyboard != 0 && keyboard != 0
&& keyboard != settings.keyboard) {
return false;
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index bd2c3ed80e069..60496d67fe541 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -442,6 +442,8 @@ public class WindowManagerService extends IWindowManager.Stub
// Who is holding the screen on.
Session mHoldingScreenOn;
+ boolean mTurnOnScreen;
+
/**
* Whether the UI is currently running in touch mode (not showing
* navigational focus because the user is directly pressing the screen).
@@ -2208,6 +2210,10 @@ public class WindowManagerService extends IWindowManager.Stub
&& !win.mCommitDrawPending && !mDisplayFrozen) {
applyEnterAnimationLocked(win);
}
+ if (displayed && (win.mAttrs.flags
+ & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
+ win.mTurnOnScreen = true;
+ }
if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
// To change the format, we need to re-build the surface.
win.destroySurfaceLocked();
@@ -6479,6 +6485,7 @@ public class WindowManagerService extends IWindowManager.Stub
int mLastLayer;
boolean mHaveFrame;
boolean mObscured;
+ boolean mTurnOnScreen;
WindowState mNextOutsideTouch;
@@ -7710,10 +7717,11 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" mDestroying="); pw.print(mDestroying);
pw.print(" mRemoved="); pw.println(mRemoved);
}
- if (mOrientationChanging || mAppFreezing) {
+ if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
pw.print(prefix); pw.print("mOrientationChanging=");
pw.print(mOrientationChanging);
- pw.print(" mAppFreezing="); pw.println(mAppFreezing);
+ pw.print(" mAppFreezing="); pw.print(mAppFreezing);
+ pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
}
if (mHScale != 1 || mVScale != 1) {
pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
@@ -9782,6 +9790,12 @@ public class WindowManagerService extends IWindowManager.Stub
Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
mH.sendMessage(m);
}
+
+ if (mTurnOnScreen) {
+ mPowerManager.userActivity(SystemClock.uptimeMillis(), false,
+ LocalPowerManager.BUTTON_EVENT, true);
+ mTurnOnScreen = false;
+ }
}
void requestAnimationLocked(long delay) {
@@ -9803,6 +9817,10 @@ public class WindowManagerService extends IWindowManager.Stub
try {
if (win.mSurface != null) {
win.mSurface.show();
+ if (win.mTurnOnScreen) {
+ win.mTurnOnScreen = false;
+ mTurnOnScreen = true;
+ }
}
return true;
} catch (RuntimeException e) {
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index b00d8b0b8296c..b6b0e63f19aa6 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -187,6 +187,13 @@ AaptGroupEntry::parseNamePart(const String8& part, int* axis, uint32_t* value)
return 0;
}
+ // navigation hidden
+ if (getNavHiddenName(part.string(), &config)) {
+ *axis = AXIS_NAVHIDDEN;
+ *value = config.inputFlags;
+ return 0;
+ }
+
// navigation
if (getNavigationName(part.string(), &config)) {
*axis = AXIS_NAVIGATION;
@@ -217,7 +224,7 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
Vector parts;
String8 mcc, mnc, loc, layoutsize, layoutlong, orient, den;
- String8 touch, key, keysHidden, nav, size, vers;
+ String8 touch, key, keysHidden, nav, navHidden, size, vers;
const char *p = dir;
const char *q;
@@ -393,6 +400,19 @@ AaptGroupEntry::initFromDirName(const char* dir, String8* resType)
//printf("not keyboard: %s\n", part.string());
}
+ // navigation hidden
+ if (getNavHiddenName(part.string())) {
+ navHidden = part;
+
+ index++;
+ if (index == N) {
+ goto success;
+ }
+ part = parts[index];
+ } else {
+ //printf("not navHidden: %s\n", part.string());
+ }
+
if (getNavigationName(part.string())) {
nav = part;
@@ -443,6 +463,7 @@ success:
this->touchscreen = touch;
this->keysHidden = keysHidden;
this->keyboard = key;
+ this->navHidden = navHidden;
this->navigation = nav;
this->screenSize = size;
this->version = vers;
@@ -476,6 +497,8 @@ AaptGroupEntry::toString() const
s += ",";
s += keyboard;
s += ",";
+ s += navHidden;
+ s += ",";
s += navigation;
s += ",";
s += screenSize;
@@ -528,6 +551,10 @@ AaptGroupEntry::toDirName(const String8& resType) const
s += "-";
s += keyboard;
}
+ if (this->navHidden != "") {
+ s += "-";
+ s += navHidden;
+ }
if (this->navigation != "") {
s += "-";
s += navigation;
@@ -852,6 +879,30 @@ bool AaptGroupEntry::getKeyboardName(const char* name,
return false;
}
+bool AaptGroupEntry::getNavHiddenName(const char* name,
+ ResTable_config* out)
+{
+ uint8_t mask = 0;
+ uint8_t value = 0;
+ if (strcmp(name, kWildcardName) == 0) {
+ mask = out->MASK_NAVHIDDEN;
+ value = out->NAVHIDDEN_ANY;
+ } else if (strcmp(name, "navexposed") == 0) {
+ mask = out->MASK_NAVHIDDEN;
+ value = out->NAVHIDDEN_NO;
+ } else if (strcmp(name, "navhidden") == 0) {
+ mask = out->MASK_NAVHIDDEN;
+ value = out->NAVHIDDEN_YES;
+ }
+
+ if (mask != 0) {
+ if (out) out->inputFlags = (out->inputFlags&~mask) | value;
+ return true;
+ }
+
+ return false;
+}
+
bool AaptGroupEntry::getNavigationName(const char* name,
ResTable_config* out)
{
@@ -953,6 +1004,7 @@ int AaptGroupEntry::compare(const AaptGroupEntry& o) const
if (v == 0) v = touchscreen.compare(o.touchscreen);
if (v == 0) v = keysHidden.compare(o.keysHidden);
if (v == 0) v = keyboard.compare(o.keyboard);
+ if (v == 0) v = navHidden.compare(o.navHidden);
if (v == 0) v = navigation.compare(o.navigation);
if (v == 0) v = screenSize.compare(o.screenSize);
if (v == 0) v = version.compare(o.version);
@@ -973,6 +1025,7 @@ ResTable_config AaptGroupEntry::toParams() const
getTouchscreenName(touchscreen.string(), ¶ms);
getKeysHiddenName(keysHidden.string(), ¶ms);
getKeyboardName(keyboard.string(), ¶ms);
+ getNavHiddenName(navHidden.string(), ¶ms);
getNavigationName(navigation.string(), ¶ms);
getScreenSizeName(screenSize.string(), ¶ms);
getVersionName(version.string(), ¶ms);
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 865efd1eff8b6..26500a34886d4 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -37,6 +37,7 @@ enum {
AXIS_TOUCHSCREEN,
AXIS_KEYSHIDDEN,
AXIS_KEYBOARD,
+ AXIS_NAVHIDDEN,
AXIS_NAVIGATION,
AXIS_SCREENSIZE,
AXIS_VERSION
@@ -64,6 +65,7 @@ public:
String8 touchscreen;
String8 keysHidden;
String8 keyboard;
+ String8 navHidden;
String8 navigation;
String8 screenSize;
String8 version;
@@ -83,6 +85,7 @@ public:
static bool getKeysHiddenName(const char* name, ResTable_config* out = NULL);
static bool getKeyboardName(const char* name, ResTable_config* out = NULL);
static bool getNavigationName(const char* name, ResTable_config* out = NULL);
+ static bool getNavHiddenName(const char* name, ResTable_config* out = NULL);
static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
static bool getVersionName(const char* name, ResTable_config* out = NULL);