1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_
6 #define CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_
11 #include "base/callback_forward.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/shared_memory.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/synchronization/lock.h"
17 #include "base/system_monitor/system_monitor.h"
18 #include "content/common/content_export.h"
19 #include "third_party/WebKit/public/platform/WebGamepads.h"
22 class SingleThreadTaskRunner
;
28 class GamepadDataFetcher
;
29 struct GamepadHardwareBuffer
;
31 class CONTENT_EXPORT GamepadProvider
:
32 public base::SystemMonitor::DevicesChangedObserver
{
36 // Manually specifies the data fetcher. Used for testing.
37 explicit GamepadProvider(scoped_ptr
<GamepadDataFetcher
> fetcher
);
39 ~GamepadProvider() override
;
41 // Returns the shared memory handle of the gamepad data duplicated into the
43 base::SharedMemoryHandle
GetSharedMemoryHandleForProcess(
44 base::ProcessHandle renderer_process
);
46 void GetCurrentGamepadData(blink::WebGamepads
* data
);
48 // Pause and resume the background polling thread. Can be called from any
53 // Registers the given closure for calling when the user has interacted with
54 // the device. This callback will only be issued once.
55 void RegisterForUserGesture(const base::Closure
& closure
);
57 // base::SystemMonitor::DevicesChangedObserver implementation.
58 void OnDevicesChanged(base::SystemMonitor::DeviceType type
) override
;
61 void Initialize(scoped_ptr
<GamepadDataFetcher
> fetcher
);
63 // Method for setting up the platform-specific data fetcher. Takes ownership
65 void DoInitializePollingThread(scoped_ptr
<GamepadDataFetcher
> fetcher
);
67 // Method for sending pause hints to the low-level data fetcher. Runs on
69 void SendPauseHint(bool paused
);
71 // Method for polling a GamepadDataFetcher. Runs on the polling_thread_.
73 void ScheduleDoPoll();
75 void OnGamepadConnectionChange(bool connected
,
77 const blink::WebGamepad
& pad
);
78 void DispatchGamepadConnectionChange(bool connected
,
80 const blink::WebGamepad
& pad
);
82 GamepadHardwareBuffer
* SharedMemoryAsHardwareBuffer();
84 // Checks the gamepad state to see if the user has interacted with it.
85 void CheckForUserGesture();
87 enum { kDesiredSamplingIntervalMs
= 16 };
89 // Keeps track of when the background thread is paused. Access to is_paused_
90 // must be guarded by is_paused_lock_.
91 base::Lock is_paused_lock_
;
94 // Keep track of when a polling task is schedlued, so as to prevent us from
95 // accidentally scheduling more than one at any time, when rapidly toggling
97 bool have_scheduled_do_poll_
;
99 // Lists all observers registered for user gestures, and the thread which
100 // to issue the callbacks on. Since we always issue the callback on the
101 // thread which the registration happened, and this class lives on the I/O
102 // thread, the message loop proxies will normally just be the I/O thread.
103 // However, this will be the main thread for unit testing.
104 base::Lock user_gesture_lock_
;
105 struct ClosureAndThread
{
106 ClosureAndThread(const base::Closure
& c
,
107 const scoped_refptr
<base::SingleThreadTaskRunner
>& m
);
110 base::Closure closure
;
111 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
;
113 typedef std::vector
<ClosureAndThread
> UserGestureObserverVector
;
114 UserGestureObserverVector user_gesture_observers_
;
116 // Updated based on notification from SystemMonitor when the system devices
117 // have been updated, and this notification is passed on to the data fetcher
118 // to enable it to avoid redundant (and possibly expensive) is-connected
119 // tests. Access to devices_changed_ must be guarded by
120 // devices_changed_lock_.
121 base::Lock devices_changed_lock_
;
122 bool devices_changed_
;
124 bool ever_had_user_gesture_
;
132 bool Match(const blink::WebGamepad
& pad
) const;
133 void SetPad(const blink::WebGamepad
& pad
);
134 void SetDisconnected();
135 void AsWebGamepad(blink::WebGamepad
* pad
);
137 bool connected() const { return connected_
; }
141 unsigned axes_length_
;
142 unsigned buttons_length_
;
143 blink::WebUChar id_
[blink::WebGamepad::idLengthCap
];
144 blink::WebUChar mapping_
[blink::WebGamepad::mappingLengthCap
];
147 // Used to detect connections and disconnections.
148 scoped_ptr
<PadState
[]> pad_states_
;
150 // Only used on the polling thread.
151 scoped_ptr
<GamepadDataFetcher
> data_fetcher_
;
153 base::Lock shared_memory_lock_
;
154 base::SharedMemory gamepad_shared_memory_
;
156 // Polling is done on this background thread.
157 scoped_ptr
<base::Thread
> polling_thread_
;
159 static GamepadProvider
* instance_
;
161 DISALLOW_COPY_AND_ASSIGN(GamepadProvider
);
164 } // namespace content
166 #endif // CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_