mobile/android/base/util/GamepadUtils.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko.util;
     8 import android.os.Build;
     9 import android.view.InputDevice;
    10 import android.view.KeyCharacterMap;
    11 import android.view.KeyEvent;
    12 import android.view.MotionEvent;
    13 import android.view.View;
    14 import android.widget.AdapterView;
    15 import android.widget.ListView;
    17 public final class GamepadUtils {
    18     private static final int SONY_XPERIA_GAMEPAD_DEVICE_ID = 196611;
    20     private static View.OnKeyListener sClickDispatcher;
    21     private static float sDeadZoneThresholdOverride = 1e-2f;
    23     private GamepadUtils() {
    24     }
    26     private static boolean isGamepadKey(KeyEvent event) {
    27         if (Build.VERSION.SDK_INT >= 9) {
    28             return (event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD;
    29         }
    30         return false;
    31     }
    33     public static boolean isActionKey(KeyEvent event) {
    34         return (isGamepadKey(event) && (event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_A));
    35     }
    37     public static boolean isActionKeyDown(KeyEvent event) {
    38         return isActionKey(event) && event.getAction() == KeyEvent.ACTION_DOWN;
    39     }
    41     public static boolean isBackKey(KeyEvent event) {
    42         return (isGamepadKey(event) && (event.getKeyCode() == KeyEvent.KEYCODE_BUTTON_B));
    43     }
    45     public static void overrideDeadZoneThreshold(float threshold) {
    46         sDeadZoneThresholdOverride = threshold;
    47     }
    49     public static boolean isValueInDeadZone(MotionEvent event, int axis) {
    50         if (Build.VERSION.SDK_INT < 9) {
    51             return false;
    52         }
    54         float threshold;
    55         if (sDeadZoneThresholdOverride >= 0) {
    56             threshold = sDeadZoneThresholdOverride;
    57         } else {
    58             InputDevice.MotionRange range = event.getDevice().getMotionRange(axis);
    59             threshold = range.getFlat() + range.getFuzz();
    60         }
    61         float value = event.getAxisValue(axis);
    62         return (Math.abs(value) < threshold);
    63     }
    65     public static boolean isPanningControl(MotionEvent event) {
    66         if (Build.VERSION.SDK_INT < 12) {
    67             return false;
    68         }
    69         if ((event.getSource() & InputDevice.SOURCE_CLASS_MASK) != InputDevice.SOURCE_CLASS_JOYSTICK) {
    70             return false;
    71         }
    72         if (isValueInDeadZone(event, MotionEvent.AXIS_X)
    73                 && isValueInDeadZone(event, MotionEvent.AXIS_Y)
    74                 && isValueInDeadZone(event, MotionEvent.AXIS_Z)
    75                 && isValueInDeadZone(event, MotionEvent.AXIS_RZ)) {
    76             return false;
    77         }
    78         return true;
    79     }
    81     public static View.OnKeyListener getClickDispatcher() {
    82         if (sClickDispatcher == null) {
    83             sClickDispatcher = new View.OnKeyListener() {
    84                 @Override
    85                 public boolean onKey(View v, int keyCode, KeyEvent event) {
    86                     if (isActionKeyDown(event)) {
    87                         return v.performClick();
    88                     }
    89                     return false;
    90                 }
    91             };
    92         }
    93         return sClickDispatcher;
    94     }
    96     public static KeyEvent translateSonyXperiaGamepadKeys(int keyCode, KeyEvent event) {
    97         // The cross and circle button mappings may be swapped in the different regions so
    98         // determine if they are swapped so the proper key codes can be mapped to the keys
    99         boolean areKeysSwapped = areSonyXperiaGamepadKeysSwapped();
   101         // If a Sony Xperia, remap the cross and circle buttons to buttons
   102         // A and B for the gamepad API
   103         switch (keyCode) {
   104             case KeyEvent.KEYCODE_BACK:
   105                 keyCode = (areKeysSwapped ? KeyEvent.KEYCODE_BUTTON_A : KeyEvent.KEYCODE_BUTTON_B);
   106                 break;
   108             case KeyEvent.KEYCODE_DPAD_CENTER:
   109                 keyCode = (areKeysSwapped ? KeyEvent.KEYCODE_BUTTON_B : KeyEvent.KEYCODE_BUTTON_A);
   110                 break;
   112             default:
   113                 return event;
   114         }
   116         return new KeyEvent(event.getAction(), keyCode);
   117     }
   119     public static boolean isSonyXperiaGamepadKeyEvent(KeyEvent event) {
   120         return (event.getDeviceId() == SONY_XPERIA_GAMEPAD_DEVICE_ID &&
   121                 "Sony Ericsson".equals(Build.MANUFACTURER) &&
   122                 ("R800".equals(Build.MODEL) || "R800i".equals(Build.MODEL)));
   123     }
   125     private static boolean areSonyXperiaGamepadKeysSwapped() {
   126         // The cross and circle buttons on Sony Xperia phones are swapped
   127         // in different regions
   128         // http://developer.sonymobile.com/2011/02/13/xperia-play-game-keys/
   129         final char DEFAULT_O_BUTTON_LABEL = 0x25CB;
   131         boolean swapped = false;
   132         int[] deviceIds = InputDevice.getDeviceIds();
   134         for (int i= 0; deviceIds != null && i < deviceIds.length; i++) {
   135             KeyCharacterMap keyCharacterMap = KeyCharacterMap.load(deviceIds[i]);
   136             if (keyCharacterMap != null && DEFAULT_O_BUTTON_LABEL ==
   137                 keyCharacterMap.getDisplayLabel(KeyEvent.KEYCODE_DPAD_CENTER)) {
   138                 swapped = true;
   139                 break;
   140             }
   141         }
   142         return swapped;
   143     }
   144 }

mercurial