KeyEventCompat.java revision 791f31bbba40b8b51694a1b2cdc804f360786ed1
12a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn/*
22a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Copyright (C) 2011 The Android Open Source Project
32a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn *
42a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
52a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * you may not use this file except in compliance with the License.
62a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * You may obtain a copy of the License at
72a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn *
82a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
92a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn *
102a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
112a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
122a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * See the License for the specific language governing permissions and
142a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * limitations under the License.
152a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */
162a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
172a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackbornpackage android.support.v4.view;
182a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
192a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackbornimport android.view.KeyEvent;
202a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
212a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn/**
220574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * Helper for accessing features in {@link KeyEvent} introduced after
230574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * API level 4 in a backwards compatible fashion.
242a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */
252a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackbornpublic class KeyEventCompat {
262a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    /**
272a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     * Interface for the full API.
282a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     */
292a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    interface KeyEventVersionImpl {
302a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public int normalizeMetaState(int metaState);
312a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasModifiers(int metaState, int modifiers);
322a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasNoModifiers(int metaState);
33791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        public void startTracking(KeyEvent event);
34791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        public boolean isTracking(KeyEvent event);
352a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
362a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
372a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    /**
382a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     * Interface implementation that doesn't use anything about v4 APIs.
392a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     */
402a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    static class BaseKeyEventVersionImpl implements KeyEventVersionImpl {
412a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        private static final int META_MODIFIER_MASK =
422a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON
432a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                | KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON
442a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                | KeyEvent.META_SYM_ON;
452a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
462a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        // Mask of all lock key meta states.
472a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        private static final int META_ALL_MASK = META_MODIFIER_MASK;
482a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
492a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        private static int metaStateFilterDirectionalModifiers(int metaState,
502a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                int modifiers, int basic, int left, int right) {
512a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            final boolean wantBasic = (modifiers & basic) != 0;
522a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            final int directional = left | right;
532a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            final boolean wantLeftOrRight = (modifiers & directional) != 0;
542a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
552a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            if (wantBasic) {
562a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                if (wantLeftOrRight) {
572a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                    throw new IllegalArgumentException("bad arguments");
582a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                }
592a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                return metaState & ~directional;
602a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            } else if (wantLeftOrRight) {
612a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                return metaState & ~basic;
622a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            } else {
632a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                return metaState;
642a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            }
652a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
662a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
672a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
682a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public int normalizeMetaState(int metaState) {
692a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            if ((metaState & (KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON)) != 0) {
702a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                metaState |= KeyEvent.META_SHIFT_ON;
712a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            }
722a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            if ((metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0) {
732a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                metaState |= KeyEvent.META_ALT_ON;
742a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            }
752a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return metaState & META_ALL_MASK;
762a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
772a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
782a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
792a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasModifiers(int metaState, int modifiers) {
802a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            metaState = normalizeMetaState(metaState) & META_MODIFIER_MASK;
812a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
822a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                    KeyEvent.META_SHIFT_ON, KeyEvent.META_SHIFT_LEFT_ON, KeyEvent.META_SHIFT_RIGHT_ON);
832a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
842a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                    KeyEvent.META_ALT_ON, KeyEvent.META_ALT_LEFT_ON, KeyEvent.META_ALT_RIGHT_ON);
852a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return metaState == modifiers;
862a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
872a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
882a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
892a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasNoModifiers(int metaState) {
902a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return (normalizeMetaState(metaState) & META_MODIFIER_MASK) == 0;
912a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
92791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell
93791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        @Override
94791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        public void startTracking(KeyEvent event) {
95791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        }
96791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell
97791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        @Override
98791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        public boolean isTracking(KeyEvent event) {
99791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell            return false;
100791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        }
101791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell    }
102791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell
103791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell    static class EclairKeyEventVersionImpl extends BaseKeyEventVersionImpl {
104791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        @Override
105791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        public void startTracking(KeyEvent event) {
106791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell            KeyEventCompatEclair.startTracking(event);
107791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        }
108791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell
109791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        @Override
110791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        public boolean isTracking(KeyEvent event) {
111791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell            return KeyEventCompatEclair.isTracking(event);
112791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        }
1132a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1142a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1152a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    /**
1162a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     * Interface implementation for devices with at least v11 APIs.
1172a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     */
118791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell    static class HoneycombKeyEventVersionImpl extends EclairKeyEventVersionImpl {
1192a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
1202a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public int normalizeMetaState(int metaState) {
1212a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return KeyEventCompatHoneycomb.normalizeMetaState(metaState);
1222a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1232a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1242a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
1252a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasModifiers(int metaState, int modifiers) {
1262a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return KeyEventCompatHoneycomb.metaStateHasModifiers(metaState, modifiers);
1272a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1282a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1292a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
1302a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasNoModifiers(int metaState) {
1312a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return KeyEventCompatHoneycomb.metaStateHasNoModifiers(metaState);
1322a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1332a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1342a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1352a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    /**
1362a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     * Select the correct implementation to use for the current platform.
1372a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     */
1382a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    static final KeyEventVersionImpl IMPL;
1392a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    static {
1402a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        if (android.os.Build.VERSION.SDK_INT >= 11) {
1412a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            IMPL = new HoneycombKeyEventVersionImpl();
1422a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        } else {
1432a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            IMPL = new BaseKeyEventVersionImpl();
1442a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1452a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1462a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1472a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    // -------------------------------------------------------------------
1482a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1492a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static int normalizeMetaState(int metaState) {
1502a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.normalizeMetaState(metaState);
1512a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1522a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1532a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean metaStateHasModifiers(int metaState, int modifiers) {
1542a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasModifiers(metaState, modifiers);
1552a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1562a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1572a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean metaStateHasNoModifiers(int metaState) {
1582a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasNoModifiers(metaState);
1592a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1602a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1612a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean hasModifiers(KeyEvent event, int modifiers) {
1622a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasModifiers(event.getMetaState(), modifiers);
1632a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1642a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1652a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean hasNoModifiers(KeyEvent event) {
1662a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasNoModifiers(event.getMetaState());
1672a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
168791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell
169791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell    public static void startTracking(KeyEvent event) {
170791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        IMPL.startTracking(event);
171791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell    }
172791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell
173791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell    public static boolean isTracking(KeyEvent event) {
174791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell        return IMPL.isTracking(event);
175791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell    }
1762a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn}
177