blob: 199334d9f6061aefab00a0463f68007d5b7aa861 [file] [log] [blame]
// Copyright 2015 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.device.gamepad;
import android.view.KeyEvent;
import android.view.MotionEvent;
import org.chromium.base.test.util.Feature;
import org.chromium.testing.local.LocalRobolectricTestRunner;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import java.util.Arrays;
import java.util.BitSet;
/**
* Verify no regressions in gamepad mappings.
*/
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class GamepadMappingsTest {
private static final float ERROR_TOLERANCE = 0.000001f;
/**
* Set bits indicate that we don't expect the button at mMappedButtons[index] to be mapped.
*/
private BitSet mUnmappedButtons = new BitSet(CanonicalButtonIndex.COUNT);
/**
* Set bits indicate that we don't expect the axis at mMappedAxes[index] to be mapped.
*/
private BitSet mUnmappedAxes = new BitSet(CanonicalAxisIndex.COUNT);
private float[] mMappedButtons = new float[CanonicalButtonIndex.COUNT];
private float[] mMappedAxes = new float[CanonicalAxisIndex.COUNT];
private float[] mRawButtons = new float[GamepadDevice.MAX_RAW_BUTTON_VALUES];
private float[] mRawAxes = new float[GamepadDevice.MAX_RAW_AXIS_VALUES];
@Before
public void setUp() throws Exception {
// By default, we expect every button and axis to be mapped.
mUnmappedButtons.clear();
mUnmappedAxes.clear();
// Start with all the mapped values as unmapped.
Arrays.fill(mMappedButtons, Float.NaN);
Arrays.fill(mMappedAxes, Float.NaN);
// Set each raw value to something unique.
for (int i = 0; i < GamepadDevice.MAX_RAW_AXIS_VALUES; i++) {
mRawAxes[i] = -i - 1.0f;
}
for (int i = 0; i < GamepadDevice.MAX_RAW_BUTTON_VALUES; i++) {
mRawButtons[i] = i + 1.0f;
}
}
@Test
@Feature({"Gamepad"})
public void testShieldGamepadMappings() throws Exception {
GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
GamepadMappings.NVIDIA_SHIELD_DEVICE_NAME_PREFIX);
assertShieldGamepadMappings();
}
@Test
@Feature({"Gamepad"})
public void testXBox360GamepadMappings() throws Exception {
GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
GamepadMappings.MICROSOFT_XBOX_PAD_DEVICE_NAME);
assertShieldGamepadMappings();
}
@Test
@Feature({"Gamepad"})
public void testPS3SixAxisGamepadMappings() throws Exception {
GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
GamepadMappings.PS3_SIXAXIS_DEVICE_NAME);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
assertMappedCommonTriggerButtons();
assertMappedCommonThumbstickButtons();
assertMappedCommonDpadButtons();
assertMappedCommonStartSelectMetaButtons();
assertMappedTriggerAxexToShoulderButtons();
assertMappedXYAxes();
assertMappedZAndRZAxesToRightStick();
assertMapping();
}
@Test
@Feature({"Gamepad"})
public void testSamsungEIGP20GamepadMappings() throws Exception {
GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
GamepadMappings.SAMSUNG_EI_GP20_DEVICE_NAME);
assertMappedCommonXYABButtons();
assertMappedCommonTriggerButtons();
assertMappedCommonThumbstickButtons();
assertMappedCommonStartSelectMetaButtons();
assertMappedHatAxisToDpadButtons();
assertMappedXYAxes();
assertMappedRXAndRYAxesToRightStick();
expectNoShoulderButtons();
assertMapping();
}
@Test
@Feature({"Gamepad"})
public void testAmazonFireGamepadMappings() throws Exception {
GamepadMappings.mapToStandardGamepad(mMappedAxes, mMappedButtons, mRawAxes, mRawButtons,
GamepadMappings.AMAZON_FIRE_DEVICE_NAME);
assertMappedCommonXYABButtons();
assertMappedPedalAxesToBottomShoulder();
assertMappedCommonThumbstickButtons();
assertMappedCommonStartSelectMetaButtons();
assertMappedTriggerButtonsToTopShoulder();
assertMappedHatAxisToDpadButtons();
assertMappedXYAxes();
assertMappedZAndRZAxesToRightStick();
assertMapping();
}
@Test
@Feature({"Gamepad"})
public void testUnknownGamepadMappings() throws Exception {
GamepadMappings.mapToStandardGamepad(
mMappedAxes, mMappedButtons, mRawAxes, mRawButtons, "");
assertMappedCommonXYABButtons();
assertMappedCommonTriggerButtons();
assertMappedCommonThumbstickButtons();
assertMappedCommonStartSelectMetaButtons();
assertMappedTriggerAxexToShoulderButtons();
assertMappedCommonDpadButtons();
assertMappedXYAxes();
assertMappedRXAndRYAxesToRightStick();
assertMapping();
}
/**
* Asserts that the current gamepad mapping being tested matches the shield mappings.
*/
public void assertShieldGamepadMappings() {
assertMappedCommonXYABButtons();
assertMappedTriggerButtonsToTopShoulder();
assertMappedCommonThumbstickButtons();
assertMappedCommonStartSelectMetaButtons();
assertMappedTriggerAxesToBottomShoulder();
assertMappedHatAxisToDpadButtons();
assertMappedXYAxes();
assertMappedZAndRZAxesToRightStick();
assertMapping();
}
public void expectNoShoulderButtons() {
mUnmappedButtons.set(CanonicalButtonIndex.LEFT_SHOULDER);
mUnmappedButtons.set(CanonicalButtonIndex.RIGHT_SHOULDER);
}
public void assertMapping() {
for (int i = 0; i < mMappedAxes.length; i++) {
if (mUnmappedAxes.get(i)) {
Assert.assertTrue(
"An unexpected axis was mapped at index " + i, Float.isNaN(mMappedAxes[i]));
} else {
Assert.assertFalse(
"An axis was not mapped at index " + i, Float.isNaN(mMappedAxes[i]));
}
}
for (int i = 0; i < mMappedButtons.length; i++) {
if (mUnmappedButtons.get(i)) {
Assert.assertTrue("An unexpected button was mapped at index " + i,
Float.isNaN(mMappedButtons[i]));
} else {
Assert.assertFalse(
"A button was not mapped at index " + i, Float.isNaN(mMappedButtons[i]));
}
}
}
private void assertMappedCommonTriggerButtons() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
mRawButtons[KeyEvent.KEYCODE_BUTTON_L1], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
mRawButtons[KeyEvent.KEYCODE_BUTTON_R1], ERROR_TOLERANCE);
}
private void assertMappedCommonDpadButtons() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_DOWN],
mRawButtons[KeyEvent.KEYCODE_DPAD_DOWN], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_UP],
mRawButtons[KeyEvent.KEYCODE_DPAD_UP], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_LEFT],
mRawButtons[KeyEvent.KEYCODE_DPAD_LEFT], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_RIGHT],
mRawButtons[KeyEvent.KEYCODE_DPAD_RIGHT], ERROR_TOLERANCE);
}
private void assertMappedTriggerAxexToShoulderButtons() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER],
mRawAxes[MotionEvent.AXIS_LTRIGGER], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER],
mRawAxes[MotionEvent.AXIS_RTRIGGER], ERROR_TOLERANCE);
}
private void assertMappedTriggerButtonsToTopShoulder() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_SHOULDER],
mRawButtons[KeyEvent.KEYCODE_BUTTON_L1], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER],
mRawButtons[KeyEvent.KEYCODE_BUTTON_R1], ERROR_TOLERANCE);
}
private void assertMappedCommonXYABButtons() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.PRIMARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_A], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.SECONDARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_B], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.TERTIARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_X], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.QUATERNARY],
mRawButtons[KeyEvent.KEYCODE_BUTTON_Y], ERROR_TOLERANCE);
}
private void assertMappedCommonThumbstickButtons() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_THUMBSTICK],
mRawButtons[KeyEvent.KEYCODE_BUTTON_THUMBL], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_THUMBSTICK],
mRawButtons[KeyEvent.KEYCODE_BUTTON_THUMBR], ERROR_TOLERANCE);
}
private void assertMappedCommonStartSelectMetaButtons() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.START],
mRawButtons[KeyEvent.KEYCODE_BUTTON_START], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.BACK_SELECT],
mRawButtons[KeyEvent.KEYCODE_BUTTON_SELECT], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.META],
mRawButtons[KeyEvent.KEYCODE_BUTTON_MODE], ERROR_TOLERANCE);
}
private void assertMappedPedalAxesToBottomShoulder() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
mRawAxes[MotionEvent.AXIS_BRAKE], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
mRawAxes[MotionEvent.AXIS_GAS], ERROR_TOLERANCE);
}
private void assertMappedTriggerAxesToBottomShoulder() {
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.LEFT_TRIGGER],
mRawAxes[MotionEvent.AXIS_LTRIGGER], ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER],
mRawAxes[MotionEvent.AXIS_RTRIGGER], ERROR_TOLERANCE);
}
private void assertMappedHatAxisToDpadButtons() {
float hatX = mRawAxes[MotionEvent.AXIS_HAT_X];
float hatY = mRawAxes[MotionEvent.AXIS_HAT_Y];
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_LEFT],
GamepadMappings.negativeAxisValueAsButton(hatX), ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_RIGHT],
GamepadMappings.positiveAxisValueAsButton(hatX), ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_UP],
GamepadMappings.negativeAxisValueAsButton(hatY), ERROR_TOLERANCE);
Assert.assertEquals(mMappedButtons[CanonicalButtonIndex.DPAD_DOWN],
GamepadMappings.positiveAxisValueAsButton(hatY), ERROR_TOLERANCE);
}
private void assertMappedXYAxes() {
Assert.assertEquals(mMappedAxes[CanonicalAxisIndex.LEFT_STICK_X],
mRawAxes[MotionEvent.AXIS_X], ERROR_TOLERANCE);
Assert.assertEquals(mMappedAxes[CanonicalAxisIndex.LEFT_STICK_Y],
mRawAxes[MotionEvent.AXIS_Y], ERROR_TOLERANCE);
}
private void assertMappedRXAndRYAxesToRightStick() {
Assert.assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_X],
mRawAxes[MotionEvent.AXIS_RX], ERROR_TOLERANCE);
Assert.assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_Y],
mRawAxes[MotionEvent.AXIS_RY], ERROR_TOLERANCE);
}
private void assertMappedZAndRZAxesToRightStick() {
Assert.assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_X],
mRawAxes[MotionEvent.AXIS_Z], ERROR_TOLERANCE);
Assert.assertEquals(mMappedAxes[CanonicalAxisIndex.RIGHT_STICK_Y],
mRawAxes[MotionEvent.AXIS_RZ], ERROR_TOLERANCE);
}
}