// Copyright (c) 2017 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 CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_AUDIO_OUTPUT_DEV_H_ #define CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_AUDIO_OUTPUT_DEV_H_ #include #include #include "base/macros.h" #include "base/memory/ref_counted.h" #include "media/audio/audio_output_ipc.h" #include "media/base/audio_parameters.h" #include "media/base/output_device_info.h" namespace base { class OneShotTimer; class SingleThreadTaskRunner; } namespace content { class PepperAudioOutputHost; // This class is used to support new PPAPI |PPB_AudioOutput_Dev|, while // |PepperPlatformAudioOutput| is to support old PPAPI |PPB_Audio|. class PepperPlatformAudioOutputDev : public media::AudioOutputIPCDelegate, public base::RefCountedThreadSafe { public: // Factory function, returns NULL on failure. StreamCreated() will be called // when the stream is created. static PepperPlatformAudioOutputDev* Create(int render_frame_id, const std::string& device_id, const GURL& document_url, int sample_rate, int frames_per_buffer, PepperAudioOutputHost* client); // The following three methods are all called on main thread. // Request authorization to use the device. void RequestDeviceAuthorization(); // Starts the playback. Returns false on error or if called before the // stream is created or after the stream is closed. bool StartPlayback(); // Stops the playback. Returns false on error or if called before the stream // is created or after the stream is closed. bool StopPlayback(); // Sets the volume. Returns false on error or if called before the stream // is created or after the stream is closed. bool SetVolume(double volume); // Closes the stream. Make sure to call this before the object is // destructed. void ShutDown(); // media::AudioOutputIPCDelegate implementation. void OnError() override; void OnDeviceAuthorized(media::OutputDeviceStatus device_status, const media::AudioParameters& output_params, const std::string& matched_device_id) override; void OnStreamCreated(base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle) override; void OnIPCClosed() override; protected: ~PepperPlatformAudioOutputDev() override; private: enum State { IPC_CLOSED, // No more IPCs can take place. IDLE, // Not started. AUTHORIZING, // Sent device authorization request, waiting for reply. AUTHORIZED, // Successful device authorization received. CREATING_STREAM, // Waiting for OnStreamCreated() to be called back. PAUSED, // Paused. OnStreamCreated() has been called. Can Play()/Stop(). PLAYING, // Playing back. Can Pause()/Stop(). }; friend class base::RefCountedThreadSafe; PepperPlatformAudioOutputDev(); PepperPlatformAudioOutputDev(int render_frame_id, const std::string& device_id, const GURL& document_url, base::TimeDelta authorization_timeout); // Creates audio stream. Used for new Pepper audio output interface // |PPB_AudioOutput_Dev|. bool Initialize(int sample_rate, int frames_per_buffer, PepperAudioOutputHost* client); void RequestDeviceAuthorizationOnIOThread(); void CreateStreamOnIOThread(const media::AudioParameters& params); void StartPlaybackOnIOThread(); void StopPlaybackOnIOThread(); void SetVolumeOnIOThread(double volume); void ShutDownOnIOThread(); void NotifyStreamCreationFailed(); PepperAudioOutputHost* client_; // Used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE // I/O thread except to send messages and get the message loop. std::unique_ptr ipc_; scoped_refptr main_task_runner_; scoped_refptr io_task_runner_; // The frame containing the Pepper widget. int render_frame_id_; // Initialized on the main thread and accessed on the I/O thread afterwards. media::AudioParameters params_; // Current state (must only be accessed from the IO thread). State state_; // State of Start() calls before OnDeviceAuthorized() is called. bool start_on_authorized_; // State of StartPlayback() calls before OnStreamCreated() is called. bool play_on_start_; // The media session ID used to identify which output device to be started. int session_id_; // ID of hardware output device to be used (provided session_id_ is zero) const std::string device_id_; const url::Origin security_origin_; // If |device_id_| is empty and |session_id_| is not, |matched_device_id_| is // received in OnDeviceAuthorized(). std::string matched_device_id_; base::WaitableEvent did_receive_auth_; media::AudioParameters output_params_; media::OutputDeviceStatus device_status_; const base::TimeDelta auth_timeout_; std::unique_ptr auth_timeout_action_; DISALLOW_COPY_AND_ASSIGN(PepperPlatformAudioOutputDev); }; } // namespace content #endif // CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_AUDIO_OUTPUT_DEV_H_