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/message_loop/message_loop_proxy.h"
17 #include "base/synchronization/lock.h"
18 #include "base/system_monitor/system_monitor.h"
19 #include "content/common/content_export.h"
20 #include "third_party/WebKit/public/platform/WebGamepads.h"
23 class MessageLoopProxy
;
29 class GamepadDataFetcher
;
30 struct GamepadHardwareBuffer
;
32 class CONTENT_EXPORT GamepadProvider
:
33 public base::SystemMonitor::DevicesChangedObserver
{
37 // Manually specifies the data fetcher. Used for testing.
38 explicit GamepadProvider(scoped_ptr
<GamepadDataFetcher
> fetcher
);
40 virtual ~GamepadProvider();
42 // Returns the shared memory handle of the gamepad data duplicated into the
44 base::SharedMemoryHandle
GetSharedMemoryHandleForProcess(
45 base::ProcessHandle renderer_process
);
47 void GetCurrentGamepadData(blink::WebGamepads
* data
);
49 // Pause and resume the background polling thread. Can be called from any
54 // Registers the given closure for calling when the user has interacted with
55 // the device. This callback will only be issued once.
56 void RegisterForUserGesture(const base::Closure
& closure
);
58 // base::SystemMonitor::DevicesChangedObserver implementation.
59 virtual void OnDevicesChanged(base::SystemMonitor::DeviceType type
) OVERRIDE
;
62 void Initialize(scoped_ptr
<GamepadDataFetcher
> fetcher
);
64 // Method for setting up the platform-specific data fetcher. Takes ownership
66 void DoInitializePollingThread(scoped_ptr
<GamepadDataFetcher
> fetcher
);
68 // Method for sending pause hints to the low-level data fetcher. Runs on
70 void SendPauseHint(bool paused
);
72 // Method for polling a GamepadDataFetcher. Runs on the polling_thread_.
74 void ScheduleDoPoll();
76 void OnGamepadConnectionChange(bool connected
,
78 const blink::WebGamepad
& pad
);
79 void DispatchGamepadConnectionChange(bool connected
,
81 const blink::WebGamepad
& pad
);
83 GamepadHardwareBuffer
* SharedMemoryAsHardwareBuffer();
85 // Checks the gamepad state to see if the user has interacted with it.
86 void CheckForUserGesture();
88 enum { kDesiredSamplingIntervalMs
= 16 };
90 // Keeps track of when the background thread is paused. Access to is_paused_
91 // must be guarded by is_paused_lock_.
92 base::Lock is_paused_lock_
;
95 // Keep track of when a polling task is schedlued, so as to prevent us from
96 // accidentally scheduling more than one at any time, when rapidly toggling
98 bool have_scheduled_do_poll_
;
100 // Lists all observers registered for user gestures, and the thread which
101 // to issue the callbacks on. Since we always issue the callback on the
102 // thread which the registration happened, and this class lives on the I/O
103 // thread, the message loop proxies will normally just be the I/O thread.
104 // However, this will be the main thread for unit testing.
105 base::Lock user_gesture_lock_
;
106 struct ClosureAndThread
{
107 ClosureAndThread(const base::Closure
& c
,
108 const scoped_refptr
<base::MessageLoopProxy
>& m
);
111 base::Closure closure
;
112 scoped_refptr
<base::MessageLoopProxy
> message_loop
;
114 typedef std::vector
<ClosureAndThread
> UserGestureObserverVector
;
115 UserGestureObserverVector user_gesture_observers_
;
117 // Updated based on notification from SystemMonitor when the system devices
118 // have been updated, and this notification is passed on to the data fetcher
119 // to enable it to avoid redundant (and possibly expensive) is-connected
120 // tests. Access to devices_changed_ must be guarded by
121 // devices_changed_lock_.
122 base::Lock devices_changed_lock_
;
123 bool devices_changed_
;
125 bool ever_had_user_gesture_
;
133 bool Match(const blink::WebGamepad
& pad
) const;
134 void SetPad(const blink::WebGamepad
& pad
);
135 void SetDisconnected();
136 void AsWebGamepad(blink::WebGamepad
* pad
);
138 bool connected() const { return connected_
; }
142 unsigned axes_length_
;
143 unsigned buttons_length_
;
144 blink::WebUChar id_
[blink::WebGamepad::idLengthCap
];
145 blink::WebUChar mapping_
[blink::WebGamepad::mappingLengthCap
];
148 // Used to detect connections and disconnections.
149 scoped_ptr
<PadState
[]> pad_states_
;
151 // Only used on the polling thread.
152 scoped_ptr
<GamepadDataFetcher
> data_fetcher_
;
154 base::Lock shared_memory_lock_
;
155 base::SharedMemory gamepad_shared_memory_
;
157 // Polling is done on this background thread.
158 scoped_ptr
<base::Thread
> polling_thread_
;
160 static GamepadProvider
* instance_
;
162 DISALLOW_COPY_AND_ASSIGN(GamepadProvider
);
165 } // namespace content
167 #endif // CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_