forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a new RenderFrameAudioOutputStreamFactory
It checks that the stream is allowed and forwards the request to the relevant ForwardingAudioOutputStreamFactory if so. This will cause the stream to be served by the audio service. The old RenderFrameAudioOutputStreamFactory which creates streams living in content/ is renamed to OldRenderFrameAudioOutputStreamFactory. Since the class was renamed, the files were moved (by adding "old_" to the beginning). No need to review those files. Also note that replacement is diffed against the previous implementation. It's probably best to just ignore the diff and review render_frame_audio_output_stream_factory{.cc,.h,_unittest.cc} as new files. A flag is added to switch between the old factory and the new one. Approximate diagram of stuff: https://docs.google.com/drawings/d/1_ZIKj6lihGKRjq4Mflduitmkn_REqpHFeqVNelBGHHk/edit Tbr since there was a "verbal" LGTM in cl comments. Tbr: nasko Bug: 830493 Change-Id: I38887bb97c817cc9182d71edd89d5ff0193b2504 Reviewed-on: https://chromium-review.googlesource.com/1032751 Commit-Queue: Max Morin <maxmorin@chromium.org> Reviewed-by: Olga Sharonova <olka@chromium.org> Cr-Commit-Position: refs/heads/master@{#557492}
- Loading branch information
Max Morin
authored and
Commit Bot
committed
May 10, 2018
1 parent
74fa71a
commit 59f892f
Showing
20 changed files
with
1,039 additions
and
428 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright 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. | ||
|
||
#include "content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.h" | ||
|
||
#include <memory> | ||
#include <utility> | ||
|
||
#include "base/metrics/histogram_macros.h" | ||
#include "base/task_runner_util.h" | ||
#include "content/browser/renderer_host/media/audio_output_authorization_handler.h" | ||
#include "content/browser/renderer_host/media/audio_output_stream_observer_impl.h" | ||
#include "content/browser/renderer_host/media/renderer_audio_output_stream_factory_context.h" | ||
#include "content/public/browser/render_frame_host.h" | ||
#include "media/base/audio_parameters.h" | ||
#include "media/mojo/services/mojo_audio_output_stream_provider.h" | ||
#include "mojo/public/cpp/bindings/message.h" | ||
|
||
namespace content { | ||
|
||
// static | ||
std::unique_ptr<RenderFrameAudioOutputStreamFactoryHandle, | ||
BrowserThread::DeleteOnIOThread> | ||
RenderFrameAudioOutputStreamFactoryHandle::CreateFactory( | ||
RendererAudioOutputStreamFactoryContext* context, | ||
int render_frame_id, | ||
mojom::RendererAudioOutputStreamFactoryRequest request) { | ||
std::unique_ptr<RenderFrameAudioOutputStreamFactoryHandle, | ||
BrowserThread::DeleteOnIOThread> | ||
handle(new RenderFrameAudioOutputStreamFactoryHandle(context, | ||
render_frame_id)); | ||
// Unretained is safe since |*handle| must be posted to the IO thread prior to | ||
// deletion. | ||
BrowserThread::PostTask( | ||
BrowserThread::IO, FROM_HERE, | ||
base::BindOnce(&RenderFrameAudioOutputStreamFactoryHandle::Init, | ||
base::Unretained(handle.get()), std::move(request))); | ||
return handle; | ||
} | ||
|
||
RenderFrameAudioOutputStreamFactoryHandle:: | ||
~RenderFrameAudioOutputStreamFactoryHandle() { | ||
DCHECK_CURRENTLY_ON(BrowserThread::IO); | ||
} | ||
|
||
RenderFrameAudioOutputStreamFactoryHandle:: | ||
RenderFrameAudioOutputStreamFactoryHandle( | ||
RendererAudioOutputStreamFactoryContext* context, | ||
int render_frame_id) | ||
: impl_(render_frame_id, context), binding_(&impl_) {} | ||
|
||
void RenderFrameAudioOutputStreamFactoryHandle::Init( | ||
mojom::RendererAudioOutputStreamFactoryRequest request) { | ||
DCHECK_CURRENTLY_ON(BrowserThread::IO); | ||
binding_.Bind(std::move(request)); | ||
} | ||
|
||
OldRenderFrameAudioOutputStreamFactory::OldRenderFrameAudioOutputStreamFactory( | ||
int render_frame_id, | ||
RendererAudioOutputStreamFactoryContext* context) | ||
: render_frame_id_(render_frame_id), | ||
context_(context), | ||
weak_ptr_factory_(this) { | ||
DCHECK(context_); | ||
} | ||
|
||
OldRenderFrameAudioOutputStreamFactory:: | ||
~OldRenderFrameAudioOutputStreamFactory() { | ||
DCHECK_CURRENTLY_ON(BrowserThread::IO); | ||
UMA_HISTOGRAM_EXACT_LINEAR("Media.Audio.OutputStreamsCanceledByBrowser", | ||
stream_providers_.size(), 50); | ||
// Make sure to close all streams. | ||
stream_providers_.clear(); | ||
} | ||
|
||
void OldRenderFrameAudioOutputStreamFactory::RequestDeviceAuthorization( | ||
media::mojom::AudioOutputStreamProviderRequest stream_provider_request, | ||
int32_t session_id, | ||
const std::string& device_id, | ||
RequestDeviceAuthorizationCallback callback) { | ||
DCHECK_CURRENTLY_ON(BrowserThread::IO); | ||
const base::TimeTicks auth_start_time = base::TimeTicks::Now(); | ||
|
||
context_->RequestDeviceAuthorization( | ||
render_frame_id_, session_id, device_id, | ||
base::BindOnce( | ||
&OldRenderFrameAudioOutputStreamFactory::AuthorizationCompleted, | ||
weak_ptr_factory_.GetWeakPtr(), auth_start_time, | ||
std::move(stream_provider_request), std::move(callback))); | ||
} | ||
|
||
void OldRenderFrameAudioOutputStreamFactory::AuthorizationCompleted( | ||
base::TimeTicks auth_start_time, | ||
media::mojom::AudioOutputStreamProviderRequest request, | ||
RequestDeviceAuthorizationCallback callback, | ||
media::OutputDeviceStatus status, | ||
const media::AudioParameters& params, | ||
const std::string& raw_device_id, | ||
const std::string& device_id_for_renderer) { | ||
DCHECK_CURRENTLY_ON(BrowserThread::IO); | ||
AudioOutputAuthorizationHandler::UMALogDeviceAuthorizationTime( | ||
auth_start_time); | ||
|
||
if (status != media::OUTPUT_DEVICE_STATUS_OK) { | ||
std::move(callback).Run(media::OutputDeviceStatus(status), | ||
media::AudioParameters::UnavailableDeviceParams(), | ||
std::string()); | ||
return; | ||
} | ||
|
||
int stream_id = next_stream_id_++; | ||
std::unique_ptr<media::mojom::AudioOutputStreamObserver> observer = | ||
std::make_unique<AudioOutputStreamObserverImpl>( | ||
context_->GetRenderProcessId(), render_frame_id_, stream_id); | ||
// Since |context_| outlives |this| and |this| outlives |stream_providers_|, | ||
// unretained is safe. | ||
stream_providers_.insert( | ||
std::make_unique<media::MojoAudioOutputStreamProvider>( | ||
std::move(request), | ||
base::BindOnce( | ||
&RendererAudioOutputStreamFactoryContext::CreateDelegate, | ||
base::Unretained(context_), raw_device_id, render_frame_id_, | ||
stream_id), | ||
base::BindOnce(&OldRenderFrameAudioOutputStreamFactory::RemoveStream, | ||
base::Unretained(this)), | ||
std::move(observer))); | ||
|
||
std::move(callback).Run(media::OutputDeviceStatus(status), params, | ||
device_id_for_renderer); | ||
} | ||
|
||
void OldRenderFrameAudioOutputStreamFactory::RemoveStream( | ||
media::mojom::AudioOutputStreamProvider* stream_provider) { | ||
DCHECK_CURRENTLY_ON(BrowserThread::IO); | ||
|
||
stream_providers_.erase(stream_provider); | ||
} | ||
|
||
} // namespace content |
109 changes: 109 additions & 0 deletions
109
content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright 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_BROWSER_RENDERER_HOST_MEDIA_OLD_RENDER_FRAME_AUDIO_OUTPUT_STREAM_FACTORY_H_ | ||
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_OLD_RENDER_FRAME_AUDIO_OUTPUT_STREAM_FACTORY_H_ | ||
|
||
#include <memory> | ||
#include <string> | ||
|
||
#include "base/containers/flat_set.h" | ||
#include "base/containers/unique_ptr_adapters.h" | ||
#include "content/common/content_export.h" | ||
#include "content/common/media/renderer_audio_output_stream_factory.mojom.h" | ||
#include "content/public/browser/browser_thread.h" | ||
#include "mojo/public/cpp/bindings/binding.h" | ||
|
||
namespace content { | ||
|
||
class RendererAudioOutputStreamFactoryContext; | ||
|
||
// Handles a RendererAudioOutputStreamFactory request for a render frame host, | ||
// using the provided RendererAudioOutputStreamFactoryContext. This class may | ||
// be constructed on any thread, but must be used on the IO thread after that. | ||
// This class is used for creating streams hosted by the browser. It is being | ||
// replaced by RenderFrameAudioOutputStreamFactory, which forwards stream | ||
// requests to the audio service (https://crbug.com/830493). | ||
class CONTENT_EXPORT OldRenderFrameAudioOutputStreamFactory | ||
: public mojom::RendererAudioOutputStreamFactory { | ||
public: | ||
OldRenderFrameAudioOutputStreamFactory( | ||
int render_frame_id, | ||
RendererAudioOutputStreamFactoryContext* context); | ||
|
||
~OldRenderFrameAudioOutputStreamFactory() override; | ||
|
||
private: | ||
using OutputStreamProviderSet = | ||
base::flat_set<std::unique_ptr<media::mojom::AudioOutputStreamProvider>, | ||
base::UniquePtrComparator>; | ||
|
||
// mojom::RendererAudioOutputStreamFactory implementation. | ||
void RequestDeviceAuthorization( | ||
media::mojom::AudioOutputStreamProviderRequest stream_provider, | ||
int32_t session_id, | ||
const std::string& device_id, | ||
RequestDeviceAuthorizationCallback callback) override; | ||
|
||
// Here, the |raw_device_id| is used to create the stream, and | ||
// |device_id_for_renderer| is nonempty in the case when the renderer | ||
// requested a device using a |session_id|, to let it know which device was | ||
// chosen. This id is hashed. | ||
void AuthorizationCompleted( | ||
base::TimeTicks auth_start_time, | ||
media::mojom::AudioOutputStreamProviderRequest request, | ||
RequestDeviceAuthorizationCallback callback, | ||
media::OutputDeviceStatus status, | ||
const media::AudioParameters& params, | ||
const std::string& raw_device_id, | ||
const std::string& device_id_for_renderer); | ||
|
||
void RemoveStream(media::mojom::AudioOutputStreamProvider* stream_provider); | ||
|
||
const int render_frame_id_; | ||
RendererAudioOutputStreamFactoryContext* const context_; | ||
|
||
// The stream providers will contain the corresponding streams. | ||
OutputStreamProviderSet stream_providers_; | ||
|
||
// All streams require IDs. Use a counter to generate them. | ||
int next_stream_id_ = 0; | ||
|
||
base::WeakPtrFactory<OldRenderFrameAudioOutputStreamFactory> | ||
weak_ptr_factory_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(OldRenderFrameAudioOutputStreamFactory); | ||
}; | ||
|
||
// This class is a convenient bundle of factory and binding. | ||
class CONTENT_EXPORT RenderFrameAudioOutputStreamFactoryHandle { | ||
public: | ||
static std::unique_ptr<RenderFrameAudioOutputStreamFactoryHandle, | ||
BrowserThread::DeleteOnIOThread> | ||
CreateFactory(RendererAudioOutputStreamFactoryContext* context, | ||
int render_frame_id, | ||
mojom::RendererAudioOutputStreamFactoryRequest request); | ||
|
||
~RenderFrameAudioOutputStreamFactoryHandle(); | ||
|
||
private: | ||
RenderFrameAudioOutputStreamFactoryHandle( | ||
RendererAudioOutputStreamFactoryContext* context, | ||
int render_frame_id); | ||
|
||
void Init(mojom::RendererAudioOutputStreamFactoryRequest request); | ||
|
||
OldRenderFrameAudioOutputStreamFactory impl_; | ||
mojo::Binding<mojom::RendererAudioOutputStreamFactory> binding_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioOutputStreamFactoryHandle); | ||
}; | ||
|
||
using UniqueAudioOutputStreamFactoryPtr = | ||
std::unique_ptr<RenderFrameAudioOutputStreamFactoryHandle, | ||
BrowserThread::DeleteOnIOThread>; | ||
|
||
} // namespace content | ||
|
||
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_OLD_RENDER_FRAME_AUDIO_OUTPUT_STREAM_FACTORY_H_ |
Oops, something went wrong.