blob: f9506bff57382ea8875d18e3a63d54fe2e27fbe2 [file] [log] [blame]
// 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.
//
// AudioRendererHost serves audio related requests from AudioRenderer which
// lives inside the render process and provide access to audio hardware.
//
// This class is owned by RenderProcessHostImpl, and instantiated on UI
// thread, but all other operations and method calls happen on IO thread, so we
// need to be extra careful about the lifetime of this object. AudioManager is a
// singleton and created in IO thread, audio output streams are also created in
// the IO thread, so we need to destroy them also in IO thread. After this class
// is created, a task of OnInitialized() is posted on IO thread in which
// singleton of AudioManager is created.
//
// Here's an example of a typical IPC dialog for audio:
//
// Renderer AudioRendererHost
// | |
// | RequestDeviceAuthorization > |
// | < NotifyDeviceAuthorized |
// | |
// | CreateStream > |
// | < NotifyStreamCreated |
// | |
// | PlayStream > |
// | |
// | PauseStream > |
// | |
// | PlayStream > |
// | ... |
// | CloseStream > |
// v v
// If there is an error at any point, a NotifyStreamError will
// be sent. Otherwise, the renderer can assume that the actual state
// of the output stream is consistent with the control signals it sends.
// A SyncSocket pair is used to signal buffer readiness between processes.
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_RENDERER_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_RENDERER_HOST_H_
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "content/browser/renderer_host/media/audio_output_authorization_handler.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/render_process_host.h"
#include "media/audio/audio_output_delegate.h"
namespace base {
class SharedMemory;
class CancelableSyncSocket;
}
namespace media {
class AudioManager;
class AudioParameters;
class AudioSystem;
}
namespace content {
class AudioMirroringManager;
class MediaStreamManager;
class CONTENT_EXPORT AudioRendererHost
: public BrowserMessageFilter,
public media::AudioOutputDelegate::EventHandler {
public:
// Called from UI thread from the owner of this object.
AudioRendererHost(int render_process_id,
media::AudioManager* audio_manager,
media::AudioSystem* audio_system,
AudioMirroringManager* mirroring_manager,
MediaStreamManager* media_stream_manager);
// BrowserMessageFilter implementation.
void OnChannelClosing() override;
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
// AudioOutputDelegate::EventHandler implementation
void OnStreamCreated(
int stream_id,
const base::SharedMemory* shared_memory,
std::unique_ptr<base::CancelableSyncSocket> foreign_socket) override;
void OnStreamError(int stream_id) override;
void OverrideDevicePermissionsForTesting(bool has_access);
private:
friend class AudioRendererHostTest;
friend class BrowserThread;
friend class base::DeleteHelper<AudioRendererHost>;
friend class MockAudioRendererHost;
friend class TestAudioRendererHost;
FRIEND_TEST_ALL_PREFIXES(AudioRendererHostTest, CreateMockStream);
FRIEND_TEST_ALL_PREFIXES(AudioRendererHostTest, MockStreamDataConversation);
using AudioOutputDelegateVector =
std::vector<std::unique_ptr<media::AudioOutputDelegate>>;
// The type of a function that is run on the UI thread to check whether the
// routing IDs reference a valid RenderFrameHost. The function then runs
// |callback| on the IO thread with true/false if valid/invalid.
using ValidateRenderFrameIdFunction =
void (*)(int render_process_id,
int render_frame_id,
base::OnceCallback<void(bool)> callback);
~AudioRendererHost() override;
// Methods called on IO thread ----------------------------------------------
// Audio related IPC message handlers.
// Request permission to use an output device for use by a stream produced
// in the RenderFrame referenced by |render_frame_id|.
// |session_id| is used for unified IO to find out which input device to be
// opened for the stream. For clients that do not use unified IO,
// |session_id| will be ignored and the given |device_id| and
// |security_origin| will be used to select the output device.
// Upon completion of the process, the peer is notified with the device output
// parameters via the NotifyDeviceAuthorized message.
void OnRequestDeviceAuthorization(int stream_id,
int render_frame_id,
int session_id,
const std::string& device_id,
const url::Origin& security_origin);
void AuthorizationCompleted(int stream_id,
base::TimeTicks auth_start_time,
media::OutputDeviceStatus status,
const media::AudioParameters& params,
const std::string& raw_device_id,
const std::string& device_id_for_renderer);
// Creates an audio output stream with the specified format.
// Upon success/failure, the peer is notified via the NotifyStreamCreated
// message.
void OnCreateStream(int stream_id,
int render_frame_id,
const media::AudioParameters& params);
// Play the audio stream referenced by |stream_id|.
void OnPlayStream(int stream_id);
// Pause the audio stream referenced by |stream_id|.
void OnPauseStream(int stream_id);
// Close the audio stream referenced by |stream_id|.
void OnCloseStream(int stream_id);
// Set the volume of the audio stream referenced by |stream_id|.
void OnSetVolume(int stream_id, double volume);
// Helper methods.
// Called after the |render_frame_id| provided to OnCreateStream() was
// validated. When |is_valid| is false, this calls OnStreamError().
void DidValidateRenderFrame(int stream_id, bool is_valid);
// Updates status of stream for AudioStreamMonitor and updates
// the number of playing streams.
void StreamStateChanged(int stream_id, bool is_playing);
// Send an error message to the renderer.
void SendErrorMessage(int stream_id);
// Helper methods to look up a AudioOutputDelegate identified by |stream_id|.
// Returns delegates_.end() if not found.
AudioOutputDelegateVector::iterator LookupIteratorById(int stream_id);
// Returns nullptr if not found.
media::AudioOutputDelegate* LookupById(int stream_id);
// Helper method to check if the authorization procedure for stream
// |stream_id| has started.
bool IsAuthorizationStarted(int stream_id);
// ID of the RenderProcessHost that owns this instance.
const int render_process_id_;
media::AudioManager* const audio_manager_;
AudioMirroringManager* const mirroring_manager_;
// Used to access to AudioInputDeviceManager.
MediaStreamManager* media_stream_manager_;
// Map of device authorizations for streams that are not yet created
// The key is the stream ID, and the value is a pair. The pair's first element
// is a bool that is true if the authorization process completes successfully.
// The second element contains the unique ID of the authorized device.
std::map<int, std::pair<bool, std::string>> authorizations_;
AudioOutputAuthorizationHandler authorization_handler_;
// A list of the current open streams.
AudioOutputDelegateVector delegates_;
DISALLOW_COPY_AND_ASSIGN(AudioRendererHost);
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AUDIO_RENDERER_HOST_H_