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(); |
} |