1 // Copyright 2017 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 DEVICE_GAMEPAD_ABSTRACT_HAPTIC_GAMEPAD_ 6 #define DEVICE_GAMEPAD_ABSTRACT_HAPTIC_GAMEPAD_ 7 8 #include "base/memory/scoped_refptr.h" 9 #include "base/memory/weak_ptr.h" 10 #include "base/sequenced_task_runner.h" 11 #include "base/threading/thread_checker.h" 12 #include "base/time/time.h" 13 #include "device/gamepad/gamepad_export.h" 14 #include "device/gamepad/public/mojom/gamepad.mojom.h" 15 16 namespace device { 17 18 // AbstractHapticGamepad is a base class for gamepads that support dual-rumble 19 // vibration effects. To use it, override the SetVibration method so that it 20 // sets the vibration intensity on the device. Then, calling PlayEffect or 21 // ResetVibration will call your SetVibration method at the appropriate times 22 // to produce the desired vibration effect. When the effect is complete, or when 23 // it has been preempted by another effect, the callback is invoked with a 24 // result code. 25 // 26 // By default, SetZeroVibration simply calls SetVibration with both parameters 27 // set to zero. You may optionally override SetZeroVibration if the device has a 28 // more efficient means of stopping an ongoing effect. 29 class DEVICE_GAMEPAD_EXPORT AbstractHapticGamepad { 30 public: 31 AbstractHapticGamepad(); 32 virtual ~AbstractHapticGamepad(); 33 34 // Start playing a haptic effect of type |type|, described by |params|. When 35 // the effect is complete, or if it encounters an error, the result code is 36 // passed back to the caller on its own sequence by calling |callback| using 37 // |callback_runner|. 38 void PlayEffect( 39 mojom::GamepadHapticEffectType type, 40 mojom::GamepadEffectParametersPtr params, 41 mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback callback, 42 scoped_refptr<base::SequencedTaskRunner> callback_runner); 43 44 // Reset vibration on the gamepad, perhaps interrupting an ongoing effect. A 45 // result code is passed back to the caller on its own sequence by calling 46 // |callback| using |callback_runner|. 47 void ResetVibration( 48 mojom::GamepadHapticsManager::ResetVibrationActuatorCallback callback, 49 scoped_refptr<base::SequencedTaskRunner> callback_runner); 50 51 // Stop vibration effects, run callbacks, and release held resources. Must be 52 // called exactly once before the device is destroyed. 53 void Shutdown(); 54 55 // Returns true if Shutdown() has been called. IsShuttingDown()56 bool IsShuttingDown() { return is_shutting_down_; } 57 58 // Set the vibration magnitude for the strong and weak vibration actuators. 59 virtual void SetVibration(double strong_magnitude, double weak_magnitude) = 0; 60 61 // Set the vibration magnitude for both actuators to zero. 62 virtual void SetZeroVibration(); 63 64 // The maximum effect duration supported by this device. Long-running effects 65 // must be divided into effects of this duration or less. 66 virtual double GetMaxEffectDurationMillis(); 67 68 virtual base::WeakPtr<AbstractHapticGamepad> GetWeakPtr() = 0; 69 70 private: 71 // Override to perform additional shutdown actions after vibration effects 72 // are halted and callbacks are issued. DoShutdown()73 virtual void DoShutdown() {} 74 75 void PlayDualRumbleEffect(int sequence_id, 76 double duration, 77 double start_delay, 78 double strong_magnitude, 79 double weak_magnitude); 80 void StartVibration(int sequence_id, 81 double duration, 82 double strong_magnitude, 83 double weak_magnitude); 84 void FinishEffect(int sequence_id); 85 86 bool is_shutting_down_ = false; 87 bool is_shut_down_ = false; 88 int sequence_id_ = 0; 89 mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback 90 playing_effect_callback_; 91 scoped_refptr<base::SequencedTaskRunner> callback_runner_; 92 THREAD_CHECKER(thread_checker_); 93 }; 94 95 } // namespace device 96 97 #endif // DEVICE_GAMEPAD_ABSTRACT_HAPTIC_GAMEPAD_ 98