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

Unified Diff: content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java

Issue 165483003: Gamepad API for Android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: incorporated comments 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 side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java b/content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0f344067013163f5a4fdf41d9af8d5854ba3170
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java
@@ -0,0 +1,198 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import android.util.SparseArray;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import org.chromium.base.JNINamespace;
+import org.chromium.content.browser.input.gamepad_mapping.CanonicalAxisIndex;
+import org.chromium.content.browser.input.gamepad_mapping.CanonicalButtonIndex;
+
+/**
+ * Device specific input data converter for Gamepad API.
+ * Implemented per device by subclasses.
+ */
+@JNINamespace("content")
+abstract class GamepadDataMapper {
+ protected static final String PS3_SIXAXIS_DEVICE_NAME = "Sony PLAYSTATION(R)3 Controller";
+
+ public abstract WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> buttons);
Ted C 2014/03/07 20:18:09 per my comment about object creation in the other
kbalazs 2014/03/12 00:17:36 Done, I hold the object in the mapper now.
+
+ // Factory method.
+ public static GamepadDataMapper createDataMapper(String deviceName) {
+ if (deviceName.equals(PS3_SIXAXIS_DEVICE_NAME))
+ return new PS3SixAxisGamepadDataMapper();
+
+ return new GenericGamepadDataMapper(deviceName);
+ }
+
+ protected static float axisValue(Float f) { return f == null ? 0 : f.floatValue(); }
+ protected static float buttonValue(Boolean b) { return (b == null || !b) ? 0 : 1; }
+
+ protected static WebGamepadData createWebGamepadData() {
+ WebGamepadData data = new WebGamepadData();
+ data.axes = new float[CanonicalAxisIndex.NUM_CANONICAL_AXES];
+ data.buttons = new float[CanonicalButtonIndex.NUM_CANONICAL_BUTTONS];
+ return data;
+ }
+
+ protected static void mapCommonXYAxes(WebGamepadData data, SparseArray<Float> axes) {
+ Float x = (Float) axes.get(MotionEvent.AXIS_X);
Ted C 2014/03/07 20:18:09 get on a typed SparseArray should mean that you do
kbalazs 2014/03/07 22:40:22 Right, but unfortunately there is no such thing as
Ted C 2014/03/08 01:06:00 My previous comment was that calling .get() on a S
+ Float y = (Float) axes.get(MotionEvent.AXIS_Y);
+ data.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_X] = axisValue(x);
+ data.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_Y] = axisValue(y);
+ }
+
+ protected static void mapCommonTriggerAxes(WebGamepadData data, SparseArray<Float> axes) {
+ Float lTrigger = (Float) axes.get(MotionEvent.AXIS_LTRIGGER);
+ Float rTrigger = (Float) axes.get(MotionEvent.AXIS_RTRIGGER);
+ data.buttons[CanonicalButtonIndex.BUTTON_LEFT_SHOULDER] = axisValue(lTrigger);
+ data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_SHOULDER] = axisValue(rTrigger);
+ }
+
+ protected static void mapCommonTriggerButtons(
+ WebGamepadData data, SparseArray<Boolean> buttons) {
+ Boolean l1 = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_L1);
+ Boolean r1 = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_R1);
+ data.buttons[CanonicalButtonIndex.BUTTON_LEFT_TRIGGER] = buttonValue(l1);
+ data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_TRIGGER] = buttonValue(r1);
+ }
+
+ protected static void mapCommonThumbstickButtons(
+ WebGamepadData data, SparseArray<Boolean> buttons) {
+ Boolean thumbL = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_THUMBL);
+ Boolean thumbR = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_THUMBR);
+ data.buttons[CanonicalButtonIndex.BUTTON_LEFT_THUMBSTICK] = buttonValue(thumbL);
+ data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_THUMBSTICK] = buttonValue(thumbR);
+ }
+
+ protected static void mapCommonStartSelectButtons(
+ WebGamepadData data, SparseArray<Boolean> buttons) {
+ Boolean select = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_SELECT);
+ Boolean start = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_START);
+ data.buttons[CanonicalButtonIndex.BUTTON_BACK_SELECT] = buttonValue(select);
+ data.buttons[CanonicalButtonIndex.BUTTON_START] = buttonValue(start);
+ }
+
+ protected static void mapCommonDpadButtons(
+ WebGamepadData data, SparseArray<Boolean> buttons) {
+ Boolean dpadDown = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_DOWN);
+ Boolean dpadUp = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_UP);
+ Boolean dpadLeft = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_LEFT);
+ Boolean dpadRight = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_RIGHT);
+ data.buttons[CanonicalButtonIndex.BUTTON_DPAD_DOWN] = buttonValue(dpadDown);
+ data.buttons[CanonicalButtonIndex.BUTTON_DPAD_UP] = buttonValue(dpadUp);
+ data.buttons[CanonicalButtonIndex.BUTTON_DPAD_LEFT] = buttonValue(dpadLeft);
+ data.buttons[CanonicalButtonIndex.BUTTON_DPAD_RIGHT] = buttonValue(dpadRight);
+ }
+
+ protected static void mapCommonXYABButtons(
+ WebGamepadData data, SparseArray<Boolean> buttons) {
+ Boolean bA = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_A);
+ Boolean bB = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_B);
+ Boolean bX = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_X);
+ Boolean bY = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_Y);
+ data.buttons[CanonicalButtonIndex.BUTTON_PRIMARY] = buttonValue(bA);
+ data.buttons[CanonicalButtonIndex.BUTTON_SECONDARY] = buttonValue(bB);
+ data.buttons[CanonicalButtonIndex.BUTTON_TERTIARY] = buttonValue(bX);
+ data.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY] = buttonValue(bY);
+ }
+}
+
+// This is a last resort if we find a device that we don't know about.
+// The Android API is general enough that this can be better than nothing
+// but we should not really rely on this.
+class GenericGamepadDataMapper extends GamepadDataMapper {
+ private final String mDeviceName;
+
+ GenericGamepadDataMapper(String deviceName) {
+ mDeviceName = deviceName;
+ }
+
+ // Find something for right stick x and y. If there is even more axes, map them to
+ // non-canonical positions.
+ private static void mapRightAndExtraSticks(WebGamepadData data, SparseArray<Float> axes) {
+ int position = CanonicalAxisIndex.AXIS_RIGHT_STICK_X;
+ // position + 1 is AXIS_RIGHT_STICK_Y.
+ Float x = (Float) axes.get(MotionEvent.AXIS_RX);
+ Float y = (Float) axes.get(MotionEvent.AXIS_RY);
+ if (x != null || y != null) {
+ data.axes[position++] = axisValue(x);
+ data.axes[position++] = axisValue(y);
+ }
+ x = (Float) axes.get(MotionEvent.AXIS_Z);
+ y = (Float) axes.get(MotionEvent.AXIS_RZ);
+ if (x != null || y != null) {
+ data.axes[position++] = axisValue(x);
+ data.axes[position++] = axisValue(y);
+ }
+ x = (Float) axes.get(MotionEvent.AXIS_HAT_X);
+ y = (Float) axes.get(MotionEvent.AXIS_HAT_Y);
+ if (x != null || y != null) {
+ data.axes[position++] = axisValue(x);
+ data.axes[position++] = axisValue(y);
+ }
Ted C 2014/03/07 20:18:09 This doesn't verify axes size is large enough. Mi
kbalazs 2014/03/07 22:40:22 Right, I overlooked it.
kbalazs 2014/03/12 00:17:36 Done.
+ }
+
+ public WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> buttons) {
+ WebGamepadData data = createWebGamepadData();
+ data.id = mDeviceName + " (STANDARD_GAMEPAD)";
+ data.mapping = "standard";
+ mapCommonXYAxes(data, axes);
+ mapRightAndExtraSticks(data, axes);
+ mapCommonTriggerAxes(data, axes);
+ mapCommonXYABButtons(data, buttons);
+ mapCommonTriggerButtons(data, buttons);
+ mapCommonThumbstickButtons(data, buttons);
+ mapCommonStartSelectButtons(data, buttons);
+ mapCommonDpadButtons(data, buttons);
+
+ // TODO(b.kelemen): meta is missing.
+
+ return data;
+ }
+}
+
+class PS3SixAxisGamepadDataMapper extends GamepadDataMapper {
+ public WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> buttons) {
+ WebGamepadData data = createWebGamepadData();
+ data.id = PS3_SIXAXIS_DEVICE_NAME + " (STANDARD_GAMEPAD)";
Ted C 2014/03/07 20:18:09 I would make " (STANDARD_GAMEPAD)" and "standard"
kbalazs 2014/03/12 00:17:36 Done.
+ data.mapping = "standard";
+
+ mapCommonXYAxes(data, axes);
+
+ Float z = (Float) axes.get(MotionEvent.AXIS_Z);
+ Float rz = (Float) axes.get(MotionEvent.AXIS_RZ);
+ data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_X] = axisValue(z);
+ data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_Y] = axisValue(rz);
+
+ mapCommonTriggerAxes(data, axes);
+
+ Boolean bA = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_A);
+ Boolean bB = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_B);
+ Boolean bX = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_X);
+ Boolean bY = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_Y);
+ data.buttons[CanonicalButtonIndex.BUTTON_PRIMARY] = buttonValue(bX);
+ data.buttons[CanonicalButtonIndex.BUTTON_SECONDARY] = buttonValue(bY);
+ data.buttons[CanonicalButtonIndex.BUTTON_TERTIARY] = buttonValue(bA);
+ data.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY] = buttonValue(bB);
+
+ mapCommonTriggerButtons(data, buttons);
+ mapCommonThumbstickButtons(data, buttons);
+ mapCommonStartSelectButtons(data, buttons);
+ mapCommonDpadButtons(data, buttons);
+
+ // TODO(b.kelemen): PS button is missing. Looks like it is swallowed by Android
+ // but probably there is a way to configure otherwise and in this case we should
+ // handle it.
+
+ return data;
+ }
+}
+
+// TODO(b.kelemen): add more implementations. It would be nice to support at least those that are
+// supported on Linux.

Powered by Google App Engine
This is Rietveld 408576698