am e0e9fd98
: Merge "Fix system hotkey handling." into ics-mr1
* commit 'e0e9fd981ca71aeaa45c888485c11788456bd838': Fix system hotkey handling.
This commit is contained in:
@ -810,7 +810,7 @@ please see themes_device_defaults.xml.
|
|||||||
|
|
||||||
<!-- Special theme for the recent apps dialog, to allow customization
|
<!-- Special theme for the recent apps dialog, to allow customization
|
||||||
with overlays. -->
|
with overlays. -->
|
||||||
<style name="Theme.Dialog.RecentApplications">
|
<style name="Theme.Dialog.RecentApplications" parent="Theme.DeviceDefault.Dialog">
|
||||||
<item name="windowFrame">@null</item>
|
<item name="windowFrame">@null</item>
|
||||||
<item name="windowBackground">@android:color/transparent</item>
|
<item name="windowBackground">@android:color/transparent</item>
|
||||||
<item name="android:windowAnimationStyle">@android:style/Animation.RecentApplications</item>
|
<item name="android:windowAnimationStyle">@android:style/Animation.RecentApplications</item>
|
||||||
|
@ -38,6 +38,8 @@ import android.text.StaticLayout;
|
|||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.ContextThemeWrapper;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
@ -74,9 +76,13 @@ final class IconUtilities {
|
|||||||
mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2);
|
mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2);
|
||||||
|
|
||||||
mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL));
|
mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL));
|
||||||
mGlowColorPressedPaint.setColor(0xffffc300);
|
|
||||||
|
TypedValue value = new TypedValue();
|
||||||
|
mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute(
|
||||||
|
android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300);
|
||||||
mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
|
mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
|
||||||
mGlowColorFocusedPaint.setColor(0xffff8e00);
|
mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute(
|
||||||
|
android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00);
|
||||||
mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
|
mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
|
||||||
|
|
||||||
ColorMatrix cm = new ColorMatrix();
|
ColorMatrix cm = new ColorMatrix();
|
||||||
|
@ -298,9 +298,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
GlobalActions mGlobalActions;
|
GlobalActions mGlobalActions;
|
||||||
volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
|
volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
|
||||||
boolean mPendingPowerKeyUpCanceled;
|
boolean mPendingPowerKeyUpCanceled;
|
||||||
RecentApplicationsDialog mRecentAppsDialog;
|
|
||||||
Handler mHandler;
|
Handler mHandler;
|
||||||
|
|
||||||
|
static final int RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS = 0;
|
||||||
|
static final int RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW = 1;
|
||||||
|
static final int RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH = 2;
|
||||||
|
|
||||||
|
RecentApplicationsDialog mRecentAppsDialog;
|
||||||
|
int mRecentAppsDialogHeldModifiers;
|
||||||
|
|
||||||
private static final int LID_ABSENT = -1;
|
private static final int LID_ABSENT = -1;
|
||||||
private static final int LID_CLOSED = 0;
|
private static final int LID_CLOSED = 0;
|
||||||
private static final int LID_OPEN = 1;
|
private static final int LID_OPEN = 1;
|
||||||
@ -693,7 +699,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
|
if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
|
||||||
showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
|
showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
|
||||||
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
|
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
|
||||||
try {
|
try {
|
||||||
mStatusBarService.toggleRecentApps();
|
mStatusBarService.toggleRecentApps();
|
||||||
@ -704,10 +710,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create (if necessary) and launch the recent apps dialog, or hide it if it is
|
* Create (if necessary) and show or dismiss the recent apps dialog according
|
||||||
* already shown.
|
* according to the requested behavior.
|
||||||
*/
|
*/
|
||||||
void showOrHideRecentAppsDialog(final int heldModifiers, final boolean dismissIfShown) {
|
void showOrHideRecentAppsDialog(final int behavior) {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -715,12 +721,33 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
mRecentAppsDialog = new RecentApplicationsDialog(mContext);
|
mRecentAppsDialog = new RecentApplicationsDialog(mContext);
|
||||||
}
|
}
|
||||||
if (mRecentAppsDialog.isShowing()) {
|
if (mRecentAppsDialog.isShowing()) {
|
||||||
if (dismissIfShown) {
|
switch (behavior) {
|
||||||
|
case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
|
||||||
mRecentAppsDialog.dismiss();
|
mRecentAppsDialog.dismiss();
|
||||||
|
break;
|
||||||
|
case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
|
||||||
|
mRecentAppsDialog.dismissAndSwitch();
|
||||||
|
break;
|
||||||
|
case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mRecentAppsDialog.setHeldModifiers(heldModifiers);
|
switch (behavior) {
|
||||||
|
case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
|
||||||
mRecentAppsDialog.show();
|
mRecentAppsDialog.show();
|
||||||
|
break;
|
||||||
|
case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
|
||||||
|
try {
|
||||||
|
mWindowManager.setInTouchMode(false);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
}
|
||||||
|
mRecentAppsDialog.show();
|
||||||
|
break;
|
||||||
|
case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1598,7 +1625,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
return 0;
|
return 0;
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
|
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
|
||||||
if (down && repeatCount == 0) {
|
if (down && repeatCount == 0) {
|
||||||
showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
|
showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1634,6 +1661,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoke shortcuts using Meta.
|
||||||
|
if (down && repeatCount == 0
|
||||||
|
&& (metaState & KeyEvent.META_META_ON) != 0) {
|
||||||
|
final KeyCharacterMap kcm = event.getKeyCharacterMap();
|
||||||
|
Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
|
||||||
|
metaState & ~(KeyEvent.META_META_ON
|
||||||
|
| KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
|
||||||
|
if (shortcutIntent != null) {
|
||||||
|
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
try {
|
||||||
|
mContext.startActivity(shortcutIntent);
|
||||||
|
} catch (ActivityNotFoundException ex) {
|
||||||
|
Slog.w(TAG, "Dropping shortcut key combination because "
|
||||||
|
+ "the activity to which it is registered was not found: "
|
||||||
|
+ "META+" + KeyEvent.keyCodeToString(keyCode), ex);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle application launch keys.
|
// Handle application launch keys.
|
||||||
if (down && repeatCount == 0) {
|
if (down && repeatCount == 0) {
|
||||||
String category = sApplicationLaunchKeyCategories.get(keyCode);
|
String category = sApplicationLaunchKeyCategories.get(keyCode);
|
||||||
@ -1647,9 +1694,29 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
+ "the activity to which it is registered was not found: "
|
+ "the activity to which it is registered was not found: "
|
||||||
+ "keyCode=" + keyCode + ", category=" + category, ex);
|
+ "keyCode=" + keyCode + ", category=" + category, ex);
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display task switcher for ALT-TAB or Meta-TAB.
|
||||||
|
if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
|
||||||
|
if (mRecentAppsDialogHeldModifiers == 0) {
|
||||||
|
final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
|
||||||
|
if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
|
||||||
|
|| KeyEvent.metaStateHasModifiers(
|
||||||
|
shiftlessModifiers, KeyEvent.META_META_ON)) {
|
||||||
|
mRecentAppsDialogHeldModifiers = shiftlessModifiers;
|
||||||
|
showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!down && mRecentAppsDialogHeldModifiers != 0
|
||||||
|
&& (metaState & mRecentAppsDialogHeldModifiers) == 0) {
|
||||||
|
mRecentAppsDialogHeldModifiers = 0;
|
||||||
|
showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let the application handle the key.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1671,39 +1738,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
final KeyCharacterMap kcm = event.getKeyCharacterMap();
|
final KeyCharacterMap kcm = event.getKeyCharacterMap();
|
||||||
final int keyCode = event.getKeyCode();
|
final int keyCode = event.getKeyCode();
|
||||||
final int metaState = event.getMetaState();
|
final int metaState = event.getMetaState();
|
||||||
final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
|
|
||||||
&& event.getRepeatCount() == 0;
|
|
||||||
|
|
||||||
if (initialDown) {
|
|
||||||
// Invoke shortcuts using Meta as a fallback.
|
|
||||||
if ((metaState & KeyEvent.META_META_ON) != 0) {
|
|
||||||
Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
|
|
||||||
metaState & ~(KeyEvent.META_META_ON
|
|
||||||
| KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
|
|
||||||
if (shortcutIntent != null) {
|
|
||||||
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
try {
|
|
||||||
mContext.startActivity(shortcutIntent);
|
|
||||||
} catch (ActivityNotFoundException ex) {
|
|
||||||
Slog.w(TAG, "Dropping shortcut key combination because "
|
|
||||||
+ "the activity to which it is registered was not found: "
|
|
||||||
+ "META+" + KeyEvent.keyCodeToString(keyCode), ex);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display task switcher for ALT-TAB or Meta-TAB.
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_TAB) {
|
|
||||||
final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
|
|
||||||
if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
|
|
||||||
|| KeyEvent.metaStateHasModifiers(
|
|
||||||
shiftlessModifiers, KeyEvent.META_META_ON)) {
|
|
||||||
showOrHideRecentAppsDialog(shiftlessModifiers, false /*dismissIfShown*/);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for fallback actions specified by the key character map.
|
// Check for fallback actions specified by the key character map.
|
||||||
if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
|
if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
|
||||||
|
@ -71,8 +71,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private int mHeldModifiers;
|
|
||||||
|
|
||||||
public RecentApplicationsDialog(Context context) {
|
public RecentApplicationsDialog(Context context) {
|
||||||
super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
|
super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
|
||||||
|
|
||||||
@ -124,17 +122,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the modifier keys that are being held to keep the dialog open, or 0 if none.
|
|
||||||
* Used to make the recent apps dialog automatically dismiss itself when the modifiers
|
|
||||||
* all go up.
|
|
||||||
* @param heldModifiers The held key modifiers, such as {@link KeyEvent#META_ALT_ON}.
|
|
||||||
* Should exclude shift.
|
|
||||||
*/
|
|
||||||
public void setHeldModifiers(int heldModifiers) {
|
|
||||||
mHeldModifiers = heldModifiers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_TAB) {
|
if (keyCode == KeyEvent.KEYCODE_TAB) {
|
||||||
@ -174,9 +161,10 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
|
|||||||
return super.onKeyDown(keyCode, event);
|
return super.onKeyDown(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
* Dismiss the dialog and switch to the selected application.
|
||||||
if (mHeldModifiers != 0 && (event.getModifiers() & mHeldModifiers) == 0) {
|
*/
|
||||||
|
public void dismissAndSwitch() {
|
||||||
final int numIcons = mIcons.length;
|
final int numIcons = mIcons.length;
|
||||||
RecentTag tag = null;
|
RecentTag tag = null;
|
||||||
for (int i = 0; i < numIcons; i++) {
|
for (int i = 0; i < numIcons; i++) {
|
||||||
@ -194,10 +182,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
|
|||||||
switchTo(tag);
|
switchTo(tag);
|
||||||
}
|
}
|
||||||
dismiss();
|
dismiss();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onKeyUp(keyCode, event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4320,12 +4320,23 @@ bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
|
|||||||
mKeyMementos.removeAt(index);
|
mKeyMementos.removeAt(index);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/* FIXME: We can't just drop the key up event because that prevents creating
|
||||||
|
* popup windows that are automatically shown when a key is held and then
|
||||||
|
* dismissed when the key is released. The problem is that the popup will
|
||||||
|
* not have received the original key down, so the key up will be considered
|
||||||
|
* to be inconsistent with its observed state. We could perhaps handle this
|
||||||
|
* by synthesizing a key down but that will cause other problems.
|
||||||
|
*
|
||||||
|
* So for now, allow inconsistent key up events to be dispatched.
|
||||||
|
*
|
||||||
#if DEBUG_OUTBOUND_EVENT_DETAILS
|
#if DEBUG_OUTBOUND_EVENT_DETAILS
|
||||||
LOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
|
LOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
|
||||||
"keyCode=%d, scanCode=%d",
|
"keyCode=%d, scanCode=%d",
|
||||||
entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
|
entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AKEY_EVENT_ACTION_DOWN: {
|
case AKEY_EVENT_ACTION_DOWN: {
|
||||||
|
Reference in New Issue
Block a user