| Index: services/service_manager/standalone/context.cc
|
| diff --git a/services/service_manager/standalone/context.cc b/services/service_manager/standalone/context.cc
|
| index e2ef480c41ed922e3ab3ca182073567a8f3ce4fc..469af658b727ddc0e593684b2fc23e3fafca9823 100644
|
| --- a/services/service_manager/standalone/context.cc
|
| +++ b/services/service_manager/standalone/context.cc
|
| @@ -14,24 +14,31 @@
|
| #include "base/command_line.h"
|
| #include "base/files/file_path.h"
|
| #include "base/json/json_file_value_serializer.h"
|
| +#include "base/lazy_instance.h"
|
| +#include "base/location.h"
|
| #include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| #include "base/path_service.h"
|
| #include "base/process/process_info.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/single_thread_task_runner.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/string_split.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "base/threading/sequenced_worker_pool.h"
|
| +#include "base/threading/thread_task_runner_handle.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "build/build_config.h"
|
| #include "components/tracing/common/tracing_switches.h"
|
| +#include "mojo/edk/embedder/embedder.h"
|
| +#include "mojo/public/cpp/bindings/strong_binding.h"
|
| #include "services/catalog/catalog.h"
|
| +#include "services/catalog/store.h"
|
| #include "services/service_manager/connect_params.h"
|
| #include "services/service_manager/connect_util.h"
|
| #include "services/service_manager/runner/common/switches.h"
|
| #include "services/service_manager/runner/host/service_process_launcher.h"
|
| -#include "services/service_manager/service_manager.h"
|
| #include "services/service_manager/standalone/tracer.h"
|
| #include "services/service_manager/switches.h"
|
| #include "services/tracing/public/cpp/provider.h"
|
| @@ -43,14 +50,29 @@
|
| #include "services/service_manager/public/cpp/standalone_service/mach_broker.h"
|
| #endif
|
|
|
| -namespace base {
|
| -class TaskRunner;
|
| -}
|
| -
|
| namespace service_manager {
|
| namespace {
|
|
|
| +base::FilePath::StringType GetPathFromCommandLineSwitch(
|
| + const base::StringPiece& value) {
|
| +#if defined(OS_POSIX)
|
| + return value.as_string();
|
| +#elif defined(OS_WIN)
|
| + return base::UTF8ToUTF16(value);
|
| +#endif // OS_POSIX
|
| +}
|
| +
|
| // Used to ensure we only init once.
|
| +class Setup {
|
| + public:
|
| + Setup() { mojo::edk::Init(); }
|
| +
|
| + ~Setup() {}
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(Setup);
|
| +};
|
| +
|
| class ServiceProcessLauncherFactoryImpl : public ServiceProcessLauncherFactory {
|
| public:
|
| ServiceProcessLauncherFactoryImpl(base::TaskRunner* launch_process_runner,
|
| @@ -70,6 +92,14 @@
|
| ServiceProcessLauncher::Delegate* delegate_;
|
| };
|
|
|
| +std::unique_ptr<base::Thread> CreateIOThread(const char* name) {
|
| + std::unique_ptr<base::Thread> thread(new base::Thread(name));
|
| + base::Thread::Options options;
|
| + options.message_loop_type = base::MessageLoop::TYPE_IO;
|
| + thread->StartWithOptions(options);
|
| + return thread;
|
| +}
|
| +
|
| void OnInstanceQuit(const std::string& name, const Identity& identity) {
|
| if (name == identity.name())
|
| base::MessageLoop::current()->QuitWhenIdle();
|
| @@ -79,11 +109,26 @@
|
|
|
| } // namespace
|
|
|
| -Context::Context(
|
| - ServiceProcessLauncher::Delegate* service_process_launcher_delegate,
|
| - std::unique_ptr<base::Value> catalog_contents)
|
| - : main_entry_time_(base::Time::Now()) {
|
| - TRACE_EVENT0("service_manager", "Context::Context");
|
| +Context::InitParams::InitParams() {}
|
| +Context::InitParams::~InitParams() {}
|
| +
|
| +Context::Context()
|
| + : io_thread_(CreateIOThread("io_thread")),
|
| + main_entry_time_(base::Time::Now()) {}
|
| +
|
| +Context::~Context() {
|
| + DCHECK(!base::MessageLoop::current());
|
| + blocking_pool_->Shutdown();
|
| +}
|
| +
|
| +// static
|
| +void Context::EnsureEmbedderIsInitialized() {
|
| + static base::LazyInstance<Setup>::Leaky setup = LAZY_INSTANCE_INITIALIZER;
|
| + setup.Get();
|
| +}
|
| +
|
| +void Context::Init(std::unique_ptr<InitParams> init_params) {
|
| + TRACE_EVENT0("service_manager", "Context::Init");
|
| const base::CommandLine& command_line =
|
| *base::CommandLine::ForCurrentProcess();
|
|
|
| @@ -95,18 +140,58 @@
|
| "mojo_runner.trace");
|
| }
|
|
|
| + if (!init_params || init_params->init_edk)
|
| + EnsureEmbedderIsInitialized();
|
| +
|
| + service_manager_runner_ = base::ThreadTaskRunnerHandle::Get();
|
| blocking_pool_ = new base::SequencedWorkerPool(
|
| kThreadPoolMaxThreads, "blocking_pool", base::TaskPriority::USER_VISIBLE);
|
|
|
| + init_edk_ = !init_params || init_params->init_edk;
|
| + if (init_edk_) {
|
| + mojo::edk::InitIPCSupport(io_thread_->task_runner().get());
|
| +#if defined(OS_MACOSX)
|
| + mojo::edk::SetMachPortProvider(MachBroker::GetInstance()->port_provider());
|
| +#endif
|
| + }
|
| +
|
| std::unique_ptr<ServiceProcessLauncherFactory>
|
| service_process_launcher_factory =
|
| - base::MakeUnique<ServiceProcessLauncherFactoryImpl>(
|
| - blocking_pool_.get(),
|
| - service_process_launcher_delegate);
|
| - catalog_.reset(new catalog::Catalog(std::move(catalog_contents)));
|
| + base::MakeUnique<ServiceProcessLauncherFactoryImpl>(
|
| + blocking_pool_.get(),
|
| + init_params ? init_params->service_process_launcher_delegate
|
| + : nullptr);
|
| + if (init_params && init_params->static_catalog) {
|
| + catalog_.reset(
|
| + new catalog::Catalog(std::move(init_params->static_catalog)));
|
| + } else {
|
| + catalog_.reset(
|
| + new catalog::Catalog(blocking_pool_.get(), nullptr));
|
| + }
|
| service_manager_.reset(
|
| new ServiceManager(std::move(service_process_launcher_factory),
|
| catalog_->TakeService()));
|
| +
|
| + if (command_line.HasSwitch(::switches::kServiceOverrides)) {
|
| + base::FilePath overrides_file(GetPathFromCommandLineSwitch(
|
| + command_line.GetSwitchValueASCII(::switches::kServiceOverrides)));
|
| + JSONFileValueDeserializer deserializer(overrides_file);
|
| + int error = 0;
|
| + std::string message;
|
| + std::unique_ptr<base::Value> contents =
|
| + deserializer.Deserialize(&error, &message);
|
| + if (!contents) {
|
| + LOG(ERROR) << "Failed to parse service overrides file: " << message;
|
| + } else {
|
| + std::unique_ptr<ServiceOverrides> service_overrides =
|
| + base::MakeUnique<ServiceOverrides>(std::move(contents));
|
| + for (const auto& iter : service_overrides->entries()) {
|
| + if (!iter.second.package_name.empty())
|
| + catalog_->OverridePackageName(iter.first, iter.second.package_name);
|
| + }
|
| + service_manager_->SetServiceOverrides(std::move(service_overrides));
|
| + }
|
| + }
|
|
|
| bool enable_stats_collection_bindings =
|
| command_line.HasSwitch(tracing::kEnableStatsCollectionBindings);
|
| @@ -144,7 +229,33 @@
|
| }
|
| }
|
|
|
| -Context::~Context() { blocking_pool_->Shutdown(); }
|
| +void Context::Shutdown() {
|
| + // Actions triggered by Service Manager's destructor may require a current
|
| + // message loop,
|
| + // so we should destruct it explicitly now as ~Context() occurs post message
|
| + // loop shutdown.
|
| + service_manager_.reset();
|
| +
|
| + DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), service_manager_runner_);
|
| +
|
| + // If we didn't initialize the edk we should not shut it down.
|
| + if (!init_edk_)
|
| + return;
|
| +
|
| + TRACE_EVENT0("service_manager", "Context::Shutdown");
|
| + mojo::edk::ShutdownIPCSupport(
|
| + base::Bind(IgnoreResult(&base::TaskRunner::PostTask),
|
| + base::ThreadTaskRunnerHandle::Get(), FROM_HERE,
|
| + base::Bind(&Context::OnShutdownComplete,
|
| + base::Unretained(this))));
|
| + // We'll quit when we get OnShutdownComplete().
|
| + base::RunLoop().Run();
|
| +}
|
| +
|
| +void Context::OnShutdownComplete() {
|
| + DCHECK_EQ(base::ThreadTaskRunnerHandle::Get(), service_manager_runner_);
|
| + base::MessageLoop::current()->QuitWhenIdle();
|
| +}
|
|
|
| void Context::RunCommandLineApplication() {
|
| base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
|
|