blob: 03dff4f2d8ff8dfe29827ccf25e3eb160a4247b9 [file] [log] [blame]
// Copyright (c) 2012 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/utility/chrome_content_utility_client.h"
#include <stddef.h>
#include <utility>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/profiler/thread_profiler.h"
#include "chrome/common/profiler/thread_profiler_configuration.h"
#include "chrome/utility/browser_exposed_utility_interfaces.h"
#include "chrome/utility/services.h"
#include "content/public/child/child_thread.h"
#include "content/public/common/content_switches.h"
#include "sandbox/policy/switches.h"
#if BUILDFLAG(ENABLE_PRINT_PREVIEW) && defined(OS_WIN)
#include "chrome/utility/printing_handler.h"
#endif
namespace {
base::LazyInstance<ChromeContentUtilityClient::NetworkBinderCreationCallback>::
Leaky g_network_binder_creation_callback = LAZY_INSTANCE_INITIALIZER;
} // namespace
ChromeContentUtilityClient::ChromeContentUtilityClient()
: utility_process_running_elevated_(false) {
#if BUILDFLAG(ENABLE_PRINT_PREVIEW) && defined(OS_WIN)
printing_handler_ = std::make_unique<printing::PrintingHandler>();
#endif
}
ChromeContentUtilityClient::~ChromeContentUtilityClient() = default;
void ChromeContentUtilityClient::ExposeInterfacesToBrowser(
mojo::BinderMap* binders) {
#if defined(OS_WIN)
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
utility_process_running_elevated_ = command_line->HasSwitch(
sandbox::policy::switches::kNoSandboxAndElevatedPrivileges);
#endif
// If our process runs with elevated privileges, only add elevated Mojo
// interfaces to the BinderMap.
//
// NOTE: Do not add interfaces directly from within this method. Instead,
// modify the definition of |ExposeElevatedChromeUtilityInterfacesToBrowser()|
// to ensure security review coverage.
if (!utility_process_running_elevated_)
ExposeElevatedChromeUtilityInterfacesToBrowser(binders);
}
bool ChromeContentUtilityClient::OnMessageReceived(
const IPC::Message& message) {
if (utility_process_running_elevated_)
return false;
#if BUILDFLAG(ENABLE_PRINT_PREVIEW) && defined(OS_WIN)
if (printing_handler_->OnMessageReceived(message))
return true;
#endif
return false;
}
void ChromeContentUtilityClient::RegisterNetworkBinders(
service_manager::BinderRegistry* registry) {
if (g_network_binder_creation_callback.Get())
std::move(g_network_binder_creation_callback.Get()).Run(registry);
}
void ChromeContentUtilityClient::UtilityThreadStarted() {
// Only builds message pipes for utility processes which enable sampling
// profilers.
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
const std::string process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
if (process_type ==
switches::kUtilityProcess && // An in-process utility thread may run
// in other processes, only set up
// collector in a utility process.
ThreadProfilerConfiguration::Get()
->IsProfilerEnabledForCurrentProcess()) {
mojo::PendingRemote<metrics::mojom::CallStackProfileCollector> collector;
content::ChildThread::Get()->BindHostReceiver(
collector.InitWithNewPipeAndPassReceiver());
ThreadProfiler::SetCollectorForChildProcess(std::move(collector));
}
}
void ChromeContentUtilityClient::RegisterMainThreadServices(
mojo::ServiceFactory& services) {
if (utility_process_running_elevated_)
return ::RegisterElevatedMainThreadServices(services);
return ::RegisterMainThreadServices(services);
}
void ChromeContentUtilityClient::PostIOThreadCreated(
base::SingleThreadTaskRunner* io_thread_task_runner) {
io_thread_task_runner->PostTask(
FROM_HERE, base::BindOnce(&ThreadProfiler::StartOnChildThread,
metrics::CallStackProfileParams::IO_THREAD));
}
void ChromeContentUtilityClient::RegisterIOThreadServices(
mojo::ServiceFactory& services) {
return ::RegisterIOThreadServices(services);
}
bool ChromeContentUtilityClient::GetDefaultUserDataDirectory(
base::FilePath* path) {
return base::PathService::Get(chrome::DIR_USER_DATA, path);
}
// static
void ChromeContentUtilityClient::SetNetworkBinderCreationCallback(
NetworkBinderCreationCallback callback) {
g_network_binder_creation_callback.Get() = std::move(callback);
}