// Copyright 2015 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 "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h" #include #include "base/bind.h" #include "base/logging.h" #include "base/no_destructor.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "content/public/common/child_process_host.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h" #if defined(OS_ANDROID) #include "services/proxy_resolver/proxy_resolver_factory_impl.h" #else #include "content/public/browser/service_process_host.h" #include "services/strings/grit/services_strings.h" #endif namespace { proxy_resolver::mojom::ProxyResolverFactory* GetProxyResolverFactory() { static base::NoDestructor< mojo::Remote> remote; if (!remote->is_bound()) { #if defined(OS_ANDROID) // For Android we just lazily initialize a single factory instance and keep // it around forever. static base::NoDestructor factory( remote->BindNewPipeAndPassReceiver()); #else // For other platforms we launch the resolver in its own sandboxed service // process. content::ServiceProcessHost::Launch( remote->BindNewPipeAndPassReceiver(), content::ServiceProcessHost::Options() #if defined(OS_MACOSX) // The proxy_resolver service runs V8, so it needs to run in the // helper application that has the com.apple.security.cs.allow-jit // code signing entitlement, which is CHILD_RENDERER. The service // still runs under the utility process sandbox. .WithChildFlags(content::ChildProcessHost::CHILD_RENDERER) #endif .WithDisplayName(IDS_PROXY_RESOLVER_DISPLAY_NAME) .Pass()); // The service will report itself idle once there are no more bound // ProxyResolver instances. We drop the Remote at that point to initiate // service process termination. Any subsequent call to // |GetProxyResolverFactory()| will launch a new process. remote->reset_on_idle_timeout(base::TimeDelta()); // Also reset on disconnection in case, e.g., the service crashes. remote->reset_on_disconnect(); #endif } return remote->get(); } } // namespace ChromeMojoProxyResolverFactory::ChromeMojoProxyResolverFactory() = default; ChromeMojoProxyResolverFactory::~ChromeMojoProxyResolverFactory() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } mojo::PendingRemote ChromeMojoProxyResolverFactory::CreateWithSelfOwnedReceiver() { mojo::PendingRemote remote; mojo::MakeSelfOwnedReceiver( std::make_unique(), remote.InitWithNewPipeAndPassReceiver()); return remote; } void ChromeMojoProxyResolverFactory::CreateResolver( const std::string& pac_script, mojo::PendingReceiver receiver, mojo::PendingRemote< proxy_resolver::mojom::ProxyResolverFactoryRequestClient> client) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); GetProxyResolverFactory()->CreateResolver(pac_script, std::move(receiver), std::move(client)); }