123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef DEVICE_GAMEPAD_GAMEPAD_PROVIDER_H_
- #define DEVICE_GAMEPAD_GAMEPAD_PROVIDER_H_
- #include <memory>
- #include <utility>
- #include <vector>
- #include "base/callback_forward.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/read_only_shared_memory_region.h"
- #include "base/memory/ref_counted.h"
- #include "base/synchronization/lock.h"
- #include "base/system/system_monitor.h"
- #include "base/time/time.h"
- #include "device/gamepad/gamepad_export.h"
- #include "device/gamepad/gamepad_pad_state_provider.h"
- #include "device/gamepad/gamepad_shared_buffer.h"
- #include "device/gamepad/public/cpp/gamepads.h"
- #include "device/gamepad/public/mojom/gamepad.mojom.h"
- #include "mojo/public/cpp/system/buffer.h"
- namespace base {
- class SingleThreadTaskRunner;
- class Thread;
- } // namespace base
- namespace device {
- class GamepadDataFetcher;
- class DEVICE_GAMEPAD_EXPORT GamepadChangeClient {
- public:
- virtual void OnGamepadConnectionChange(bool connected,
- uint32_t index,
- const Gamepad& pad) = 0;
- virtual void OnGamepadChange(mojom::GamepadChangesPtr changes) = 0;
- };
- class DEVICE_GAMEPAD_EXPORT GamepadProvider
- : public GamepadPadStateProvider,
- public base::SystemMonitor::DevicesChangedObserver {
- public:
- explicit GamepadProvider(GamepadChangeClient* gamepad_change_client);
- // Manually specifies the data fetcher and polling thread. The polling thread
- // will be created normally if |polling_thread| is nullptr. Used for testing.
- GamepadProvider(GamepadChangeClient* gamepad_change_client,
- std::unique_ptr<GamepadDataFetcher> fetcher,
- std::unique_ptr<base::Thread> polling_thread);
- GamepadProvider(const GamepadProvider&) = delete;
- GamepadProvider& operator=(const GamepadProvider&) = delete;
- ~GamepadProvider() override;
- // Returns a duplicate of the shared memory region of the gamepad data.
- base::ReadOnlySharedMemoryRegion DuplicateSharedMemoryRegion();
- void GetCurrentGamepadData(Gamepads* data);
- void PlayVibrationEffectOnce(
- uint32_t pad_index,
- mojom::GamepadHapticEffectType,
- mojom::GamepadEffectParametersPtr,
- mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback);
- void ResetVibrationActuator(
- uint32_t pad_index,
- mojom::GamepadHapticsManager::ResetVibrationActuatorCallback);
- // Pause and resume the background polling thread. Can be called from any
- // thread.
- void Pause();
- void Resume();
- // Registers the given closure for calling when the user has interacted with
- // the device. This callback will only be issued once.
- void RegisterForUserGesture(base::OnceClosure closure);
- // base::SystemMonitor::DevicesChangedObserver implementation.
- void OnDevicesChanged(base::SystemMonitor::DeviceType type) override;
- // Add a gamepad data fetcher. Takes ownership of |fetcher|.
- void AddGamepadDataFetcher(std::unique_ptr<GamepadDataFetcher> fetcher);
- // Remove gamepad data fetchers with the given source.
- void RemoveSourceGamepadDataFetcher(GamepadSource source);
- void SetSanitizationEnabled(bool sanitize) { sanitize_ = sanitize; }
- private:
- void Initialize(std::unique_ptr<GamepadDataFetcher> fetcher);
- // Method for setting up the platform-specific data fetcher. Takes ownership
- // of |fetcher|.
- void DoAddGamepadDataFetcher(std::unique_ptr<GamepadDataFetcher> fetcher);
- void DoRemoveSourceGamepadDataFetcher(GamepadSource source);
- GamepadDataFetcher* GetSourceGamepadDataFetcher(GamepadSource source);
- // Method for sending pause hints to the low-level data fetcher. Runs on
- // polling_thread_.
- void SendPauseHint(bool paused);
- // Method for polling a GamepadDataFetcher. Runs on the polling_thread_.
- void DoPoll();
- void ScheduleDoPoll();
- void SendChangeEvents(mojom::GamepadChangesPtr changes);
- void OnGamepadConnectionChange(bool connected,
- uint32_t index,
- const Gamepad& pad);
- // Checks the gamepad state to see if the user has interacted with it. Returns
- // true if any user gesture observers were notified.
- bool CheckForUserGesture();
- // GamepadPadStateProvider implementation.
- void DisconnectUnrecognizedGamepad(GamepadSource source,
- int source_id) override;
- void PlayEffectOnPollingThread(
- uint32_t pad_index,
- mojom::GamepadHapticEffectType,
- mojom::GamepadEffectParametersPtr,
- mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback,
- scoped_refptr<base::SequencedTaskRunner>);
- void ResetVibrationOnPollingThread(
- uint32_t pad_index,
- mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback,
- scoped_refptr<base::SequencedTaskRunner>);
- // The duration of the delay between iterations of DoPoll.
- base::TimeDelta sampling_interval_delta_;
- // Keeps track of when the background thread is paused. Access to is_paused_
- // must be guarded by is_paused_lock_.
- base::Lock is_paused_lock_;
- bool is_paused_ = true;
- // Keep track of when a polling task is schedlued, so as to prevent us from
- // accidentally scheduling more than one at any time, when rapidly toggling
- // |is_paused_|.
- bool have_scheduled_do_poll_ = false;
- // Lists all observers registered for user gestures, and the thread which
- // to issue the callbacks on. Since we always issue the callback on the
- // thread which the registration happened, and this class lives on the I/O
- // thread, the message loop proxies will normally just be the I/O thread.
- // However, this will be the main thread for unit testing.
- base::Lock user_gesture_lock_;
- using ClosureAndThread =
- std::pair<base::OnceClosure, scoped_refptr<base::SingleThreadTaskRunner>>;
- using UserGestureObserverVector = std::vector<ClosureAndThread>;
- UserGestureObserverVector user_gesture_observers_;
- // Updated based on notification from SystemMonitor when the system devices
- // have been updated, and this notification is passed on to the data fetcher
- // to enable it to avoid redundant (and possibly expensive) is-connected
- // tests. Access to devices_changed_ must be guarded by
- // devices_changed_lock_.
- base::Lock devices_changed_lock_;
- bool devices_changed_ = true;
- bool ever_had_user_gesture_ = false;
- bool sanitize_ = true;
- // Only used on the polling thread.
- using GamepadFetcherVector = std::vector<std::unique_ptr<GamepadDataFetcher>>;
- GamepadFetcherVector data_fetchers_;
- base::Lock shared_memory_lock_;
- std::unique_ptr<GamepadSharedBuffer> gamepad_shared_buffer_;
- // Polling is done on this background thread.
- std::unique_ptr<base::Thread> polling_thread_;
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
- raw_ptr<GamepadChangeClient> gamepad_change_client_;
- };
- } // namespace device
- #endif // DEVICE_GAMEPAD_GAMEPAD_PROVIDER_H_
|