| Index: media/mojo/services/service_factory_impl.cc
|
| diff --git a/media/mojo/services/service_factory_impl.cc b/media/mojo/services/service_factory_impl.cc
|
| index fe62213b6dc2441349b324d839145509c2e0926c..cc6bfb7de19b38ec447cba453f0545aa3e898d06 100644
|
| --- a/media/mojo/services/service_factory_impl.cc
|
| +++ b/media/mojo/services/service_factory_impl.cc
|
| @@ -12,21 +12,44 @@
|
| #include "media/mojo/services/mojo_media_client.h"
|
| #include "media/mojo/services/mojo_renderer_service.h"
|
| #include "mojo/application/public/cpp/app_lifetime_helper.h"
|
| +#include "mojo/application/public/cpp/application_connection.h"
|
| +#include "mojo/application/public/cpp/application_impl.h"
|
| #include "mojo/application/public/interfaces/service_provider.mojom.h"
|
| +#include "mojo/common/weak_binding_set.h"
|
|
|
| namespace media {
|
|
|
| +struct ServiceFactoryImpl::ServiceBundle {
|
| + typedef base::Callback<void(const std::string&)> EmptyCallback;
|
| + ServiceBundle(scoped_ptr<mojo::AppRefCount> refcount,
|
| + const std::string& url,
|
| + const EmptyCallback& cb)
|
| + : app_refcount(std::move(refcount)), app_url(url), empty_cb(cb) {
|
| + cdm_bindings.set_connection_error_handler(
|
| + [this]() { OnConnectionError(); });
|
| + renderer_bindings.set_connection_error_handler(
|
| + [this]() { OnConnectionError(); });
|
| + }
|
| + ~ServiceBundle() {}
|
| + void OnConnectionError() {
|
| + if (cdm_bindings.empty() && renderer_bindings.empty())
|
| + empty_cb.Run(app_url);
|
| + }
|
| +
|
| + scoped_ptr<mojo::AppRefCount> app_refcount;
|
| + std::string app_url;
|
| + EmptyCallback empty_cb;
|
| + MojoCdmServiceContext cdm_service_context;
|
| + mojo::WeakBindingSet<interfaces::ContentDecryptionModule> cdm_bindings;
|
| + mojo::WeakBindingSet<interfaces::Renderer> renderer_bindings;
|
| +};
|
| +
|
| ServiceFactoryImpl::ServiceFactoryImpl(
|
| - mojo::InterfaceRequest<interfaces::ServiceFactory> request,
|
| - mojo::ServiceProvider* service_provider,
|
| - scoped_refptr<MediaLog> media_log,
|
| - scoped_ptr<mojo::AppRefCount> parent_app_refcount,
|
| - MojoMediaClient* mojo_media_client)
|
| - : binding_(this, std::move(request)),
|
| - service_provider_(service_provider),
|
| - media_log_(media_log),
|
| - parent_app_refcount_(std::move(parent_app_refcount)),
|
| - mojo_media_client_(mojo_media_client) {
|
| + scoped_ptr<MojoMediaClient> mojo_media_client,
|
| + scoped_refptr<MediaLog> media_log)
|
| + : app_(nullptr),
|
| + mojo_media_client_(std::move(mojo_media_client)),
|
| + media_log_(media_log) {
|
| DVLOG(1) << __FUNCTION__;
|
| }
|
|
|
| @@ -34,10 +57,14 @@ ServiceFactoryImpl::~ServiceFactoryImpl() {
|
| DVLOG(1) << __FUNCTION__;
|
| }
|
|
|
| -// interfaces::ServiceFactory implementation.
|
| -void ServiceFactoryImpl::CreateRenderer(
|
| +void ServiceFactoryImpl::Initialize(mojo::ApplicationImpl* app) {
|
| + app_ = app;
|
| + mojo_media_client_->Initialize();
|
| +}
|
| +
|
| +void ServiceFactoryImpl::Create(
|
| + mojo::ApplicationConnection* connection,
|
| mojo::InterfaceRequest<interfaces::Renderer> request) {
|
| - // The created object is owned by the pipe.
|
| scoped_refptr<base::SingleThreadTaskRunner> task_runner(
|
| base::MessageLoop::current()->task_runner());
|
| scoped_refptr<AudioRendererSink> audio_renderer_sink =
|
| @@ -48,15 +75,44 @@ void ServiceFactoryImpl::CreateRenderer(
|
| task_runner, task_runner, audio_renderer_sink.get(),
|
| video_renderer_sink.get());
|
|
|
| - new MojoRendererService(cdm_service_context_.GetWeakPtr(),
|
| - std::move(renderer), std::move(request));
|
| + ServiceBundle* bundle =
|
| + GetOrCreateServiceBundle(connection->GetRemoteApplicationURL());
|
| + MojoRendererService* renderer_service = new MojoRendererService(
|
| + bundle->cdm_service_context.GetWeakPtr(), std::move(renderer));
|
| + bundle->renderer_bindings.AddBinding(renderer_service, std::move(request));
|
| }
|
|
|
| -void ServiceFactoryImpl::CreateCdm(
|
| +void ServiceFactoryImpl::Create(
|
| + mojo::ApplicationConnection* connection,
|
| mojo::InterfaceRequest<interfaces::ContentDecryptionModule> request) {
|
| - // The created object is owned by the pipe.
|
| - new MojoCdmService(cdm_service_context_.GetWeakPtr(), service_provider_,
|
| - GetCdmFactory(), std::move(request));
|
| + ServiceBundle* bundle =
|
| + GetOrCreateServiceBundle(connection->GetRemoteApplicationURL());
|
| + MojoCdmService* cdm_service =
|
| + new MojoCdmService(bundle->cdm_service_context.GetWeakPtr(),
|
| + GetCdmFactory(connection->GetServiceProvider()));
|
| + bundle->cdm_bindings.AddBinding(cdm_service, std::move(request));
|
| +}
|
| +
|
| +ServiceFactoryImpl::ServiceBundle* ServiceFactoryImpl::GetOrCreateServiceBundle(
|
| + const std::string& url) {
|
| + auto iter = service_bundle_map_.find(url);
|
| + if (iter != service_bundle_map_.end())
|
| + return iter->second.get();
|
| +
|
| + auto ret = service_bundle_map_.insert(std::make_pair(
|
| + url,
|
| + new ServiceBundle(app_->app_lifetime_helper()->CreateAppRefCount(), url,
|
| + base::Bind(&ServiceFactoryImpl::OnServiceBundleEmpty,
|
| + base::Unretained(this)))));
|
| + return ret.first->second.get();
|
| +}
|
| +
|
| +void ServiceFactoryImpl::OnServiceBundleEmpty(const std::string& url) {
|
| + auto iter = service_bundle_map_.find(url);
|
| + DCHECK(iter != service_bundle_map_.end());
|
| + DCHECK(iter->second->cdm_bindings.empty());
|
| + DCHECK(iter->second->renderer_bindings.empty());
|
| + service_bundle_map_.erase(iter);
|
| }
|
|
|
| RendererFactory* ServiceFactoryImpl::GetRendererFactory() {
|
| @@ -65,9 +121,10 @@ RendererFactory* ServiceFactoryImpl::GetRendererFactory() {
|
| return renderer_factory_.get();
|
| }
|
|
|
| -CdmFactory* ServiceFactoryImpl::GetCdmFactory() {
|
| +CdmFactory* ServiceFactoryImpl::GetCdmFactory(
|
| + mojo::ServiceProvider* service_provider) {
|
| if (!cdm_factory_)
|
| - cdm_factory_ = mojo_media_client_->CreateCdmFactory(service_provider_);
|
| + cdm_factory_ = mojo_media_client_->CreateCdmFactory(service_provider);
|
| return cdm_factory_.get();
|
| }
|
|
|
|
|