Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0e9fd98 authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Fix system hotkey handling." into ics-mr1

parents ef8913c0 68b909d8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -810,7 +810,7 @@ please see themes_device_defaults.xml.
    
    <!-- Special theme for the recent apps dialog, to allow customization
         with overlays. -->
    <style name="Theme.Dialog.RecentApplications">
    <style name="Theme.Dialog.RecentApplications" parent="Theme.DeviceDefault.Dialog">
        <item name="windowFrame">@null</item>
        <item name="windowBackground">@android:color/transparent</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.RecentApplications</item>
+8 −2
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.content.res.Resources;
import android.content.Context;

@@ -74,9 +76,13 @@ final class IconUtilities {
        mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2);

        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));
        mGlowColorFocusedPaint.setColor(0xffff8e00);
        mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute(
                android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00);
        mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));

        ColorMatrix cm = new ColorMatrix();
+77 −43
Original line number Diff line number Diff line
@@ -298,9 +298,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    GlobalActions mGlobalActions;
    volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
    boolean mPendingPowerKeyUpCanceled;
    RecentApplicationsDialog mRecentAppsDialog;
    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_CLOSED = 0;
    private static final int LID_OPEN = 1;
@@ -693,7 +699,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        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) {
            try {
                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
     * already shown.
     * Create (if necessary) and show or dismiss the recent apps dialog according
     * according to the requested behavior.
     */
    void showOrHideRecentAppsDialog(final int heldModifiers, final boolean dismissIfShown) {
    void showOrHideRecentAppsDialog(final int behavior) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
@@ -715,12 +721,33 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    mRecentAppsDialog = new RecentApplicationsDialog(mContext);
                }
                if (mRecentAppsDialog.isShowing()) {
                    if (dismissIfShown) {
                    switch (behavior) {
                        case RECENT_APPS_BEHAVIOR_SHOW_OR_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 {
                    mRecentAppsDialog.setHeldModifiers(heldModifiers);
                    switch (behavior) {
                        case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
                            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;
        } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
            if (down && repeatCount == 0) {
                showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
                showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
            }
            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.
        if (down && repeatCount == 0) {
            String category = sApplicationLaunchKeyCategories.get(keyCode);
@@ -1647,9 +1694,29 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                            + "the activity to which it is registered was not found: "
                            + "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;
    }

@@ -1671,39 +1738,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            final KeyCharacterMap kcm = event.getKeyCharacterMap();
            final int keyCode = event.getKeyCode();
            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.
            if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
+17 −33
Original line number Diff line number Diff line
@@ -71,8 +71,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
        }
    };

    private int mHeldModifiers;

    public RecentApplicationsDialog(Context context) {
        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
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_TAB) {
@@ -174,9 +161,10 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (mHeldModifiers != 0 && (event.getModifiers() & mHeldModifiers) == 0) {
    /**
     * Dismiss the dialog and switch to the selected application.
     */
    public void dismissAndSwitch() {
        final int numIcons = mIcons.length;
        RecentTag tag = null;
        for (int i = 0; i < numIcons; i++) {
@@ -194,10 +182,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
            switchTo(tag);
        }
        dismiss();
            return true;
        }

        return super.onKeyUp(keyCode, event);
    }

    /**
+11 −0
Original line number Diff line number Diff line
@@ -4320,12 +4320,23 @@ bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
            mKeyMementos.removeAt(index);
            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
        LOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
                "keyCode=%d, scanCode=%d",
                entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
#endif
        return false;
        */
        return true;
    }

    case AKEY_EVENT_ACTION_DOWN: {