Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/GamepadList.java

Issue 133943002: Gamepad API support for chrome on android (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Uploading forgotten things in previous patch Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698