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
This commit is contained in:
Dianne Hackborn
2009-09-15 22:50:40 -07:00
parent 6cf05f1c3d
commit 93e462b79d
11 changed files with 241 additions and 16 deletions

View File

@@ -43786,6 +43786,39 @@
visibility="public"
>
</field>
<field name="NAVIGATIONHIDDEN_NO"
type="int"
transient="false"
volatile="false"
value="1"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="NAVIGATIONHIDDEN_UNDEFINED"
type="int"
transient="false"
volatile="false"
value="0"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="NAVIGATIONHIDDEN_YES"
type="int"
transient="false"
volatile="false"
value="2"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="NAVIGATION_DPAD"
type="int"
transient="false"
@@ -44108,6 +44141,16 @@
visibility="public"
>
</field>
<field name="navigationHidden"
type="int"
transient="false"
volatile="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="orientation"
type="int"
transient="false"
@@ -159360,6 +159403,17 @@
visibility="public"
>
</field>
<field name="FLAG_TURN_SCREEN_ON"
type="int"
transient="false"
volatile="false"
value="2097152"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="FLAG_WATCH_OUTSIDE_TOUCH"
type="int"
transient="false"

View File

@@ -217,7 +217,9 @@ public class ActivityInfo extends ComponentInfo
public static final int CONFIG_KEYBOARD = 0x0010;
/**
* Bit in {@link #configChanges} that indicates that the activity
* can itself handle changes to the keyboard being hidden/exposed.
* can itself handle changes to the keyboard or navigation being hidden/exposed.
* Note that inspite of the name, this applies to the changes to any
* hidden states: keyboard or navigation.
* Set from the {@link android.R.attr#configChanges} attribute.
*/
public static final int CONFIG_KEYBOARD_HIDDEN = 0x0020;

View File

@@ -138,6 +138,18 @@ public final class Configuration implements Parcelable, Comparable<Configuration
*/
public int navigation;
public static final int NAVIGATIONHIDDEN_UNDEFINED = 0;
public static final int NAVIGATIONHIDDEN_NO = 1;
public static final int NAVIGATIONHIDDEN_YES = 2;
/**
* A flag indicating whether any 5-way or DPAD navigation available.
* This will be set on a device with a mechanism to hide the navigation
* controls from the user, when that mechanism is closed. One of:
* {@link #NAVIGATIONHIDDEN_NO}, {@link #NAVIGATIONHIDDEN_YES}.
*/
public int navigationHidden;
public static final int ORIENTATION_UNDEFINED = 0;
public static final int ORIENTATION_PORTRAIT = 1;
public static final int ORIENTATION_LANDSCAPE = 2;
@@ -174,6 +186,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
keyboardHidden = o.keyboardHidden;
hardKeyboardHidden = o.hardKeyboardHidden;
navigation = o.navigation;
navigationHidden = o.navigationHidden;
orientation = o.orientation;
screenLayout = o.screenLayout;
}
@@ -198,6 +211,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
sb.append(hardKeyboardHidden);
sb.append(" nav=");
sb.append(navigation);
sb.append("/");
sb.append(navigationHidden);
sb.append(" orien=");
sb.append(orientation);
sb.append(" layout=");
@@ -219,6 +234,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
keyboardHidden = KEYBOARDHIDDEN_UNDEFINED;
hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
navigation = NAVIGATION_UNDEFINED;
navigationHidden = NAVIGATIONHIDDEN_UNDEFINED;
orientation = ORIENTATION_UNDEFINED;
screenLayout = SCREENLAYOUT_SIZE_UNDEFINED;
}
@@ -286,6 +302,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration
changed |= ActivityInfo.CONFIG_NAVIGATION;
navigation = delta.navigation;
}
if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED
&& navigationHidden != delta.navigationHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
navigationHidden = delta.navigationHidden;
}
if (delta.orientation != ORIENTATION_UNDEFINED
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
@@ -360,6 +381,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
&& navigation != delta.navigation) {
changed |= ActivityInfo.CONFIG_NAVIGATION;
}
if (delta.navigationHidden != NAVIGATIONHIDDEN_UNDEFINED
&& navigationHidden != delta.navigationHidden) {
changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
}
if (delta.orientation != ORIENTATION_UNDEFINED
&& orientation != delta.orientation) {
changed |= ActivityInfo.CONFIG_ORIENTATION;
@@ -416,6 +441,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
dest.writeInt(keyboardHidden);
dest.writeInt(hardKeyboardHidden);
dest.writeInt(navigation);
dest.writeInt(navigationHidden);
dest.writeInt(orientation);
dest.writeInt(screenLayout);
}
@@ -448,6 +474,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
keyboardHidden = source.readInt();
hardKeyboardHidden = source.readInt();
navigation = source.readInt();
navigationHidden = source.readInt();
orientation = source.readInt();
screenLayout = source.readInt();
}
@@ -478,6 +505,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
if (n != 0) return n;
n = this.navigation - that.navigation;
if (n != 0) return n;
n = this.navigationHidden - that.navigationHidden;
if (n != 0) return n;
n = this.orientation - that.orientation;
if (n != 0) return n;
n = this.screenLayout - that.screenLayout;
@@ -503,6 +532,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
return ((int)this.fontScale) + this.mcc + this.mnc
+ this.locale.hashCode() + this.touchscreen
+ this.keyboard + this.keyboardHidden + this.hardKeyboardHidden
+ this.navigation + this.orientation + this.screenLayout;
+ this.navigation + this.navigationHidden
+ this.orientation + this.screenLayout;
}
}

View File

@@ -500,6 +500,12 @@ public interface WindowManager extends ViewManager {
*/
public static final int FLAG_SHOW_WALLPAPER = 0x00100000;
/** Window flag: when set as a window is being added or made
* visible, once the window has been shown then the system will
* poke the power manager's user activity (as if the user had woken
* up the device) to turn the screen on. */
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;
/** Window flag: special flag to limit the size of the window to be
* original size ([320x480] x density). Used to create window for applications
* running under compatibility mode.

View File

@@ -504,8 +504,10 @@
<!-- The keyboard type has changed, for example the user has plugged
in an external keyboard. -->
<flag name="keyboard" value="0x0010" />
<!-- The keyboard accessibility has changed, for example the user has
slid the keyboard out to expose it. -->
<!-- The keyboard or navigation accessibility has changed, for example
the user has slid the keyboard out to expose it. Note that
inspite of its name, this applied to any accessibility: keyboard
or navigation. -->
<flag name="keyboardHidden" value="0x0020" />
<!-- The navigation type has changed. Should never normally happen. -->
<flag name="navigation" value="0x0040" />

View File

@@ -35,6 +35,9 @@
<!-- The duration (in milliseconds) of a long animation. -->
<integer name="config_longAnimTime">300</integer>
<!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
Please don't copy them, copy anything else. -->
<!-- This string array should be overridden by the device to present a list of network attributes. This is used by the connectivity manager to decide which networks can coexist based on the hardward -->
<!-- An Array of "[type-name],[associated radio-name],[priority] -->
<string-array translatable="false" name="networkAttributes">
@@ -53,6 +56,16 @@
<item>"wifi,1,1"</item>
<item>"mobile,0,1"</item>
</string-array>
<!-- Flag indicating whether the keyguard should be bypassed when
the slider is open. This can be set or unset depending how easily
the slider can be opened (for example, in a pocket or purse). -->
<bool name="config_bypass_keyguard_if_slider_open">true</bool>
<!-- Flag indicating whether the device supports automatic brightness mode. -->
<bool name="config_automatic_brightness_available">false</bool>
<!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
<!-- The number of degrees to rotate the display when the keyboard is open. -->
<integer name="config_lidOpenRotation">90</integer>
@@ -60,11 +73,18 @@
<!-- The number of degrees to rotate the display when the device is in a dock. -->
<integer name="config_dockedRotation">90</integer>
<!-- Flag indicating whether the keyguard should be bypassed when
the slider is open. This can be set or unset depending how easily
the slider can be opened (for example, in a pocket or purse). -->
<bool name="config_bypass_keyguard_if_slider_open">true</bool>
<!-- Indicate whether the lid state impacts the accessibility of
the physical keyboard. 0 means it doesn't, 1 means it is accessible
when the lid is open, 2 means it is accessible when the lid is
closed. The default is 1. -->
<integer name="config_lidKeyboardAccessibility">1</integer>
<!-- Indicate whether the lid state impacts the accessibility of
the physical keyboard. 0 means it doesn't, 1 means it is accessible
when the lid is open, 2 means it is accessible when the lid is
closed. The default is 0. -->
<integer name="config_lidNavigationAccessibility">0</integer>
<!-- Vibrator pattern for feedback about a long screen/key press -->
<integer-array name="config_longPressVibePattern">
<item>0</item>
@@ -81,6 +101,4 @@
<item>30</item>
</integer-array>
<!-- Flag indicating whether the device supports automatic brightness mode. -->
<bool name="config_automatic_brightness_available">false</bool>
</resources>

View File

@@ -441,7 +441,7 @@ resources for a fully specified configuration would look like this:</p>
<pre>
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/
</pre>
<p>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/
<td>Primary text input method</td>
<td><code>nokeys</code>, <code>qwerty</code>, <code>12key</code> </td>
</tr>
<tr>
<td>Whether the navigation keys are available to the user</td>
<td><p><code>navexposed</code>, <code>navhidden</code>
</p><p>
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.</p></td>
</tr>
<tr>
<td>Primary non-touchscreen<br />
navigation method</td>

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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<String8> 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(), &params);
getKeysHiddenName(keysHidden.string(), &params);
getKeyboardName(keyboard.string(), &params);
getNavHiddenName(navHidden.string(), &params);
getNavigationName(navigation.string(), &params);
getScreenSizeName(screenSize.string(), &params);
getVersionName(version.string(), &params);

View File

@@ -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);