Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: content/browser/child_process_launcher.cc

Issue 1748973003: Revert of Bootstrap Mojo IPC independent of Chrome IPC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/child_process_launcher.h ('k') | content/browser/mojo/mojo_shell_client_host.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/child_process_launcher.h" 5 #include "content/browser/child_process_launcher.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/i18n/icu_util.h" 12 #include "base/i18n/icu_util.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/process/launch.h" 16 #include "base/process/launch.h"
17 #include "base/process/process.h" 17 #include "base/process/process.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/synchronization/lock.h" 19 #include "base/synchronization/lock.h"
20 #include "base/threading/thread.h" 20 #include "base/threading/thread.h"
21 #include "build/build_config.h" 21 #include "build/build_config.h"
22 #include "content/public/browser/content_browser_client.h" 22 #include "content/public/browser/content_browser_client.h"
23 #include "content/public/common/content_descriptors.h" 23 #include "content/public/common/content_descriptors.h"
24 #include "content/public/common/content_switches.h" 24 #include "content/public/common/content_switches.h"
25 #include "content/public/common/result_codes.h" 25 #include "content/public/common/result_codes.h"
26 #include "content/public/common/sandboxed_process_launcher_delegate.h" 26 #include "content/public/common/sandboxed_process_launcher_delegate.h"
27 #include "mojo/edk/embedder/embedder.h"
28 #include "mojo/edk/embedder/scoped_platform_handle.h"
29 27
30 #if defined(OS_WIN) 28 #if defined(OS_WIN)
31 #include "base/files/file_path.h" 29 #include "base/files/file_path.h"
32 #include "base/win/scoped_handle.h"
33 #include "base/win/win_util.h"
34 #include "content/common/sandbox_win.h" 30 #include "content/common/sandbox_win.h"
35 #include "content/public/common/sandbox_init.h" 31 #include "content/public/common/sandbox_init.h"
36 #elif defined(OS_MACOSX) 32 #elif defined(OS_MACOSX)
37 #include "content/browser/bootstrap_sandbox_manager_mac.h" 33 #include "content/browser/bootstrap_sandbox_manager_mac.h"
38 #include "content/browser/mach_broker_mac.h" 34 #include "content/browser/mach_broker_mac.h"
39 #include "sandbox/mac/bootstrap_sandbox.h" 35 #include "sandbox/mac/bootstrap_sandbox.h"
40 #include "sandbox/mac/pre_exec_delegate.h" 36 #include "sandbox/mac/pre_exec_delegate.h"
41 #elif defined(OS_ANDROID) 37 #elif defined(OS_ANDROID)
42 #include "base/android/jni_android.h" 38 #include "base/android/jni_android.h"
43 #include "content/browser/android/child_process_launcher_android.h" 39 #include "content/browser/android/child_process_launcher_android.h"
(...skipping 12 matching lines...) Expand all
56 #include "gin/v8_initializer.h" 52 #include "gin/v8_initializer.h"
57 #endif 53 #endif
58 54
59 namespace content { 55 namespace content {
60 56
61 namespace { 57 namespace {
62 58
63 typedef base::Callback<void(ZygoteHandle, 59 typedef base::Callback<void(ZygoteHandle,
64 #if defined(OS_ANDROID) 60 #if defined(OS_ANDROID)
65 base::ScopedFD, 61 base::ScopedFD,
66 base::ScopedFD,
67 #endif 62 #endif
68 base::Process)> NotifyCallback; 63 base::Process)> NotifyCallback;
69 64
70 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) { 65 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) {
71 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 66 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
72 // Log the launch time, separating out the first one (which will likely be 67 // Log the launch time, separating out the first one (which will likely be
73 // slower due to the rest of the browser initializing at the same time). 68 // slower due to the rest of the browser initializing at the same time).
74 static bool done_first_launch = false; 69 static bool done_first_launch = false;
75 if (done_first_launch) { 70 if (done_first_launch) {
76 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time); 71 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time);
77 } else { 72 } else {
78 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time); 73 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time);
79 done_first_launch = true; 74 done_first_launch = true;
80 } 75 }
81 } 76 }
82 77
83 #if defined(OS_ANDROID) 78 #if defined(OS_ANDROID)
84 // TODO(sievers): Remove this by defining better what happens on what 79 // TODO(sievers): Remove this by defining better what happens on what
85 // thread in the corresponding Java code. 80 // thread in the corresponding Java code.
86 void OnChildProcessStartedAndroid(const NotifyCallback& callback, 81 void OnChildProcessStartedAndroid(const NotifyCallback& callback,
87 BrowserThread::ID client_thread_id, 82 BrowserThread::ID client_thread_id,
88 const base::TimeTicks begin_launch_time, 83 const base::TimeTicks begin_launch_time,
89 base::ScopedFD ipcfd, 84 base::ScopedFD ipcfd,
90 base::ScopedFD mojo_fd,
91 base::ProcessHandle handle) { 85 base::ProcessHandle handle) {
92 // This can be called on the launcher thread or UI thread. 86 // This can be called on the launcher thread or UI thread.
93 base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time; 87 base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time;
94 BrowserThread::PostTask( 88 BrowserThread::PostTask(
95 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 89 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
96 base::Bind(&RecordHistogramsOnLauncherThread, launch_time)); 90 base::Bind(&RecordHistogramsOnLauncherThread, launch_time));
97 91
98 base::Closure callback_on_client_thread( 92 base::Closure callback_on_client_thread(
99 base::Bind(callback, nullptr, base::Passed(&ipcfd), 93 base::Bind(callback, nullptr, base::Passed(&ipcfd),
100 base::Passed(&mojo_fd), base::Passed(base::Process(handle)))); 94 base::Passed(base::Process(handle))));
101 if (BrowserThread::CurrentlyOn(client_thread_id)) { 95 if (BrowserThread::CurrentlyOn(client_thread_id)) {
102 callback_on_client_thread.Run(); 96 callback_on_client_thread.Run();
103 } else { 97 } else {
104 BrowserThread::PostTask( 98 BrowserThread::PostTask(
105 client_thread_id, FROM_HERE, callback_on_client_thread); 99 client_thread_id, FROM_HERE, callback_on_client_thread);
106 } 100 }
107 } 101 }
108 #endif 102 #endif
109 103
110 void LaunchOnLauncherThread(const NotifyCallback& callback, 104 void LaunchOnLauncherThread(const NotifyCallback& callback,
111 BrowserThread::ID client_thread_id, 105 BrowserThread::ID client_thread_id,
112 int child_process_id, 106 int child_process_id,
113 SandboxedProcessLauncherDelegate* delegate, 107 SandboxedProcessLauncherDelegate* delegate,
114 #if defined(OS_ANDROID) 108 #if defined(OS_ANDROID)
115 base::ScopedFD ipcfd, 109 base::ScopedFD ipcfd,
116 #endif 110 #endif
117 mojo::edk::ScopedPlatformHandle client_handle,
118 base::CommandLine* cmd_line) { 111 base::CommandLine* cmd_line) {
119 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 112 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
120 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); 113 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate);
121 #if !defined(OS_ANDROID) 114 #if !defined(OS_ANDROID)
122 ZygoteHandle zygote = nullptr; 115 ZygoteHandle zygote = nullptr;
123 #endif 116 #endif
124 #if defined(OS_WIN) 117 #if defined(OS_WIN)
125 bool launch_elevated = delegate->ShouldLaunchElevated(); 118 bool launch_elevated = delegate->ShouldLaunchElevated();
126 #elif defined(OS_MACOSX) 119 #elif defined(OS_MACOSX)
127 base::EnvironmentMap env = delegate->GetEnvironment(); 120 base::EnvironmentMap env = delegate->GetEnvironment();
128 base::ScopedFD ipcfd = delegate->TakeIpcFd(); 121 base::ScopedFD ipcfd = delegate->TakeIpcFd();
129 #elif defined(OS_POSIX) && !defined(OS_ANDROID) 122 #elif defined(OS_POSIX) && !defined(OS_ANDROID)
130 base::EnvironmentMap env = delegate->GetEnvironment(); 123 base::EnvironmentMap env = delegate->GetEnvironment();
131 base::ScopedFD ipcfd = delegate->TakeIpcFd(); 124 base::ScopedFD ipcfd = delegate->TakeIpcFd();
132 #endif 125 #endif
133 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); 126 scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line);
134 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); 127 base::TimeTicks begin_launch_time = base::TimeTicks::Now();
135 128
136 base::Process process; 129 base::Process process;
137 #if defined(OS_WIN) 130 #if defined(OS_WIN)
138 if (launch_elevated) { 131 if (launch_elevated) {
139 // TODO(rockot): We may want to support Mojo IPC to elevated processes as
140 // well, but this isn't currently feasible without sharing a pipe path on
141 // the command line as elevated process launch goes through ShellExecuteEx.
142 base::LaunchOptions options; 132 base::LaunchOptions options;
143 options.start_hidden = true; 133 options.start_hidden = true;
144 process = base::LaunchElevatedProcess(*cmd_line, options); 134 process = base::LaunchElevatedProcess(*cmd_line, options);
145 } else { 135 } else {
146 base::HandlesToInheritVector handles; 136 process = StartSandboxedProcess(
147 handles.push_back(client_handle.get().handle); 137 delegate, cmd_line, base::HandlesToInheritVector());
148 cmd_line->AppendSwitchASCII(
149 mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch,
150 base::UintToString(base::win::HandleToUint32(handles[0])));
151 process = StartSandboxedProcess(delegate, cmd_line, handles);
152 } 138 }
153 #elif defined(OS_POSIX) 139 #elif defined(OS_POSIX)
154 std::string process_type = 140 std::string process_type =
155 cmd_line->GetSwitchValueASCII(switches::kProcessType); 141 cmd_line->GetSwitchValueASCII(switches::kProcessType);
156 scoped_ptr<FileDescriptorInfo> files_to_register( 142 scoped_ptr<FileDescriptorInfo> files_to_register(
157 FileDescriptorInfoImpl::Create()); 143 FileDescriptorInfoImpl::Create());
158 144
159 base::ScopedFD mojo_fd(client_handle.release().handle);
160 DCHECK(mojo_fd.is_valid());
161
162 #if defined(OS_ANDROID) 145 #if defined(OS_ANDROID)
163 files_to_register->Share(kPrimaryIPCChannel, ipcfd.get()); 146 files_to_register->Share(kPrimaryIPCChannel, ipcfd.get());
164 files_to_register->Share(kMojoIPCChannel, mojo_fd.get());
165 #else 147 #else
166 files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd)); 148 files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd));
167 files_to_register->Transfer(kMojoIPCChannel, std::move(mojo_fd));
168 #endif 149 #endif
169 #endif 150 #endif
170 151
171 #if defined(OS_POSIX) && !defined(OS_MACOSX) 152 #if defined(OS_POSIX) && !defined(OS_MACOSX)
172 std::map<int, base::MemoryMappedFile::Region> regions; 153 std::map<int, base::MemoryMappedFile::Region> regions;
173 GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( 154 GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess(
174 *cmd_line, child_process_id, files_to_register.get() 155 *cmd_line, child_process_id, files_to_register.get()
175 #if defined(OS_ANDROID) 156 #if defined(OS_ANDROID)
176 , &regions 157 , &regions
177 #endif 158 #endif
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 kAndroidICUDataDescriptor, 216 kAndroidICUDataDescriptor,
236 base::i18n::GetIcuDataFileHandle(&regions[kAndroidICUDataDescriptor])); 217 base::i18n::GetIcuDataFileHandle(&regions[kAndroidICUDataDescriptor]));
237 218
238 // Android WebView runs in single process, ensure that we never get here 219 // Android WebView runs in single process, ensure that we never get here
239 // when running in single process mode. 220 // when running in single process mode.
240 CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); 221 CHECK(!cmd_line->HasSwitch(switches::kSingleProcess));
241 222
242 StartChildProcess( 223 StartChildProcess(
243 cmd_line->argv(), child_process_id, std::move(files_to_register), regions, 224 cmd_line->argv(), child_process_id, std::move(files_to_register), regions,
244 base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id, 225 base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id,
245 begin_launch_time, base::Passed(&ipcfd), 226 begin_launch_time, base::Passed(&ipcfd)));
246 base::Passed(&mojo_fd)));
247 227
248 #elif defined(OS_POSIX) 228 #elif defined(OS_POSIX)
249 // We need to close the client end of the IPC channel to reliably detect 229 // We need to close the client end of the IPC channel to reliably detect
250 // child termination. 230 // child termination.
251 231
252 #if !defined(OS_MACOSX) 232 #if !defined(OS_MACOSX)
253 ZygoteHandle* zygote_handle = delegate->GetZygote(); 233 ZygoteHandle* zygote_handle = delegate->GetZygote();
254 // If |zygote_handle| is null, a zygote should not be used. 234 // If |zygote_handle| is null, a zygote should not be used.
255 if (zygote_handle) { 235 if (zygote_handle) {
256 // This code runs on the PROCESS_LAUNCHER thread so race conditions are not 236 // This code runs on the PROCESS_LAUNCHER thread so race conditions are not
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 !cmd_line->HasSwitch(switches::kNoSandbox)); 416 !cmd_line->HasSwitch(switches::kNoSandbox));
437 417
438 // We need to close the client end of the IPC channel to reliably detect 418 // We need to close the client end of the IPC channel to reliably detect
439 // child termination. We will close this fd after we create the child 419 // child termination. We will close this fd after we create the child
440 // process which is asynchronous on Android. 420 // process which is asynchronous on Android.
441 base::ScopedFD ipcfd(delegate->TakeIpcFd().release()); 421 base::ScopedFD ipcfd(delegate->TakeIpcFd().release());
442 #endif 422 #endif
443 NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch, 423 NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch,
444 weak_factory_.GetWeakPtr(), 424 weak_factory_.GetWeakPtr(),
445 terminate_child_on_shutdown_)); 425 terminate_child_on_shutdown_));
446 mojo::edk::ScopedPlatformHandle client_handle =
447 mojo_platform_channel_.PassClientHandle();
448 BrowserThread::PostTask( 426 BrowserThread::PostTask(
449 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 427 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
450 base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_, 428 base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_,
451 child_process_id, delegate, 429 child_process_id, delegate,
452 #if defined(OS_ANDROID) 430 #if defined(OS_ANDROID)
453 base::Passed(&ipcfd), 431 base::Passed(&ipcfd),
454 #endif 432 #endif
455 base::Passed(&client_handle), cmd_line)); 433 cmd_line));
456 } 434 }
457 435
458 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { 436 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
459 DCHECK(CalledOnValidThread()); 437 DCHECK(CalledOnValidThread());
460 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 438 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
461 if (zygote_) { 439 if (zygote_) {
462 termination_status_ = zygote_->GetTerminationStatus( 440 termination_status_ = zygote_->GetTerminationStatus(
463 process_.Handle(), known_dead, &exit_code_); 441 process_.Handle(), known_dead, &exit_code_);
464 } else if (known_dead) { 442 } else if (known_dead) {
465 termination_status_ = 443 termination_status_ =
(...skipping 23 matching lines...) Expand all
489 base::Bind(&SetProcessBackgroundedOnLauncherThread, 467 base::Bind(&SetProcessBackgroundedOnLauncherThread,
490 base::Passed(&to_pass), background)); 468 base::Passed(&to_pass), background));
491 } 469 }
492 470
493 void ChildProcessLauncher::DidLaunch( 471 void ChildProcessLauncher::DidLaunch(
494 base::WeakPtr<ChildProcessLauncher> instance, 472 base::WeakPtr<ChildProcessLauncher> instance,
495 bool terminate_on_shutdown, 473 bool terminate_on_shutdown,
496 ZygoteHandle zygote, 474 ZygoteHandle zygote,
497 #if defined(OS_ANDROID) 475 #if defined(OS_ANDROID)
498 base::ScopedFD ipcfd, 476 base::ScopedFD ipcfd,
499 base::ScopedFD mojo_fd,
500 #endif 477 #endif
501 base::Process process) { 478 base::Process process) {
502 if (!process.IsValid()) 479 if (!process.IsValid())
503 LOG(ERROR) << "Failed to launch child process"; 480 LOG(ERROR) << "Failed to launch child process";
504 481
505 if (instance.get()) { 482 if (instance.get()) {
506 instance->Notify(zygote, 483 instance->Notify(zygote,
507 #if defined(OS_ANDROID) 484 #if defined(OS_ANDROID)
508 std::move(ipcfd), 485 std::move(ipcfd),
509 #endif 486 #endif
(...skipping 11 matching lines...) Expand all
521 498
522 void ChildProcessLauncher::Notify(ZygoteHandle zygote, 499 void ChildProcessLauncher::Notify(ZygoteHandle zygote,
523 #if defined(OS_ANDROID) 500 #if defined(OS_ANDROID)
524 base::ScopedFD ipcfd, 501 base::ScopedFD ipcfd,
525 #endif 502 #endif
526 base::Process process) { 503 base::Process process) {
527 DCHECK(CalledOnValidThread()); 504 DCHECK(CalledOnValidThread());
528 starting_ = false; 505 starting_ = false;
529 process_ = std::move(process); 506 process_ = std::move(process);
530 507
531 if (process_.IsValid()) {
532 // Set up Mojo IPC to the new process.
533 mojo::edk::ChildProcessLaunched(process_.Handle(),
534 mojo_platform_channel_.PassServerHandle());
535 }
536
537 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 508 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
538 zygote_ = zygote; 509 zygote_ = zygote;
539 #endif 510 #endif
540 if (process_.IsValid()) { 511 if (process_.IsValid()) {
541 client_->OnProcessLaunched(); 512 client_->OnProcessLaunched();
542 } else { 513 } else {
543 termination_status_ = base::TERMINATION_STATUS_LAUNCH_FAILED; 514 termination_status_ = base::TERMINATION_STATUS_LAUNCH_FAILED;
544 client_->OnProcessLaunchFailed(); 515 client_->OnProcessLaunchFailed();
545 } 516 }
546 } 517 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 } 556 }
586 557
587 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest( 558 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest(
588 Client* client) { 559 Client* client) {
589 Client* ret = client_; 560 Client* ret = client_;
590 client_ = client; 561 client_ = client;
591 return ret; 562 return ret;
592 } 563 }
593 564
594 } // namespace content 565 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_launcher.h ('k') | content/browser/mojo/mojo_shell_client_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698