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

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, 11 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 /*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of NVIDIA CORPORATION nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 package org.chromium.content.browser;
30
31 import android.content.Context;
32 import android.hardware.input.InputManager;
33 import android.hardware.input.InputManager.InputDeviceListener;
34 import android.view.InputDevice;
35 import android.view.InputEvent;
36 import android.view.KeyEvent;
37 import android.view.MotionEvent;
38
39 import org.chromium.base.CalledByNative;
40
41 /*
42 * Class to manage connected gamepad devices list.
43 */
44 class GamepadList implements InputDeviceListener {
45 private static final int MAX_GAMEPADS = 4;
46 private GamepadDevice[] mGamepadDevices = new GamepadDevice[MAX_GAMEPADS];
47 protected boolean mHaveDevicesBeenInteractedWith = false;
48 private boolean IS_GAMEPAD_ACCESSED = false;
49 private InputManager inputManager;
50
51 private GamepadList(Context context) {
52
53 inputManager = (InputManager) context.getSystemService(Context.INPUT_SE RVICE);
54 // Get list of all the attached input devices.
55 int[] deviceIds = inputManager.getInputDeviceIds();
56
57 for (int i = 0; i < deviceIds.length; i++) {
58 InputDevice inputDevice = InputDevice.getDevice(deviceIds[i]);
59 // Check for gamepad device
60 if (isGamepadDevice(inputDevice)) {
61 // Register a new gamepad device.
62 registerGamepad(inputDevice);
63 }
64 }
65 // Register an input device listener.
66 inputManager.registerInputDeviceListener(this, null);
67 }
68
69 private static GamepadList gamepadList = null;
70
71 public boolean haveDevicesBeenInteractedWith() { return mHaveDevicesBeenInte ractedWith; }
72
73 // Override InputDeviceListener methods
74 @Override
75 public void onInputDeviceChanged(int deviceId) {
76 }
77
78 @Override
79 public void onInputDeviceRemoved(int deviceId) {
80 unregisterGamepad(deviceId);
81 }
82
83 @Override
84 public void onInputDeviceAdded(int deviceId) {
85 InputDevice inputDevice = InputDevice.getDevice(deviceId);
86 if (isGamepadDevice(inputDevice))
87 registerGamepad(inputDevice);
88 }
89
90 public static GamepadList createInstance(Context context) {
91 if (gamepadList != null) {
92 return gamepadList;
93 } else {
94 gamepadList = new GamepadList(context);
95 return gamepadList;
96 }
97 }
98
99 @CalledByNative
100 public static GamepadList getInstance() {
101 if (gamepadList != null) {
102 return gamepadList;
103 } else {
104 return null;
105 }
106 }
107
108 @CalledByNative
109 private void notifyForGamepadsAccess(boolean isaccesspaused) {
110 IS_GAMEPAD_ACCESSED = !isaccesspaused;
111 }
112
113 @CalledByNative
114 private GamepadList getGamepadList() {
115 // Gamepads must only appear in the list if they are currently connected to the user agent,
116 // and at least one device has been interacted with by the user. If no d evices have been
117 // interacted with, devices must not appear in the list to avoid a malic ious page from
118 // fingerprinting the user.
119 if (haveDevicesBeenInteractedWith()) {
120 return gamepadList;
121 }
122 else {
123 return null;
124 }
125 }
126
127 @CalledByNative
128 private int getDeviceCount() {
129 int count = 0;
130 for (int i = 0; i < getCount(); ++i) {
131 if (getDevice(i) != null) {
132 count++;
133 }
134 }
135 return count;
136 }
137
138 @CalledByNative
139 private String getDeviceName(int index) {
140 return getDevice(index).getName();
141 }
142
143 @CalledByNative
144 private long getDeviceTimestamp(int index) {
145 return getDevice(index).getTimestamp();
146 }
147
148 @CalledByNative
149 private float[] getDeviceAxes(int index) {
150 return getDevice(index).getAxes();
151 }
152
153 @CalledByNative
154 private float[] getDeviceButtons(int index) {
155 return getDevice(index).getButtons();
156 }
157
158 @CalledByNative
159 private boolean isDeviceConnected(int index) {
160 if (index < MAX_GAMEPADS && getDevice(index) != null) {
161 return true;
162 }
163 return false;
164 }
165
166 @CalledByNative
167 private boolean isKnownGamepadLayout(int index) {
168 return getDevice(index).isKnownGamepadLayout();
169 }
170
171 public GamepadDevice getDeviceById(int deviceId) {
172 for (int i = 0; i < getCount(); ++i) {
173 GamepadDevice gamepad = mGamepadDevices[i];
174 if (gamepad != null && gamepad.getId() == deviceId) {
175 return gamepad;
176 }
177 }
178 return null;
179 }
180
181 public GamepadDevice getDevice(int index) {
182 // Maximum 4 Gamepads can be connected at a time starting at index zero.
183 assert index >= 0 && index <= getCount() - 1;
184 return mGamepadDevices[index];
185 }
186
187 public int getCount() {
188 return MAX_GAMEPADS;
189 }
190
191 public boolean updateForEvent(KeyEvent event) {
192 GamepadDevice gamepad = getGamepadForEvent(event);
193 if (gamepad != null) {
194 mHaveDevicesBeenInteractedWith = true;
195 return gamepad.updateForEvent(event);
196 }
197 return false;
198 }
199
200 public boolean updateForEvent(MotionEvent event) {
201 GamepadDevice gamepad = getGamepadForEvent(event);
202 if (gamepad != null) {
203 mHaveDevicesBeenInteractedWith = true;
204 return gamepad.updateForEvent(event);
205 }
206 return false;
207 }
208
209 public void onPause() {
210 inputManager.unregisterInputDeviceListener(this);
211 }
212
213 public void onResume() {
214 // Re-initialize gamepad list.
215 // Check if any registered gamepad is disconnected when webview was in p ause state.
216 for (int i = 0; i < getCount(); ++i) {
217 if (mGamepadDevices[i] != null) {
218 InputDevice device = InputDevice.getDevice(mGamepadDevices[i].ge tId());
219 if (device == null) {
220 // Remove disconnected gamepad.
221 mGamepadDevices[i] = null;
222 }
223 }
224 }
225 // Check if any new gamepad is connected when webview was in pause state .
226 int[] deviceIds = inputManager.getInputDeviceIds();
227 for (int i = 0; i < deviceIds.length; ++i) {
228 InputDevice device = InputDevice.getDevice(deviceIds[i]);
229 if (isGamepadDevice(device)) {
230 GamepadDevice gamepad = getDeviceById(deviceIds[i]);
231 if (gamepad == null) {
232 // Found unregistered gamepad, could be a new device connect ed when
233 // webview was in puase state or disconnected and re-connect ed same device.
234 registerGamepad(device);
235 }
236 }
237 }
238 inputManager.registerInputDeviceListener(this, null);
239 }
240
241 protected int getNextAvailableIndex() {
242 // When multiple gamepads are connected to a user agent, indices must be assigned on a
243 // first-come first-serve basis, starting at zero. If a gamepad is disco nnected, previously
244 // assigned indices must not be reassigned to gamepads that continue to be connected.
245 // However, if a gamepad is disconnected, and subsequently the same or a different
246 // gamepad is then connected, index entries must be reused.
247
248 for (int i = 0; i < getCount(); ++i) {
249 if (getDevice(i) == null) {
250 return i;
251 }
252 }
253 // Reached maximum gamepads limit.
254 return -1;
255 }
256
257 protected boolean registerGamepad(InputDevice inputDevice) {
258 int index = getNextAvailableIndex();
259 if (index == -1) {
260 return false; // invalid index
261 }
262
263 GamepadDevice gamepad = new GamepadDevice(index, inputDevice);
264 mGamepadDevices[index] = gamepad;
265 return true;
266 }
267
268 protected void unregisterGamepad(int deviceId) {
269 GamepadDevice gamepadDevice = getDeviceById(deviceId);
270 if (gamepadDevice == null) {
271 return; // Not a registered device.
272 }
273 int index = gamepadDevice.getIndex();
274 mGamepadDevices[index] = null;
275 }
276
277 private boolean isGamepadDevice(InputDevice inputDevice) {
278 int sources = inputDevice.getSources();
279 if ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JO YSTICK ) {
280 //Found gamepad device
281 return true;
282 }
283 return false;
284 }
285
286 private GamepadDevice getGamepadForEvent(InputEvent event) {
287 int deviceId = event.getDeviceId();
288 GamepadDevice gamepad = getDeviceById(deviceId);
289 return gamepad;
290 }
291
292 public boolean isGamepadAccessed() {
293 return IS_GAMEPAD_ACCESSED;
294 }
295
296 public boolean isGamepadEvent(MotionEvent event) {
297 if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOU RCE_JOYSTICK) {
298 return true;
299 }
300 return false;
301 }
302
303 // Returns true if event's keycode corresponds to a gamepad key.
304 // Specific handling for dpad keys is required because
305 // KeyEvent.isGamepadButton doesn't consider dpad keys.
306 public boolean isGamepadEvent(KeyEvent event) {
307 int keyCode = event.getKeyCode();
308 switch (keyCode) {
309 case KeyEvent.KEYCODE_DPAD_UP:
310 case KeyEvent.KEYCODE_DPAD_DOWN:
311 case KeyEvent.KEYCODE_DPAD_LEFT:
312 case KeyEvent.KEYCODE_DPAD_RIGHT:
313 return true;
314 default:
315 return KeyEvent.isGamepadButton(keyCode);
316 }
317 }
318
319 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698