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; 20d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackbornimport android.view.View; 212a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 222a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn/** 230574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * Helper for accessing features in {@link KeyEvent} introduced after 240574ca37da4619afe4e26753f5a1b4de314b6565Svetoslav Ganov * API level 4 in a backwards compatible fashion. 252a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 262a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackbornpublic class KeyEventCompat { 272a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn /** 282a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Interface for the full API. 292a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 302a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn interface KeyEventVersionImpl { 312a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public int normalizeMetaState(int metaState); 322a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public boolean metaStateHasModifiers(int metaState, int modifiers); 332a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public boolean metaStateHasNoModifiers(int metaState); 34791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public void startTracking(KeyEvent event); 35791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean isTracking(KeyEvent event); 36d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public Object getKeyDispatcherState(View view); 37d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public boolean dispatch(KeyEvent event, KeyEvent.Callback receiver, Object state, 38d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn Object target); 392a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 402a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 412a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn /** 422a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Interface implementation that doesn't use anything about v4 APIs. 432a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 442a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn static class BaseKeyEventVersionImpl implements KeyEventVersionImpl { 452a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn private static final int META_MODIFIER_MASK = 462a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON 472a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn | KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON 482a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn | KeyEvent.META_SYM_ON; 492a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 502a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn // Mask of all lock key meta states. 512a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn private static final int META_ALL_MASK = META_MODIFIER_MASK; 522a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 532a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn private static int metaStateFilterDirectionalModifiers(int metaState, 542a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn int modifiers, int basic, int left, int right) { 552a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn final boolean wantBasic = (modifiers & basic) != 0; 562a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn final int directional = left | right; 572a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn final boolean wantLeftOrRight = (modifiers & directional) != 0; 582a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 592a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (wantBasic) { 602a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (wantLeftOrRight) { 612a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn throw new IllegalArgumentException("bad arguments"); 622a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 632a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return metaState & ~directional; 642a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } else if (wantLeftOrRight) { 652a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return metaState & ~basic; 662a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } else { 672a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return metaState; 682a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 692a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 702a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 712a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn @Override 722a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public int normalizeMetaState(int metaState) { 732a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if ((metaState & (KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON)) != 0) { 742a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn metaState |= KeyEvent.META_SHIFT_ON; 752a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 762a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if ((metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0) { 772a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn metaState |= KeyEvent.META_ALT_ON; 782a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 792a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return metaState & META_ALL_MASK; 802a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 812a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 822a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn @Override 832a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public boolean metaStateHasModifiers(int metaState, int modifiers) { 842a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn metaState = normalizeMetaState(metaState) & META_MODIFIER_MASK; 852a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn metaState = metaStateFilterDirectionalModifiers(metaState, modifiers, 862a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn KeyEvent.META_SHIFT_ON, KeyEvent.META_SHIFT_LEFT_ON, KeyEvent.META_SHIFT_RIGHT_ON); 872a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn metaState = metaStateFilterDirectionalModifiers(metaState, modifiers, 882a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn KeyEvent.META_ALT_ON, KeyEvent.META_ALT_LEFT_ON, KeyEvent.META_ALT_RIGHT_ON); 892a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return metaState == modifiers; 902a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 912a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 922a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn @Override 932a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public boolean metaStateHasNoModifiers(int metaState) { 942a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return (normalizeMetaState(metaState) & META_MODIFIER_MASK) == 0; 952a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 96791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 97791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 98791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public void startTracking(KeyEvent event) { 99791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 100791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 101791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 102791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean isTracking(KeyEvent event) { 103791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return false; 104791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 105d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn 106d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn @Override 107d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public Object getKeyDispatcherState(View view) { 108d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn return null; 109d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn } 110d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn 111d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn @Override 112d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public boolean dispatch(KeyEvent event, KeyEvent.Callback receiver, Object state, 113d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn Object target) { 114d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn return event.dispatch(receiver); 115d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn } 116791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 117791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 118791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell static class EclairKeyEventVersionImpl extends BaseKeyEventVersionImpl { 119791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 120791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public void startTracking(KeyEvent event) { 121791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell KeyEventCompatEclair.startTracking(event); 122791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 123791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 124791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell @Override 125791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public boolean isTracking(KeyEvent event) { 126791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return KeyEventCompatEclair.isTracking(event); 127791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 128d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn 129d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn @Override 130d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public Object getKeyDispatcherState(View view) { 131d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn return KeyEventCompatEclair.getKeyDispatcherState(view); 132d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn } 133d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn 134d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn @Override 135d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public boolean dispatch(KeyEvent event, KeyEvent.Callback receiver, Object state, 136d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn Object target) { 137d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn return KeyEventCompatEclair.dispatch(event, receiver, state, target); 138d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn } 1392a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1402a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1412a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn /** 1422a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Interface implementation for devices with at least v11 APIs. 1432a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 144791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell static class HoneycombKeyEventVersionImpl extends EclairKeyEventVersionImpl { 1452a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn @Override 1462a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public int normalizeMetaState(int metaState) { 1472a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return KeyEventCompatHoneycomb.normalizeMetaState(metaState); 1482a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1492a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1502a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn @Override 1512a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public boolean metaStateHasModifiers(int metaState, int modifiers) { 1522a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return KeyEventCompatHoneycomb.metaStateHasModifiers(metaState, modifiers); 1532a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1542a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1552a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn @Override 1562a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public boolean metaStateHasNoModifiers(int metaState) { 1572a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return KeyEventCompatHoneycomb.metaStateHasNoModifiers(metaState); 1582a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1592a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1602a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1612a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn /** 1622a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn * Select the correct implementation to use for the current platform. 1632a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn */ 1642a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn static final KeyEventVersionImpl IMPL; 1652a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn static { 1662a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn if (android.os.Build.VERSION.SDK_INT >= 11) { 1672a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn IMPL = new HoneycombKeyEventVersionImpl(); 1682a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } else { 1692a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn IMPL = new BaseKeyEventVersionImpl(); 1702a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1712a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1722a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1732a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn // ------------------------------------------------------------------- 1742a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1752a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public static int normalizeMetaState(int metaState) { 1762a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return IMPL.normalizeMetaState(metaState); 1772a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1782a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1792a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public static boolean metaStateHasModifiers(int metaState, int modifiers) { 1802a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return IMPL.metaStateHasModifiers(metaState, modifiers); 1812a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1822a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1832a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public static boolean metaStateHasNoModifiers(int metaState) { 1842a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return IMPL.metaStateHasNoModifiers(metaState); 1852a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1862a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1872a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public static boolean hasModifiers(KeyEvent event, int modifiers) { 1882a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return IMPL.metaStateHasModifiers(event.getMetaState(), modifiers); 1892a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 1902a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn 1912a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn public static boolean hasNoModifiers(KeyEvent event) { 1922a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn return IMPL.metaStateHasNoModifiers(event.getMetaState()); 1932a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn } 194791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 195791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public static void startTracking(KeyEvent event) { 196791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell IMPL.startTracking(event); 197791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 198791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell 199791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell public static boolean isTracking(KeyEvent event) { 200791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell return IMPL.isTracking(event); 201791f31bbba40b8b51694a1b2cdc804f360786ed1Adam Powell } 202d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn 203d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public static Object getKeyDispatcherState(View view) { 204d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn return IMPL.getKeyDispatcherState(view); 205d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn } 206d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn 207d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn public static boolean dispatch(KeyEvent event, KeyEvent.Callback receiver, Object state, 208d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn Object target) { 209d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn return IMPL.dispatch(event, receiver, state, target); 210d3a70800e5f2cc2855d53ebea82fb7568affe02aDianne Hackborn } 2112a4d8518f36346ea25a22a736453ff28f2954165Dianne Hackborn} 212