Motown: Factor FactoryServiceBase out of MediaFactoryService Extracts FactoryServiceBase from MediaFactoryService so it can be used for other services (the new logging service will use it). FactoryServiceBase defines the relationship between a factory service and its 'products' and provides a means for controlling the lifetime of products. R=kulakowski@chromium.org Review URL: https://codereview.chromium.org/2007593004 .
diff --git a/services/media/factory_service/BUILD.gn b/services/media/factory_service/BUILD.gn index c93cee3..21a1e4b 100644 --- a/services/media/factory_service/BUILD.gn +++ b/services/media/factory_service/BUILD.gn
@@ -49,6 +49,7 @@ "//services/media/framework_create", "//services/media/framework_ffmpeg", "//services/media/framework_mojo", + "//services/util/cpp", "//url", ] }
diff --git a/services/media/factory_service/factory_service.cc b/services/media/factory_service/factory_service.cc index 6fe73f1..94b4c9b 100644 --- a/services/media/factory_service/factory_service.cc +++ b/services/media/factory_service/factory_service.cc
@@ -13,21 +13,10 @@ namespace mojo { namespace media { -MediaFactoryService::ProductBase::ProductBase(MediaFactoryService* owner) - : owner_(owner) { - DCHECK(owner_); -} - -MediaFactoryService::ProductBase::~ProductBase() {} - MediaFactoryService::MediaFactoryService() {} MediaFactoryService::~MediaFactoryService() {} -void MediaFactoryService::Initialize(ApplicationImpl* app) { - app_ = app; -} - bool MediaFactoryService::ConfigureIncomingConnection( ServiceProviderImpl* service_provider_impl) { service_provider_impl->AddService<MediaFactory>( @@ -40,43 +29,39 @@ void MediaFactoryService::CreatePlayer(InterfaceHandle<SeekingReader> reader, InterfaceRequest<MediaPlayer> player) { - products_.insert(std::static_pointer_cast<ProductBase>( - MediaPlayerImpl::Create(reader.Pass(), player.Pass(), this))); + AddProduct(MediaPlayerImpl::Create(reader.Pass(), player.Pass(), this)); } void MediaFactoryService::CreateSource(InterfaceHandle<SeekingReader> reader, Array<MediaTypeSetPtr> media_types, InterfaceRequest<MediaSource> source) { - products_.insert( - std::static_pointer_cast<ProductBase>(MediaSourceImpl::Create( - reader.Pass(), media_types, source.Pass(), this))); + AddProduct( + MediaSourceImpl::Create(reader.Pass(), media_types, source.Pass(), this)); } void MediaFactoryService::CreateSink(const String& destination_url, MediaTypePtr media_type, InterfaceRequest<MediaSink> sink) { - products_.insert(std::static_pointer_cast<ProductBase>(MediaSinkImpl::Create( - destination_url, media_type.Pass(), sink.Pass(), this))); + AddProduct(MediaSinkImpl::Create(destination_url, media_type.Pass(), + sink.Pass(), this)); } void MediaFactoryService::CreateDemux(InterfaceHandle<SeekingReader> reader, InterfaceRequest<MediaDemux> demux) { - products_.insert(std::static_pointer_cast<ProductBase>( - MediaDemuxImpl::Create(reader.Pass(), demux.Pass(), this))); + AddProduct(MediaDemuxImpl::Create(reader.Pass(), demux.Pass(), this)); } void MediaFactoryService::CreateDecoder( MediaTypePtr input_media_type, InterfaceRequest<MediaTypeConverter> decoder) { - products_.insert(std::static_pointer_cast<ProductBase>( - MediaDecoderImpl::Create(input_media_type.Pass(), decoder.Pass(), this))); + AddProduct( + MediaDecoderImpl::Create(input_media_type.Pass(), decoder.Pass(), this)); } void MediaFactoryService::CreateNetworkReader( const String& url, InterfaceRequest<SeekingReader> reader) { - products_.insert(std::static_pointer_cast<ProductBase>( - NetworkReaderImpl::Create(url, reader.Pass(), this))); + AddProduct(NetworkReaderImpl::Create(url, reader.Pass(), this)); } } // namespace media
diff --git a/services/media/factory_service/factory_service.h b/services/media/factory_service/factory_service.h index f2a7fd5..8b4f520 100644 --- a/services/media/factory_service/factory_service.h +++ b/services/media/factory_service/factory_service.h
@@ -5,77 +5,23 @@ #ifndef MOJO_SERVICES_MEDIA_FACTORY_FACTORY_SERVICE_H_ #define MOJO_SERVICES_MEDIA_FACTORY_FACTORY_SERVICE_H_ -#include <unordered_set> - #include "mojo/common/binding_set.h" #include "mojo/public/cpp/application/application_delegate.h" #include "mojo/public/cpp/application/application_impl.h" #include "mojo/services/media/control/interfaces/media_factory.mojom.h" +#include "services/util/cpp/factory_service_base.h" namespace mojo { namespace media { -class MediaFactoryService : public ApplicationDelegate, +class MediaFactoryService : public util::FactoryServiceBase, public MediaFactory { public: - // Provides common behavior for all objects created by the factory service. - class ProductBase : public std::enable_shared_from_this<ProductBase> { - public: - virtual ~ProductBase(); - - protected: - ProductBase(MediaFactoryService* owner); - - // Returns the ApplicationImpl. - ApplicationImpl* app() { - DCHECK(owner_->app_); - return owner_->app_; - } - - // Tells the factory service to release this product. - void ReleaseFromOwner() { - size_t erased = owner_->products_.erase(shared_from_this()); - DCHECK(erased); - } - - private: - MediaFactoryService* owner_; - }; - - template <typename Interface> - class Product : public ProductBase { - public: - virtual ~Product() {} - - protected: - Product(Interface* impl, - InterfaceRequest<Interface> request, - MediaFactoryService* owner) - : ProductBase(owner), binding_(impl, request.Pass()) { - DCHECK(impl); - binding_.set_connection_error_handler([this]() { ReleaseFromOwner(); }); - } - - // Closes the binding and calls ReleaseFromOwner. - void UnbindAndReleaseFromOwner() { - if (binding_.is_bound()) { - binding_.Close(); - } - - ReleaseFromOwner(); - } - - private: - Binding<Interface> binding_; - }; - MediaFactoryService(); ~MediaFactoryService() override; // ApplicationDelegate implementation. - void Initialize(ApplicationImpl* app) override; - bool ConfigureIncomingConnection( ServiceProviderImpl* service_provider_impl) override; @@ -102,21 +48,8 @@ private: BindingSet<MediaFactory> bindings_; - ApplicationImpl* app_; - std::unordered_set<std::shared_ptr<ProductBase>> products_; }; -// For use by products when handling mojo requests. -// Checks the condition, and, if it's false, unbinds, releases from the owner -// and calls return. Doesn't support stream arguments. -// TODO(dalesat): Support stream arguments. -#define RCHECK(condition) \ - if (!(condition)) { \ - LOG(ERROR) << "request precondition failed: " #condition "."; \ - UnbindAndReleaseFromOwner(); \ - return; \ - } - } // namespace media } // namespace mojo
diff --git a/services/util/cpp/BUILD.gn b/services/util/cpp/BUILD.gn new file mode 100644 index 0000000..6a917c3 --- /dev/null +++ b/services/util/cpp/BUILD.gn
@@ -0,0 +1,21 @@ +# Copyright 2016 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. + +import("//build/module_args/mojo.gni") +import("//mojo/public/mojo_application.gni") +import("$mojo_sdk_root/mojo/public/mojo_sdk.gni") + +source_set("cpp") { + sources = [ + "factory_service_base.cc", + "factory_service_base.h", + ] + + deps = [ + "//base", + "//mojo/application", + "//mojo/common", + "//mojo/public/cpp/application", + ] +}
diff --git a/services/util/cpp/factory_service_base.cc b/services/util/cpp/factory_service_base.cc new file mode 100644 index 0000000..cc00c1b --- /dev/null +++ b/services/util/cpp/factory_service_base.cc
@@ -0,0 +1,27 @@ +// Copyright 2016 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 "base/logging.h" +#include "services/util/cpp/factory_service_base.h" + +namespace mojo { +namespace util { + +FactoryServiceBase::ProductBase::ProductBase(FactoryServiceBase* owner) + : owner_(owner) { + DCHECK(owner_); +} + +FactoryServiceBase::ProductBase::~ProductBase() {} + +FactoryServiceBase::FactoryServiceBase() {} + +FactoryServiceBase::~FactoryServiceBase() {} + +void FactoryServiceBase::Initialize(ApplicationImpl* app) { + app_ = app; +} + +} // namespace util +} // namespace mojo
diff --git a/services/util/cpp/factory_service_base.h b/services/util/cpp/factory_service_base.h new file mode 100644 index 0000000..9a5ec4a --- /dev/null +++ b/services/util/cpp/factory_service_base.h
@@ -0,0 +1,103 @@ +// Copyright 2016 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 MOJO_SERVICES_UTIL_CPP_FACTORY_SERVICE_BASE_H_ +#define MOJO_SERVICES_UTIL_CPP_FACTORY_SERVICE_BASE_H_ + +#include <memory> +#include <unordered_set> + +#include "base/logging.h" +#include "mojo/public/cpp/application/application_delegate.h" +#include "mojo/public/cpp/application/application_impl.h" + +namespace mojo { +namespace util { + +class FactoryServiceBase : public ApplicationDelegate { + public: + // Provides common behavior for all objects created by the factory service. + class ProductBase : public std::enable_shared_from_this<ProductBase> { + public: + virtual ~ProductBase(); + + protected: + ProductBase(FactoryServiceBase* owner); + + // Returns the ApplicationImpl. + ApplicationImpl* app() { + DCHECK(owner_->app_); + return owner_->app_; + } + + // Tells the factory service to release this product. + void ReleaseFromOwner() { + size_t erased = owner_->products_.erase(shared_from_this()); + DCHECK(erased); + } + + private: + FactoryServiceBase* owner_; + }; + + template <typename Interface> + class Product : public ProductBase { + public: + virtual ~Product() {} + + protected: + Product(Interface* impl, + InterfaceRequest<Interface> request, + FactoryServiceBase* owner) + : ProductBase(owner), binding_(impl, request.Pass()) { + DCHECK(impl); + binding_.set_connection_error_handler([this]() { ReleaseFromOwner(); }); + } + + // Closes the binding and calls ReleaseFromOwner. + void UnbindAndReleaseFromOwner() { + if (binding_.is_bound()) { + binding_.Close(); + } + + ReleaseFromOwner(); + } + + private: + Binding<Interface> binding_; + }; + + FactoryServiceBase(); + + ~FactoryServiceBase() override; + + // ApplicationDelegate implementation. + void Initialize(ApplicationImpl* app) override; + + protected: + template <typename ProductImpl> + void AddProduct(std::shared_ptr<ProductImpl> product) { + products_.insert(std::static_pointer_cast<ProductBase>(product)); + } + + private: + ApplicationImpl* app_; + std::unordered_set<std::shared_ptr<ProductBase>> products_; +}; + +// For use by products when handling mojo requests. +// Checks the condition, and, if it's false, unbinds, releases from the owner +// and calls return. Doesn't support stream arguments. +// TODO(dalesat): Support stream arguments. +#define RCHECK(condition) \ + if (!(condition)) { \ + LOG(ERROR) << "request precondition failed: " #condition "."; \ + UnbindAndReleaseFromOwner(); \ + return; \ + } + +} // namespace util +} // namespace mojo + +#endif // MOJO_SERVICES_UTIL_CPP_FACTORY_SERVICE_BASE_H_