Commit ae883853 authored by Matt Reynolds's avatar Matt Reynolds Committed by Commit Bot

[gamepad] Block double-enumerated gamepads on Mac

In macOS 10.15, Game Controller API added support for Xbox Wireless
Controller and Dualshock 4. In Chrome, these devices are already
supported through XboxDataFetcher and GamepadPlatformDataFetcherMac.
When GameControllerDataFetcherMac also enumerates them, a duplicate
gamepad is added to the gamepad list.

To prevent this, GameControllerDataFetcherMac will skip these devices
during enumeration. 10.15 added a new productCategory property to
GCController which allows applications to detect these newly-supported
devices. This CL uses productCategory when available, and compares
the device's vendorName against known values when it is not.

BUG=971801

Change-Id: Ie937f341d1f3c3c1c3a81d6717da2f15d6f6b993
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1773708Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: Matt Reynolds <mattreynolds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#691900}
parent fd004051
......@@ -6,6 +6,7 @@
#include <string.h>
#include "base/mac/mac_util.h"
#include "base/strings/string16.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
......@@ -19,6 +20,46 @@ namespace {
const int kGCControllerPlayerIndexCount = 4;
// Returns true if |controller| should be enumerated by this data fetcher.
bool IsSupported(GCController* controller) {
// We only support the extendedGamepad profile, the basic gamepad profile
// appears to only be for iOS devices.
if (![controller extendedGamepad])
return false;
// In OS X 10.15, Game Controller API added support for Xbox Wireless
// Controller and Dualshock 4. A productCategory property was added to
// GCController to allow applications to detect these new categories of
// devices.
//
// In Chrome for Mac, Xbox Wireless Controller and Dualshock 4 are
// enumerated by XboxDataFetcher and GamepadPlatformDataFetcherMac,
// respectively. If GameControllerDataFetcherMac also enumerates these
// devices, it will add duplicate gamepads to the gamepad list.
//
// On macOS 10.15 or later, use the productCategory property to distinguish
// Xbox One and Dualshock 4 and block them from being enumerated by this
// data fetcher. On 10.14 or earlier, compare the |vendor_name| against
// known values for these devices. Once Chrome no longer supports 10.14, the
// |vendor_name| path may be removed.
if (base::mac::IsAtLeastOS10_15()) {
NSString* product_category =
[controller performSelector:@selector(productCategory)];
if ([product_category isEqualToString:@"Xbox One"])
return false;
if ([product_category isEqualToString:@"DualShock 4"])
return false;
} else {
NSString* vendor_name = [controller vendorName];
if ([vendor_name isEqualToString:@"Xbox Wireless Controller"])
return false;
if ([vendor_name isEqualToString:@"Wireless Controller"])
return false;
}
return true;
}
} // namespace
GameControllerDataFetcherMac::GameControllerDataFetcherMac() {}
......@@ -37,9 +78,7 @@ void GameControllerDataFetcherMac::GetGamepadData(bool) {
bool player_indices[Gamepads::kItemsLengthCap];
std::fill(player_indices, player_indices + Gamepads::kItemsLengthCap, false);
for (GCController* controller in controllers) {
// We only support the extendedGamepad profile, the basic gamepad profile
// appears to only be for iOS devices.
if (![controller extendedGamepad])
if (!IsSupported(controller))
continue;
int player_index = [controller playerIndex];
......@@ -55,9 +94,7 @@ void GameControllerDataFetcherMac::GetGamepadData(bool) {
// In the second pass, assign indices to newly connected gamepads and fetch
// the gamepad state.
for (GCController* controller in controllers) {
auto extended_gamepad = [controller extendedGamepad];
if (!extended_gamepad)
if (!IsSupported(controller))
continue;
int player_index = [controller playerIndex];
......@@ -104,6 +141,7 @@ void GameControllerDataFetcherMac::GetGamepadData(bool) {
pad.timestamp = CurrentTimeInMicroseconds();
auto extended_gamepad = [controller extendedGamepad];
pad.axes[AXIS_INDEX_LEFT_STICK_X] =
[[[extended_gamepad leftThumbstick] xAxis] value];
pad.axes[AXIS_INDEX_LEFT_STICK_Y] =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment