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

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: Created 6 years, 10 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
18 /*
19 * Class to manage connected gamepad devices list.
20 */
21 @JNINamespace("content")
22 class GamepadList implements InputDeviceListener {
23 private static final int MAX_GAMEPADS = 4;
24 private GamepadDevice[] mGamepadDevices = new GamepadDevice[MAX_GAMEPADS];
25 protected boolean mHaveDevicesBeenInteractedWith = false;
26 private boolean IS_GAMEPAD_ACCESSED = false;
kbalazs 2014/02/20 00:48:24 Shouldn't be named with initials since it's not a
SaurabhK 2014/02/26 14:14:26 On 2014/02/20 00:48:24, kbalazs wrote: Done.
27 private InputManager inputManager;
xwang 2014/02/25 10:26:58 inputManager -> mInputManager?
SaurabhK 2014/02/26 14:14:26 On 2014/02/25 10:26:58, xwang wrote: Done.
28 // Native pointer to C++ GamepadReader object which will be set by CreateJav aObject().
29 private long mNativeGamepadReader = 0;
30
31 private GamepadList(Context context) {
32
33 inputManager = (InputManager) context.getSystemService(Context.INPUT_SE RVICE);
34 // Get list of all the attached input devices.
35 int[] deviceIds = inputManager.getInputDeviceIds();
36
37 for (int i = 0; i < deviceIds.length; i++) {
38 InputDevice inputDevice = InputDevice.getDevice(deviceIds[i]);
39 // Check for gamepad device
40 if (isGamepadDevice(inputDevice)) {
41 // Register a new gamepad device.
42 registerGamepad(inputDevice);
43 }
44 }
45 // Register an input device listener.
46 inputManager.registerInputDeviceListener(this, null);
47 }
48
49 private static GamepadList gamepadList = null;
xwang 2014/02/25 10:26:58 gamepadList -> sGamepadList
SaurabhK 2014/02/26 14:14:26 On 2014/02/25 10:26:58, xwang wrote: Done.
50
51 // Override InputDeviceListener methods
52 @Override
53 public void onInputDeviceChanged(int deviceId) {
54 }
55
56 @Override
57 public void onInputDeviceRemoved(int deviceId) {
58 unregisterGamepad(deviceId);
59 }
60
61 @Override
62 public void onInputDeviceAdded(int deviceId) {
63 InputDevice inputDevice = InputDevice.getDevice(deviceId);
64 if (isGamepadDevice(inputDevice))
65 registerGamepad(inputDevice);
66 }
67
68 public static GamepadList createInstance(Context context) {
69 if (gamepadList != null) {
70 return gamepadList;
71 } else {
72 gamepadList = new GamepadList(context);
73 return gamepadList;
74 }
75 }
76
77 private boolean haveDevicesBeenInteractedWith() { return mHaveDevicesBeenInt eractedWith; }
xwang 2014/02/25 10:26:58 Is it necessary to add a private function to acces
SaurabhK 2014/02/26 14:14:26 On 2014/02/25 10:26:58, xwang wrote: Removed it.
78
79 private int getDeviceCount() {
80 int count = 0;
81 for (int i = 0; i < getCount(); ++i) {
82 if (getDevice(i) != null) {
83 count++;
84 }
85 }
86 return count;
87 }
88
89 private String getDeviceName(int index) {
90 return getDevice(index).getName();
91 }
92
93 private long getDeviceTimestamp(int index) {
94 return getDevice(index).getTimestamp();
95 }
96
97 private float[] getDeviceAxes(int index) {
98 return getDevice(index).getAxes();
99 }
100
101 private float[] getDeviceButtons(int index) {
102 return getDevice(index).getButtons();
103 }
104
105 private boolean isDeviceConnected(int index) {
106 if (index < MAX_GAMEPADS && getDevice(index) != null) {
107 return true;
108 }
109 return false;
110 }
111
112 private boolean isKnownGamepadLayout(int index) {
113 return getDevice(index).isKnownGamepadLayout();
114 }
115
116 public GamepadDevice getDeviceById(int deviceId) {
117 for (int i = 0; i < getCount(); ++i) {
118 GamepadDevice gamepad = mGamepadDevices[i];
119 if (gamepad != null && gamepad.getId() == deviceId) {
120 return gamepad;
121 }
122 }
123 return null;
124 }
125
126 public GamepadDevice getDevice(int index) {
127 // Maximum 4 Gamepads can be connected at a time starting at index zero.
128 assert index >= 0 && index <= getCount() - 1;
129 return mGamepadDevices[index];
130 }
131
132 public int getCount() {
kbalazs 2014/02/20 00:48:24 This doesn't look very useful to me, I would just
SaurabhK 2014/02/26 14:14:26 On 2014/02/20 00:48:24, kbalazs wrote: Done.
133 return MAX_GAMEPADS;
134 }
135
136 public boolean updateForEvent(KeyEvent event) {
137 GamepadDevice gamepad = getGamepadForEvent(event);
138 if (gamepad != null) {
139 mHaveDevicesBeenInteractedWith = true;
kbalazs 2014/02/20 00:48:24 I think it's not strictly necessary to maintain th
140 return gamepad.updateForEvent(event);
141 }
142 return false;
143 }
144
145 public boolean updateForEvent(MotionEvent event) {
146 GamepadDevice gamepad = getGamepadForEvent(event);
147 if (gamepad != null) {
148 mHaveDevicesBeenInteractedWith = true;
149 return gamepad.updateForEvent(event);
150 }
151 return false;
152 }
153
154 public void onPause() {
155 inputManager.unregisterInputDeviceListener(this);
156 }
157
158 public void onResume() {
159 // Re-initialize gamepad list.
160 // Check if any registered gamepad is disconnected when webview was in p ause state.
kbalazs 2014/02/20 00:48:24 Can you word it more generally? This feature is no
SaurabhK 2014/02/26 14:14:26 On 2014/02/20 00:48:24, kbalazs wrote: Removing o
161 for (int i = 0; i < getCount(); ++i) {
kbalazs 2014/02/20 00:48:24 Isn't it enough to null out the array and enumerat
162 if (mGamepadDevices[i] != null) {
163 InputDevice device = InputDevice.getDevice(mGamepadDevices[i].ge tId());
164 if (device == null) {
165 // Remove disconnected gamepad.
166 mGamepadDevices[i] = null;
167 }
168 }
169 }
170 // Check if any new gamepad is connected when webview was in pause state .
171 int[] deviceIds = inputManager.getInputDeviceIds();
172 for (int i = 0; i < deviceIds.length; ++i) {
173 InputDevice device = InputDevice.getDevice(deviceIds[i]);
174 if (isGamepadDevice(device)) {
175 GamepadDevice gamepad = getDeviceById(deviceIds[i]);
176 if (gamepad == null) {
177 // Found unregistered gamepad, could be a new device connect ed when
178 // webview was in puase state or disconnected and re-connect ed same device.
179 registerGamepad(device);
180 }
181 }
182 }
183 inputManager.registerInputDeviceListener(this, null);
184 }
185
186 protected int getNextAvailableIndex() {
187 // When multiple gamepads are connected to a user agent, indices must be assigned on a
188 // first-come first-serve basis, starting at zero. If a gamepad is disco nnected, previously
189 // assigned indices must not be reassigned to gamepads that continue to be connected.
190 // However, if a gamepad is disconnected, and subsequently the same or a different
191 // gamepad is then connected, index entries must be reused.
192
193 for (int i = 0; i < getCount(); ++i) {
194 if (getDevice(i) == null) {
195 return i;
196 }
197 }
198 // Reached maximum gamepads limit.
199 return -1;
200 }
201
202 protected boolean registerGamepad(InputDevice inputDevice) {
203 int index = getNextAvailableIndex();
204 if (index == -1) {
205 return false; // invalid index
206 }
207
208 GamepadDevice gamepad = new GamepadDevice(index, inputDevice);
209 mGamepadDevices[index] = gamepad;
210 return true;
211 }
212
213 protected void unregisterGamepad(int deviceId) {
214 GamepadDevice gamepadDevice = getDeviceById(deviceId);
215 if (gamepadDevice == null) {
216 return; // Not a registered device.
217 }
218 int index = gamepadDevice.getIndex();
219 mGamepadDevices[index] = null;
220 }
221
222 private boolean isGamepadDevice(InputDevice inputDevice) {
223 int sources = inputDevice.getSources();
224 if ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JO YSTICK ) {
kbalazs 2014/02/20 00:48:24 Shouln't it be '(sources & InputDevice.SOURCE_JOYS
225 //Found gamepad device
226 return true;
227 }
228 return false;
229 }
230
231 private GamepadDevice getGamepadForEvent(InputEvent event) {
232 int deviceId = event.getDeviceId();
233 GamepadDevice gamepad = getDeviceById(deviceId);
234 return gamepad;
235 }
236
237 public boolean isGamepadAccessed() {
238 return IS_GAMEPAD_ACCESSED;
239 }
240
241 public boolean isGamepadEvent(MotionEvent event) {
242 if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOU RCE_JOYSTICK) {
kbalazs 2014/02/20 00:48:24 Ditto about the condition.
243 return true;
244 }
245 return false;
246 }
247
248 // Returns true if event's keycode corresponds to a gamepad key.
249 // Specific handling for dpad keys is required because
250 // KeyEvent.isGamepadButton doesn't consider dpad keys.
251 public boolean isGamepadEvent(KeyEvent event) {
252 int keyCode = event.getKeyCode();
253 switch (keyCode) {
254 case KeyEvent.KEYCODE_DPAD_UP:
255 case KeyEvent.KEYCODE_DPAD_DOWN:
256 case KeyEvent.KEYCODE_DPAD_LEFT:
257 case KeyEvent.KEYCODE_DPAD_RIGHT:
258 return true;
259 default:
260 return KeyEvent.isGamepadButton(keyCode);
261 }
262 }
263
264 @CalledByNative
265 private void getGamepadData() {
266 int devicecount = getDeviceCount();
267 if (devicecount == 0 || !haveDevicesBeenInteractedWith())
268 nativeUpdateDeviceCount(mNativeGamepadReader, 0);
269 else
270 nativeUpdateDeviceCount(mNativeGamepadReader, devicecount);
271 for (int i = 0; i < MAX_GAMEPADS; i++) {
272 if (isDeviceConnected(i))
273 nativeSetGamepadData(mNativeGamepadReader, i, true, getDevic eName(i),
274 getDeviceTimestamp(i), getDeviceAxes(i) ,
275 getDeviceButtons(i));
276 else
277 nativeSetGamepadData(mNativeGamepadReader, i, false, null, 0 , null, null);
278 }
279 }
280
281 @CalledByNative
282 public static GamepadList getInstance(long nativeGamepadReader) {
283 if (gamepadList != null) {
284 gamepadList.mNativeGamepadReader = nativeGamepadReader;
285 return gamepadList;
286 } else {
287 return null;
288 }
289 }
290
291 @CalledByNative
292 private void notifyForGamepadsAccess(boolean isaccesspaused) {
293 IS_GAMEPAD_ACCESSED = !isaccesspaused;
294 }
295
296 private native void nativeSetGamepadData(long nativeGamepadsReader,
297 int index,
298 boolean connected,
299 String devicename,
300 long timestamp,
301 float[] axes,
302 float[] buttons);
303
304 private native void nativeUpdateDeviceCount(long nativeGamepadsReader, int d evicecount);
305
306 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698