KeyEventCompat.java revision 2a4d8518f36346ea25a22a736453ff28f2954165
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.text.method.MetaKeyKeyListener;
202a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackbornimport android.view.KeyEvent;
212a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
222a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn/**
232a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Helper for accessing newer features in KeyEvent.
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);
332a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
342a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
352a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    /**
362a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     * Interface implementation that doesn't use anything about v4 APIs.
372a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     */
382a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    static class BaseKeyEventVersionImpl implements KeyEventVersionImpl {
392a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        private static final int META_MODIFIER_MASK =
402a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON
412a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                | KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON
422a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                | KeyEvent.META_SYM_ON;
432a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
442a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        // Mask of all lock key meta states.
452a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        private static final int META_ALL_MASK = META_MODIFIER_MASK;
462a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
472a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        private static int metaStateFilterDirectionalModifiers(int metaState,
482a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                int modifiers, int basic, int left, int right) {
492a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            final boolean wantBasic = (modifiers & basic) != 0;
502a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            final int directional = left | right;
512a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            final boolean wantLeftOrRight = (modifiers & directional) != 0;
522a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
532a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            if (wantBasic) {
542a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                if (wantLeftOrRight) {
552a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                    throw new IllegalArgumentException("bad arguments");
562a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                }
572a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                return metaState & ~directional;
582a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            } else if (wantLeftOrRight) {
592a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                return metaState & ~basic;
602a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            } else {
612a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                return metaState;
622a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            }
632a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
642a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
652a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
662a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public int normalizeMetaState(int metaState) {
672a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            if ((metaState & (KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON)) != 0) {
682a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                metaState |= KeyEvent.META_SHIFT_ON;
692a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            }
702a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            if ((metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0) {
712a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                metaState |= KeyEvent.META_ALT_ON;
722a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            }
732a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return metaState & META_ALL_MASK;
742a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
752a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
762a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
772a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasModifiers(int metaState, int modifiers) {
782a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            metaState = normalizeMetaState(metaState) & META_MODIFIER_MASK;
792a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
802a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                    KeyEvent.META_SHIFT_ON, KeyEvent.META_SHIFT_LEFT_ON, KeyEvent.META_SHIFT_RIGHT_ON);
812a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
822a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn                    KeyEvent.META_ALT_ON, KeyEvent.META_ALT_LEFT_ON, KeyEvent.META_ALT_RIGHT_ON);
832a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return metaState == modifiers;
842a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
852a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
862a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
872a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasNoModifiers(int metaState) {
882a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return (normalizeMetaState(metaState) & META_MODIFIER_MASK) == 0;
892a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
902a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
912a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
922a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    /**
932a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     * Interface implementation for devices with at least v11 APIs.
942a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     */
952a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    static class HoneycombKeyEventVersionImpl implements KeyEventVersionImpl {
962a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
972a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public int normalizeMetaState(int metaState) {
982a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return KeyEventCompatHoneycomb.normalizeMetaState(metaState);
992a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1002a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1012a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
1022a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasModifiers(int metaState, int modifiers) {
1032a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return KeyEventCompatHoneycomb.metaStateHasModifiers(metaState, modifiers);
1042a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1052a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1062a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        @Override
1072a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        public boolean metaStateHasNoModifiers(int metaState) {
1082a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            return KeyEventCompatHoneycomb.metaStateHasNoModifiers(metaState);
1092a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1102a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1112a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1122a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    /**
1132a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     * Select the correct implementation to use for the current platform.
1142a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn     */
1152a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    static final KeyEventVersionImpl IMPL;
1162a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    static {
1172a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        if (android.os.Build.VERSION.SDK_INT >= 11) {
1182a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            IMPL = new HoneycombKeyEventVersionImpl();
1192a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        } else {
1202a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn            IMPL = new BaseKeyEventVersionImpl();
1212a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        }
1222a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1232a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1242a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    // -------------------------------------------------------------------
1252a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1262a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static int normalizeMetaState(int metaState) {
1272a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.normalizeMetaState(metaState);
1282a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1292a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1302a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean metaStateHasModifiers(int metaState, int modifiers) {
1312a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasModifiers(metaState, modifiers);
1322a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1332a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1342a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean metaStateHasNoModifiers(int metaState) {
1352a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasNoModifiers(metaState);
1362a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1372a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1382a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean hasModifiers(KeyEvent event, int modifiers) {
1392a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasModifiers(event.getMetaState(), modifiers);
1402a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1412a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn
1422a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    public static boolean hasNoModifiers(KeyEvent event) {
1432a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn        return IMPL.metaStateHasNoModifiers(event.getMetaState());
1442a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn    }
1452a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn}
146