Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.content.browser; | |
| 6 | |
| 7 import android.content.Context; | |
| 8 import android.hardware.input.InputManager; | |
| 9 import android.hardware.input.InputManager.InputDeviceListener; | |
| 10 import android.view.InputDevice; | |
| 11 import android.view.InputEvent; | |
| 12 import android.view.KeyEvent; | |
| 13 import android.view.MotionEvent; | |
| 14 | |
| 15 import org.chromium.base.CalledByNative; | |
| 16 import org.chromium.base.JNINamespace; | |
| 17 import org.chromium.base.ThreadUtils; | |
| 18 | |
| 19 /* | |
| 20 * Class to manage connected gamepad devices list. | |
| 21 */ | |
| 22 @JNINamespace("content") | |
| 23 class GamepadList implements InputDeviceListener { | |
| 24 private static final int MAX_GAMEPADS = 4; | |
| 25 private GamepadDevice[] mGamepadDevices = new GamepadDevice[MAX_GAMEPADS]; | |
|
Ted C
2014/04/04 18:52:18
for readability, try to order the params like:
st
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Done.
| |
| 26 private boolean mIsGamepadAccessed = false; | |
|
Ted C
2014/04/04 18:52:18
false is the default, so it's not needed
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Removed
| |
| 27 private final Object mLock = new Object(); | |
| 28 private InputManager mInputManager; | |
| 29 private int mAttachedToWindowCounter; | |
| 30 | |
| 31 private GamepadList() {} | |
| 32 | |
| 33 private void initializeDevices() { | |
| 34 // Get list of all the attached input devices. | |
| 35 int[] deviceIds = mInputManager.getInputDeviceIds(); | |
| 36 for (int i = 0; i < deviceIds.length; i++) { | |
| 37 InputDevice inputDevice = InputDevice.getDevice(deviceIds[i]); | |
| 38 // Check for gamepad device | |
| 39 if (isGamepadDevice(inputDevice)) { | |
| 40 // Register a new gamepad device. | |
| 41 registerGamepad(inputDevice); | |
| 42 } | |
| 43 } | |
| 44 } | |
| 45 | |
| 46 private static GamepadList sGamepadList = null; | |
|
Ted C
2014/04/04 18:52:18
move this up with the other params.
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Done.
| |
| 47 | |
| 48 /** | |
| 49 * Notifies the GamepadList that a {@link ContentView} is attached to a windo w and it should | |
| 50 * prepare itself for gamepad input. It must be called before {@link onGeneri cMotionEvent} and | |
| 51 * {@link dispatchKeyEvent}. | |
| 52 */ | |
| 53 public static void onAttachedToWindow(Context context) { | |
| 54 assert ThreadUtils.runningOnUiThread(); | |
| 55 createInstance(); | |
| 56 sGamepadList.attachedToWindow(context); | |
| 57 } | |
| 58 | |
| 59 private void attachedToWindow(Context context) { | |
| 60 if (mAttachedToWindowCounter++ == 0) { | |
| 61 mInputManager = (InputManager) context.getSystemService(Context.INP UT_SERVICE); | |
| 62 synchronized (mLock) { | |
| 63 initializeDevices(); | |
| 64 } | |
| 65 // Register an input device listener. | |
| 66 mInputManager.registerInputDeviceListener(this, null); | |
| 67 } | |
| 68 } | |
| 69 | |
| 70 /** | |
| 71 * Notifies the GamepadList that a {@link ContentView} is detached from it's window. | |
| 72 */ | |
| 73 public static void onDetachedFromWindow() { | |
| 74 assert ThreadUtils.runningOnUiThread(); | |
| 75 sGamepadList.detachedFromWindow(); | |
| 76 } | |
| 77 | |
| 78 private void detachedFromWindow() { | |
| 79 if (--mAttachedToWindowCounter == 0) { | |
| 80 synchronized (mLock) { | |
| 81 for (int i = 0; i < MAX_GAMEPADS; ++i) { | |
| 82 mGamepadDevices[i] = null; | |
| 83 } | |
| 84 } | |
| 85 mInputManager.unregisterInputDeviceListener(this); | |
| 86 mInputManager = null; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 // ------------------------------------------------------------ | |
| 91 | |
| 92 // Override InputDeviceListener methods | |
| 93 @Override | |
| 94 public void onInputDeviceChanged(int deviceId) { | |
| 95 } | |
| 96 | |
| 97 @Override | |
| 98 public void onInputDeviceRemoved(int deviceId) { | |
| 99 synchronized (mLock) { | |
| 100 unregisterGamepad(deviceId); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 @Override | |
| 105 public void onInputDeviceAdded(int deviceId) { | |
| 106 InputDevice inputDevice = InputDevice.getDevice(deviceId); | |
| 107 if (!isGamepadDevice(inputDevice)) return; | |
| 108 synchronized (mLock) { | |
| 109 registerGamepad(inputDevice); | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 // ------------------------------------------------------------ | |
| 114 | |
| 115 private static void createInstance() { | |
| 116 if (sGamepadList == null) { | |
| 117 sGamepadList = new GamepadList(); | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 private int getDeviceCount() { | |
| 122 int count = 0; | |
| 123 for (int i = 0; i < MAX_GAMEPADS; ++i) { | |
|
Ted C
2014/04/04 18:52:18
i++
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Done.
| |
| 124 if (getDevice(i) != null) { | |
| 125 count++; | |
| 126 } | |
| 127 } | |
| 128 return count; | |
| 129 } | |
| 130 | |
| 131 private boolean isDeviceConnected(int index) { | |
| 132 if (index < MAX_GAMEPADS && getDevice(index) != null) { | |
| 133 return true; | |
| 134 } | |
| 135 return false; | |
| 136 } | |
| 137 | |
| 138 private GamepadDevice getDeviceById(int deviceId) { | |
| 139 for (int i = 0; i < MAX_GAMEPADS; ++i) { | |
|
Ted C
2014/04/04 18:52:18
i++
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Done.
| |
| 140 GamepadDevice gamepad = mGamepadDevices[i]; | |
| 141 if (gamepad != null && gamepad.getId() == deviceId) { | |
| 142 return gamepad; | |
| 143 } | |
| 144 } | |
| 145 return null; | |
| 146 } | |
| 147 | |
| 148 private GamepadDevice getDevice(int index) { | |
| 149 // Maximum 4 Gamepads can be connected at a time starting at index zero. | |
| 150 assert index >= 0 && index < MAX_GAMEPADS; | |
| 151 return mGamepadDevices[index]; | |
| 152 } | |
| 153 | |
| 154 /** | |
| 155 * Handles key events from the gamepad devices. | |
| 156 * @return True if the event has been consumed. | |
| 157 */ | |
| 158 public static boolean dispatchKeyEvent(KeyEvent event) { | |
| 159 if (!isGamepadEvent(event)) return false; | |
| 160 return sGamepadList.updateForEvent(event); | |
| 161 } | |
| 162 | |
| 163 private static boolean updateForEvent(KeyEvent event) { | |
|
Ted C
2014/04/04 18:52:18
Based on the calling site, I don't think these sho
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Keeping non-
| |
| 164 synchronized (sGamepadList.mLock) { | |
| 165 if (!sGamepadList.mIsGamepadAccessed) return false; | |
| 166 GamepadDevice gamepad = sGamepadList.getGamepadForEvent(event); | |
| 167 if (gamepad == null) return false; | |
| 168 return gamepad.updateForEvent(event); | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 /** | |
| 173 * Handles motion events from the gamepad devices. | |
| 174 * @return True if the event has been consumed. | |
| 175 */ | |
| 176 public static boolean onGenericMotionEvent(MotionEvent event) { | |
| 177 if (!isGamepadEvent(event)) return false; | |
| 178 return sGamepadList.updateForEvent(event); | |
| 179 } | |
| 180 | |
| 181 private static boolean updateForEvent(MotionEvent event) { | |
| 182 synchronized (sGamepadList.mLock) { | |
| 183 if (!sGamepadList.mIsGamepadAccessed) return false; | |
| 184 GamepadDevice gamepad = sGamepadList.getGamepadForEvent(event); | |
| 185 if (gamepad == null) return false; | |
| 186 return gamepad.updateForEvent(event); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 private int getNextAvailableIndex() { | |
| 191 // When multiple gamepads are connected to a user agent, indices must be assigned on a | |
| 192 // first-come first-serve basis, starting at zero. If a gamepad is disco nnected, previously | |
| 193 // assigned indices must not be reassigned to gamepads that continue to be connected. | |
| 194 // However, if a gamepad is disconnected, and subsequently the same or a different | |
| 195 // gamepad is then connected, index entries must be reused. | |
| 196 | |
| 197 for (int i = 0; i < MAX_GAMEPADS; ++i) { | |
| 198 if (getDevice(i) == null) { | |
| 199 return i; | |
| 200 } | |
| 201 } | |
| 202 // Reached maximum gamepads limit. | |
| 203 return -1; | |
| 204 } | |
| 205 | |
| 206 private boolean registerGamepad(InputDevice inputDevice) { | |
| 207 int index = getNextAvailableIndex(); | |
| 208 if (index == -1) { | |
| 209 return false; // invalid index | |
| 210 } | |
| 211 | |
| 212 GamepadDevice gamepad = new GamepadDevice(index, inputDevice); | |
| 213 mGamepadDevices[index] = gamepad; | |
| 214 return true; | |
| 215 } | |
| 216 | |
| 217 private void unregisterGamepad(int deviceId) { | |
| 218 GamepadDevice gamepadDevice = getDeviceById(deviceId); | |
| 219 if (gamepadDevice == null) return; // Not a registered device. | |
| 220 int index = gamepadDevice.getIndex(); | |
| 221 mGamepadDevices[index] = null; | |
| 222 } | |
| 223 | |
| 224 private static boolean isGamepadDevice(InputDevice inputDevice) { | |
| 225 return ((inputDevice.getSources() & InputDevice.SOURCE_JOYSTICK) == | |
| 226 InputDevice.SOURCE_JOYSTICK); | |
|
Ted C
2014/04/04 18:52:18
should be indented 8
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Done.
| |
| 227 } | |
| 228 | |
| 229 private GamepadDevice getGamepadForEvent(InputEvent event) { | |
| 230 int deviceId = event.getDeviceId(); | |
| 231 GamepadDevice gamepad = getDeviceById(deviceId); | |
| 232 return gamepad; | |
| 233 } | |
| 234 | |
| 235 /** | |
| 236 * @return True if the motion event corresponds to a gamepad event. | |
| 237 */ | |
| 238 public static boolean isGamepadEvent(MotionEvent event) { | |
| 239 | |
|
Ted C
2014/04/04 18:52:18
remove blank line
SaurabhK
2014/04/11 14:41:42
On 2014/04/04 18:52:18, Ted C wrote:
Done.
| |
| 240 return ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice .SOURCE_JOYSTICK); | |
| 241 } | |
| 242 | |
| 243 /** | |
| 244 * @return True if event's keycode corresponds to a gamepad key. | |
| 245 * Specific handling for dpad keys is required because | |
| 246 * KeyEvent.isGamepadButton doesn't consider dpad keys. | |
| 247 */ | |
| 248 public static boolean isGamepadEvent(KeyEvent event) { | |
| 249 int keyCode = event.getKeyCode(); | |
| 250 switch (keyCode) { | |
| 251 case KeyEvent.KEYCODE_DPAD_UP: | |
| 252 case KeyEvent.KEYCODE_DPAD_DOWN: | |
| 253 case KeyEvent.KEYCODE_DPAD_LEFT: | |
| 254 case KeyEvent.KEYCODE_DPAD_RIGHT: | |
| 255 return true; | |
| 256 default: | |
| 257 return KeyEvent.isGamepadButton(keyCode); | |
| 258 } | |
| 259 } | |
| 260 | |
| 261 @CalledByNative | |
| 262 static void getGamepadData(long gamepads) { | |
| 263 assert sGamepadList != null; | |
| 264 sGamepadList.grabGamepadData(gamepads); | |
| 265 } | |
| 266 | |
| 267 private void grabGamepadData(long gamepads) { | |
| 268 synchronized (mLock) { | |
| 269 for (int i = 0; i < MAX_GAMEPADS; i++) { | |
| 270 final GamepadDevice device = getDevice(i); | |
| 271 if (device != null) { | |
| 272 device.mapButtonsAndAxes(); | |
| 273 nativeSetGamepadData(gamepads, i, device.getMapping(), true, | |
| 274 device.getName(), device.getTimestamp() , device.getAxes(), | |
| 275 device.getButtons()); | |
| 276 } | |
| 277 else | |
| 278 nativeSetGamepadData(gamepads, i, null, false, null, 0, null , null); | |
| 279 } | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 @CalledByNative | |
| 284 static void notifyForGamepadsAccess(boolean isAccessPaused) { | |
| 285 assert sGamepadList != null; | |
| 286 sGamepadList.isGamepadAccessed(!isAccessPaused); | |
| 287 } | |
| 288 | |
| 289 private void isGamepadAccessed(boolean isGamepadAccessed) { | |
| 290 synchronized (mLock) { | |
| 291 mIsGamepadAccessed = isGamepadAccessed; | |
| 292 if (isGamepadAccessed) { | |
| 293 for (int i = 0; i < MAX_GAMEPADS; i++) { | |
| 294 GamepadDevice gamepadDevice = getDevice(i); | |
| 295 if (gamepadDevice == null) continue; | |
| 296 gamepadDevice.clearData(); | |
| 297 } | |
| 298 } | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 private native void nativeSetGamepadData(long gamepads, | |
| 303 int index, | |
| 304 String mapping, | |
| 305 boolean connected, | |
| 306 String devicename, | |
| 307 long timestamp, | |
| 308 float[] axes, | |
| 309 float[] buttons); | |
| 310 | |
| 311 } | |
| OLD | NEW |