| Index: content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc | 
| diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc | 
| index f6fd2d4ef393697da51ce936497acf4f748c9162..85d419f65327b842b40df2338efc4be42e46f517 100644 | 
| --- a/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc | 
| +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_linux.cc | 
| @@ -11,8 +11,6 @@ | 
| #include <sys/types.h> | 
| #include <unistd.h> | 
|  | 
| -#include "base/macros.h" | 
| -#include "base/message_loop/message_loop.h" | 
| #include "base/posix/eintr_wrapper.h" | 
| #include "base/strings/string_number_conversions.h" | 
| #include "base/strings/string_util.h" | 
| @@ -70,13 +68,17 @@ using blink::WebGamepad; | 
| using blink::WebGamepads; | 
|  | 
| GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() { | 
| -  for (size_t i = 0; i < arraysize(pad_state_); ++i) { | 
| +  for (size_t i = 0; i < arraysize(device_fd_); ++i) { | 
| device_fd_[i] = -1; | 
| -    pad_state_[i].mapper = 0; | 
| -    pad_state_[i].axis_mask = 0; | 
| -    pad_state_[i].button_mask = 0; | 
| } | 
| +} | 
| + | 
| +GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { | 
| +  for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) | 
| +    CloseFileDescriptorIfValid(device_fd_[i]); | 
| +} | 
|  | 
| +void GamepadPlatformDataFetcherLinux::OnAddedToProvider() { | 
| std::vector<UdevLinux::UdevMonitorFilter> filters; | 
| filters.push_back(UdevLinux::UdevMonitorFilter(kInputSubsystem, NULL)); | 
| udev_.reset( | 
| @@ -87,12 +89,7 @@ GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() { | 
| EnumerateDevices(); | 
| } | 
|  | 
| -GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { | 
| -  for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) | 
| -    CloseFileDescriptorIfValid(device_fd_[i]); | 
| -} | 
| - | 
| -void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) { | 
| +void GamepadPlatformDataFetcherLinux::GetGamepadData(bool) { | 
| TRACE_EVENT0("GAMEPAD", "GetGamepadData"); | 
|  | 
| // Update our internal state. | 
| @@ -101,11 +98,6 @@ void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) { | 
| ReadDeviceData(i); | 
| } | 
| } | 
| - | 
| -  pads->length = WebGamepads::itemsLengthCap; | 
| -  for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { | 
| -    MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]); | 
| -  } | 
| } | 
|  | 
| // Used during enumeration, and monitor notifications. | 
| @@ -114,8 +106,6 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { | 
| std::string node_path; | 
| if (IsGamepad(dev, &index, &node_path))  { | 
| int& device_fd = device_fd_[index]; | 
| -    WebGamepad& pad = pad_state_[index].data; | 
| -    GamepadStandardMappingFunction& mapper = pad_state_[index].mapper; | 
|  | 
| CloseFileDescriptorIfValid(device_fd); | 
|  | 
| @@ -128,17 +118,26 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { | 
| if (!dev) { | 
| // Unable to get device information, don't use this device. | 
| device_fd = -1; | 
| -      pad.connected = false; | 
| return; | 
| } | 
|  | 
| device_fd = HANDLE_EINTR(open(node_path.c_str(), O_RDONLY | O_NONBLOCK)); | 
| if (device_fd < 0) { | 
| // Unable to open device, don't use. | 
| -      pad.connected = false; | 
| return; | 
| } | 
|  | 
| +    PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_LINUX_UDEV, index); | 
| +    if (!state) { | 
| +      // No slot available for device, don't use. | 
| +      CloseFileDescriptorIfValid(device_fd); | 
| +      device_fd = -1; | 
| +      return; | 
| +    } | 
| + | 
| +    WebGamepad& pad = state->data; | 
| +    GamepadStandardMappingFunction& mapper = state->mapper; | 
| + | 
| const char* vendor_id = | 
| device::udev_device_get_sysattr_value(dev, "id/vendor"); | 
| const char* product_id = | 
| @@ -200,9 +199,6 @@ void GamepadPlatformDataFetcherLinux::RefreshDevice(udev_device* dev) { | 
| pad.mapping[0] = 0; | 
| } | 
|  | 
| -    pad_state_[index].axis_mask = 0; | 
| -    pad_state_[index].button_mask = 0; | 
| - | 
| pad.connected = true; | 
| } | 
| } | 
| @@ -242,10 +238,15 @@ void GamepadPlatformDataFetcherLinux::ReadDeviceData(size_t index) { | 
| return; | 
| } | 
|  | 
| -  const int& fd = device_fd_[index]; | 
| -  WebGamepad& pad = pad_state_[index].data; | 
| +  PadState* state = provider()->GetPadState(GAMEPAD_SOURCE_LINUX_UDEV, index); | 
| +  if (!state) | 
| +    return; | 
| + | 
| +  int fd = device_fd_[index]; | 
| DCHECK_GE(fd, 0); | 
|  | 
| +  WebGamepad& pad = state->data; | 
| + | 
| js_event event; | 
| while (HANDLE_EINTR(read(fd, &event, sizeof(struct js_event))) > 0) { | 
| size_t item = event.number; | 
|  |