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. 4 5 #ifndef CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_ 6 #define CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_ 7 8 #include <utility> 9 #include <vector> 10 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 21 namespace base { 22 class MessageLoopProxy; 23 class Thread; 24 } 25 26 namespace content { 27 28 class GamepadDataFetcher; 29 struct GamepadHardwareBuffer; 30 31 class CONTENT_EXPORT GamepadProvider : 32 public base::SystemMonitor::DevicesChangedObserver { 33 public: 34 GamepadProvider(); 35 36 // Manually specifies the data fetcher. Used for testing. 37 explicit GamepadProvider(scoped_ptr<GamepadDataFetcher> fetcher); 38 39 virtual ~GamepadProvider(); 40 41 // Returns the shared memory handle of the gamepad data duplicated into the 42 // given process. 43 base::SharedMemoryHandle GetSharedMemoryHandleForProcess( 44 base::ProcessHandle renderer_process); 45 46 // Pause and resume the background polling thread. Can be called from any 47 // thread. 48 void Pause(); 49 void Resume(); 50 51 // Registers the given closure for calling when the user has interacted with 52 // the device. This callback will only be issued once. 53 void RegisterForUserGesture(const base::Closure& closure); 54 55 // base::SystemMonitor::DevicesChangedObserver implementation. 56 virtual void OnDevicesChanged(base::SystemMonitor::DeviceType type) OVERRIDE; 57 58 private: 59 void Initialize(scoped_ptr<GamepadDataFetcher> fetcher); 60 61 // Method for setting up the platform-specific data fetcher. Takes ownership 62 // of |fetcher|. 63 void DoInitializePollingThread(scoped_ptr<GamepadDataFetcher> fetcher); 64 65 // Method for sending pause hints to the low-level data fetcher. Runs on 66 // polling_thread_. 67 void SendPauseHint(bool paused); 68 69 // Method for polling a GamepadDataFetcher. Runs on the polling_thread_. 70 void DoPoll(); 71 void ScheduleDoPoll(); 72 73 GamepadHardwareBuffer* SharedMemoryAsHardwareBuffer(); 74 75 // Checks the gamepad state to see if the user has interacted with it. 76 void CheckForUserGesture(); 77 78 enum { kDesiredSamplingIntervalMs = 16 }; 79 80 // Keeps track of when the background thread is paused. Access to is_paused_ 81 // must be guarded by is_paused_lock_. 82 base::Lock is_paused_lock_; 83 bool is_paused_; 84 85 // Keep track of when a polling task is schedlued, so as to prevent us from 86 // accidentally scheduling more than one at any time, when rapidly toggling 87 // |is_paused_|. 88 bool have_scheduled_do_poll_; 89 90 // Lists all observers registered for user gestures, and the thread which 91 // to issue the callbacks on. Since we always issue the callback on the 92 // thread which the registration happened, and this class lives on the I/O 93 // thread, the message loop proxies will normally just be the I/O thread. 94 // However, this will be the main thread for unit testing. 95 base::Lock user_gesture_lock_; 96 struct ClosureAndThread { 97 ClosureAndThread(const base::Closure& c, 98 const scoped_refptr<base::MessageLoopProxy>& m); 99 ~ClosureAndThread(); 100 101 base::Closure closure; 102 scoped_refptr<base::MessageLoopProxy> message_loop; 103 }; 104 typedef std::vector<ClosureAndThread> UserGestureObserverVector; 105 UserGestureObserverVector user_gesture_observers_; 106 107 // Updated based on notification from SystemMonitor when the system devices 108 // have been updated, and this notification is passed on to the data fetcher 109 // to enable it to avoid redundant (and possibly expensive) is-connected 110 // tests. Access to devices_changed_ must be guarded by 111 // devices_changed_lock_. 112 base::Lock devices_changed_lock_; 113 bool devices_changed_; 114 115 // When polling_thread_ is running, members below are only to be used 116 // from that thread. 117 scoped_ptr<GamepadDataFetcher> data_fetcher_; 118 base::SharedMemory gamepad_shared_memory_; 119 120 // Polling is done on this background thread. 121 scoped_ptr<base::Thread> polling_thread_; 122 123 static GamepadProvider* instance_; 124 125 DISALLOW_COPY_AND_ASSIGN(GamepadProvider); 126 }; 127 128 } // namespace content 129 130 #endif // CONTENT_BROWSER_GAMEPAD_GAMEPAD_PROVIDER_H_ 131