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

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

Issue 284413005: Revert of Gamepad API support for chrome on android (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 6 years, 7 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.input;
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 * It is a Java counterpart of GamepadPlatformDataFetcherAndroid and feeds Gamep ad API with input
23 * data.
24 */
25 @JNINamespace("content")
26 public class GamepadList implements InputDeviceListener {
27 private static final int MAX_GAMEPADS = 4;
28
29 private final Object mLock = new Object();
30
31 private final GamepadDevice[] mGamepadDevices = new GamepadDevice[MAX_GAMEPA DS];
32 private InputManager mInputManager;
33 private int mAttachedToWindowCounter;
34 private boolean mIsGamepadAccessed;
35
36 private GamepadList() {}
37
38 private void initializeDevices() {
39 // Get list of all the attached input devices.
40 int[] deviceIds = mInputManager.getInputDeviceIds();
41 for (int i = 0; i < deviceIds.length; i++) {
42 InputDevice inputDevice = InputDevice.getDevice(deviceIds[i]);
43 // Check for gamepad device
44 if (isGamepadDevice(inputDevice)) {
45 // Register a new gamepad device.
46 registerGamepad(inputDevice);
47 }
48 }
49 }
50
51 /**
52 * Notifies the GamepadList that a {@link ContentView} is attached to a wind ow and it should
53 * prepare itself for gamepad input. It must be called before {@link onGener icMotionEvent} and
54 * {@link dispatchKeyEvent}.
55 */
56 public static void onAttachedToWindow(Context context) {
57 assert ThreadUtils.runningOnUiThread();
58 getInstance().attachedToWindow(context);
59 }
60
61 private void attachedToWindow(Context context) {
62 if (mAttachedToWindowCounter++ == 0) {
63 mInputManager = (InputManager) context.getSystemService(Context.INPU T_SERVICE);
64 synchronized (mLock) {
65 initializeDevices();
66 }
67 // Register an input device listener.
68 mInputManager.registerInputDeviceListener(this, null);
69 }
70 }
71
72 /**
73 * Notifies the GamepadList that a {@link ContentView} is detached from it's window.
74 */
75 public static void onDetachedFromWindow() {
76 assert ThreadUtils.runningOnUiThread();
77 getInstance().detachedFromWindow();
78 }
79
80 private void detachedFromWindow() {
81 if (--mAttachedToWindowCounter == 0) {
82 synchronized (mLock) {
83 for (int i = 0; i < MAX_GAMEPADS; ++i) {
84 mGamepadDevices[i] = null;
85 }
86 }
87 mInputManager.unregisterInputDeviceListener(this);
88 mInputManager = null;
89 }
90 }
91
92 // ------------------------------------------------------------
93
94 // Override InputDeviceListener methods
95 @Override
96 public void onInputDeviceChanged(int deviceId) {
97 }
98
99 @Override
100 public void onInputDeviceRemoved(int deviceId) {
101 synchronized (mLock) {
102 unregisterGamepad(deviceId);
103 }
104 }
105
106 @Override
107 public void onInputDeviceAdded(int deviceId) {
108 InputDevice inputDevice = InputDevice.getDevice(deviceId);
109 if (!isGamepadDevice(inputDevice)) return;
110 synchronized (mLock) {
111 registerGamepad(inputDevice);
112 }
113 }
114
115 // ------------------------------------------------------------
116
117 private static GamepadList getInstance() {
118 return LazyHolder.INSTANCE;
119 }
120
121 private int getDeviceCount() {
122 int count = 0;
123 for (int i = 0; i < MAX_GAMEPADS; i++) {
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++) {
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 getInstance().handleKeyEvent(event);
161 }
162
163 private boolean handleKeyEvent(KeyEvent event) {
164 synchronized (mLock) {
165 if (!mIsGamepadAccessed) return false;
166 GamepadDevice gamepad = getGamepadForEvent(event);
167 if (gamepad == null) return false;
168 return gamepad.handleKeyEvent(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 getInstance().handleMotionEvent(event);
179 }
180
181 private boolean handleMotionEvent(MotionEvent event) {
182 synchronized (mLock) {
183 if (!mIsGamepadAccessed) return false;
184 GamepadDevice gamepad = getGamepadForEvent(event);
185 if (gamepad == null) return false;
186 return gamepad.handleMotionEvent(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) return false; // invalid index
209
210 GamepadDevice gamepad = new GamepadDevice(index, inputDevice);
211 mGamepadDevices[index] = gamepad;
212 return true;
213 }
214
215 private void unregisterGamepad(int deviceId) {
216 GamepadDevice gamepadDevice = getDeviceById(deviceId);
217 if (gamepadDevice == null) return; // Not a registered device.
218 int index = gamepadDevice.getIndex();
219 mGamepadDevices[index] = null;
220 }
221
222 private static boolean isGamepadDevice(InputDevice inputDevice) {
223 return ((inputDevice.getSources() & InputDevice.SOURCE_JOYSTICK) ==
224 InputDevice.SOURCE_JOYSTICK);
225 }
226
227 private GamepadDevice getGamepadForEvent(InputEvent event) {
228 return getDeviceById(event.getDeviceId());
229 }
230
231 /**
232 * @return True if the motion event corresponds to a gamepad event.
233 */
234 public static boolean isGamepadEvent(MotionEvent event) {
235 return ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice .SOURCE_JOYSTICK);
236 }
237
238 /**
239 * @return True if event's keycode corresponds to a gamepad key.
240 */
241 public static boolean isGamepadEvent(KeyEvent event) {
242 int keyCode = event.getKeyCode();
243 switch (keyCode) {
244 // Specific handling for dpad keys is required because
245 // KeyEvent.isGamepadButton doesn't consider dpad keys.
246 case KeyEvent.KEYCODE_DPAD_UP:
247 case KeyEvent.KEYCODE_DPAD_DOWN:
248 case KeyEvent.KEYCODE_DPAD_LEFT:
249 case KeyEvent.KEYCODE_DPAD_RIGHT:
250 return true;
251 default:
252 return KeyEvent.isGamepadButton(keyCode);
253 }
254 }
255
256 @CalledByNative
257 static void updateGamepadData(long webGamepadsPtr) {
258 getInstance().grabGamepadData(webGamepadsPtr);
259 }
260
261 private void grabGamepadData(long webGamepadsPtr) {
262 synchronized (mLock) {
263 for (int i = 0; i < MAX_GAMEPADS; i++) {
264 final GamepadDevice device = getDevice(i);
265 if (device != null) {
266 device.updateButtonsAndAxesMapping();
267 nativeSetGamepadData(webGamepadsPtr, i, device.isStandardGam epad(), true,
268 device.getName(), device.getTimestamp(), device.getA xes(),
269 device.getButtons());
270 } else {
271 nativeSetGamepadData(webGamepadsPtr, i, false, false, null, 0, null, null);
272 }
273 }
274 }
275 }
276
277 @CalledByNative
278 static void notifyForGamepadsAccess(boolean isAccessPaused) {
279 getInstance().setIsGamepadAccessed(!isAccessPaused);
280 }
281
282 private void setIsGamepadAccessed(boolean isGamepadAccessed) {
283 synchronized (mLock) {
284 mIsGamepadAccessed = isGamepadAccessed;
285 if (isGamepadAccessed) {
286 for (int i = 0; i < MAX_GAMEPADS; i++) {
287 GamepadDevice gamepadDevice = getDevice(i);
288 if (gamepadDevice == null) continue;
289 gamepadDevice.clearData();
290 }
291 }
292 }
293 }
294
295 private native void nativeSetGamepadData(long webGamepadsPtr, int index, boo lean mapping,
296 boolean connected, String devicename, long timestamp, float[] axes, float[] buttons);
297
298 private static class LazyHolder {
299 private static final GamepadList INSTANCE = new GamepadList();
300 }
301
302 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698