| OLD | NEW | 
|---|
| 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" | 
| 27 | 29 | 
| 28 #if defined(OS_WIN) | 30 #if defined(OS_WIN) | 
| 29 #include "base/files/file_path.h" | 31 #include "base/files/file_path.h" | 
|  | 32 #include "base/win/scoped_handle.h" | 
|  | 33 #include "base/win/win_util.h" | 
| 30 #include "content/common/sandbox_win.h" | 34 #include "content/common/sandbox_win.h" | 
| 31 #include "content/public/common/sandbox_init.h" | 35 #include "content/public/common/sandbox_init.h" | 
| 32 #elif defined(OS_MACOSX) | 36 #elif defined(OS_MACOSX) | 
| 33 #include "content/browser/bootstrap_sandbox_manager_mac.h" | 37 #include "content/browser/bootstrap_sandbox_manager_mac.h" | 
| 34 #include "content/browser/mach_broker_mac.h" | 38 #include "content/browser/mach_broker_mac.h" | 
| 35 #include "sandbox/mac/bootstrap_sandbox.h" | 39 #include "sandbox/mac/bootstrap_sandbox.h" | 
| 36 #include "sandbox/mac/pre_exec_delegate.h" | 40 #include "sandbox/mac/pre_exec_delegate.h" | 
| 37 #elif defined(OS_ANDROID) | 41 #elif defined(OS_ANDROID) | 
| 38 #include "base/android/jni_android.h" | 42 #include "base/android/jni_android.h" | 
| 39 #include "content/browser/android/child_process_launcher_android.h" | 43 #include "content/browser/android/child_process_launcher_android.h" | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 52 #include "gin/v8_initializer.h" | 56 #include "gin/v8_initializer.h" | 
| 53 #endif | 57 #endif | 
| 54 | 58 | 
| 55 namespace content { | 59 namespace content { | 
| 56 | 60 | 
| 57 namespace { | 61 namespace { | 
| 58 | 62 | 
| 59 typedef base::Callback<void(ZygoteHandle, | 63 typedef base::Callback<void(ZygoteHandle, | 
| 60 #if defined(OS_ANDROID) | 64 #if defined(OS_ANDROID) | 
| 61                             base::ScopedFD, | 65                             base::ScopedFD, | 
|  | 66                             base::ScopedFD, | 
| 62 #endif | 67 #endif | 
| 63                             base::Process)> NotifyCallback; | 68                             base::Process)> NotifyCallback; | 
| 64 | 69 | 
| 65 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) { | 70 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) { | 
| 66   DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | 71   DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | 
| 67   // Log the launch time, separating out the first one (which will likely be | 72   // Log the launch time, separating out the first one (which will likely be | 
| 68   // slower due to the rest of the browser initializing at the same time). | 73   // slower due to the rest of the browser initializing at the same time). | 
| 69   static bool done_first_launch = false; | 74   static bool done_first_launch = false; | 
| 70   if (done_first_launch) { | 75   if (done_first_launch) { | 
| 71     UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time); | 76     UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time); | 
| 72   } else { | 77   } else { | 
| 73     UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time); | 78     UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time); | 
| 74     done_first_launch = true; | 79     done_first_launch = true; | 
| 75   } | 80   } | 
| 76 } | 81 } | 
| 77 | 82 | 
| 78 #if defined(OS_ANDROID) | 83 #if defined(OS_ANDROID) | 
| 79 // TODO(sievers): Remove this by defining better what happens on what | 84 // TODO(sievers): Remove this by defining better what happens on what | 
| 80 // thread in the corresponding Java code. | 85 // thread in the corresponding Java code. | 
| 81 void OnChildProcessStartedAndroid(const NotifyCallback& callback, | 86 void OnChildProcessStartedAndroid(const NotifyCallback& callback, | 
| 82                                   BrowserThread::ID client_thread_id, | 87                                   BrowserThread::ID client_thread_id, | 
| 83                                   const base::TimeTicks begin_launch_time, | 88                                   const base::TimeTicks begin_launch_time, | 
| 84                                   base::ScopedFD ipcfd, | 89                                   base::ScopedFD ipcfd, | 
|  | 90                                   base::ScopedFD mojo_fd, | 
| 85                                   base::ProcessHandle handle) { | 91                                   base::ProcessHandle handle) { | 
| 86   // This can be called on the launcher thread or UI thread. | 92   // This can be called on the launcher thread or UI thread. | 
| 87   base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time; | 93   base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time; | 
| 88   BrowserThread::PostTask( | 94   BrowserThread::PostTask( | 
| 89       BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 95       BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 
| 90       base::Bind(&RecordHistogramsOnLauncherThread, launch_time)); | 96       base::Bind(&RecordHistogramsOnLauncherThread, launch_time)); | 
| 91 | 97 | 
| 92   base::Closure callback_on_client_thread( | 98   base::Closure callback_on_client_thread( | 
| 93       base::Bind(callback, nullptr, base::Passed(&ipcfd), | 99       base::Bind(callback, nullptr, base::Passed(&ipcfd), | 
| 94                  base::Passed(base::Process(handle)))); | 100                  base::Passed(&mojo_fd), base::Passed(base::Process(handle)))); | 
| 95   if (BrowserThread::CurrentlyOn(client_thread_id)) { | 101   if (BrowserThread::CurrentlyOn(client_thread_id)) { | 
| 96     callback_on_client_thread.Run(); | 102     callback_on_client_thread.Run(); | 
| 97   } else { | 103   } else { | 
| 98     BrowserThread::PostTask( | 104     BrowserThread::PostTask( | 
| 99         client_thread_id, FROM_HERE, callback_on_client_thread); | 105         client_thread_id, FROM_HERE, callback_on_client_thread); | 
| 100   } | 106   } | 
| 101 } | 107 } | 
| 102 #endif | 108 #endif | 
| 103 | 109 | 
| 104 void LaunchOnLauncherThread(const NotifyCallback& callback, | 110 void LaunchOnLauncherThread(const NotifyCallback& callback, | 
| 105                             BrowserThread::ID client_thread_id, | 111                             BrowserThread::ID client_thread_id, | 
| 106                             int child_process_id, | 112                             int child_process_id, | 
| 107                             SandboxedProcessLauncherDelegate* delegate, | 113                             SandboxedProcessLauncherDelegate* delegate, | 
| 108 #if defined(OS_ANDROID) | 114 #if defined(OS_ANDROID) | 
| 109                             base::ScopedFD ipcfd, | 115                             base::ScopedFD ipcfd, | 
| 110 #endif | 116 #endif | 
|  | 117                             mojo::edk::ScopedPlatformHandle client_handle, | 
| 111                             base::CommandLine* cmd_line) { | 118                             base::CommandLine* cmd_line) { | 
| 112   DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | 119   DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | 
| 113   scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); | 120   scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); | 
| 114 #if !defined(OS_ANDROID) | 121 #if !defined(OS_ANDROID) | 
| 115   ZygoteHandle zygote = nullptr; | 122   ZygoteHandle zygote = nullptr; | 
| 116 #endif | 123 #endif | 
| 117 #if defined(OS_WIN) | 124 #if defined(OS_WIN) | 
| 118   bool launch_elevated = delegate->ShouldLaunchElevated(); | 125   bool launch_elevated = delegate->ShouldLaunchElevated(); | 
| 119 #elif defined(OS_MACOSX) | 126 #elif defined(OS_MACOSX) | 
| 120   base::EnvironmentMap env = delegate->GetEnvironment(); | 127   base::EnvironmentMap env = delegate->GetEnvironment(); | 
| 121   base::ScopedFD ipcfd = delegate->TakeIpcFd(); | 128   base::ScopedFD ipcfd = delegate->TakeIpcFd(); | 
| 122 #elif defined(OS_POSIX) && !defined(OS_ANDROID) | 129 #elif defined(OS_POSIX) && !defined(OS_ANDROID) | 
| 123   base::EnvironmentMap env = delegate->GetEnvironment(); | 130   base::EnvironmentMap env = delegate->GetEnvironment(); | 
| 124   base::ScopedFD ipcfd = delegate->TakeIpcFd(); | 131   base::ScopedFD ipcfd = delegate->TakeIpcFd(); | 
| 125 #endif | 132 #endif | 
| 126   scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); | 133   scoped_ptr<base::CommandLine> cmd_line_deleter(cmd_line); | 
| 127   base::TimeTicks begin_launch_time = base::TimeTicks::Now(); | 134   base::TimeTicks begin_launch_time = base::TimeTicks::Now(); | 
| 128 | 135 | 
| 129   base::Process process; | 136   base::Process process; | 
| 130 #if defined(OS_WIN) | 137 #if defined(OS_WIN) | 
| 131   if (launch_elevated) { | 138   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. | 
| 132     base::LaunchOptions options; | 142     base::LaunchOptions options; | 
| 133     options.start_hidden = true; | 143     options.start_hidden = true; | 
| 134     process = base::LaunchElevatedProcess(*cmd_line, options); | 144     process = base::LaunchElevatedProcess(*cmd_line, options); | 
| 135   } else { | 145   } else { | 
| 136     process = StartSandboxedProcess( | 146     base::HandlesToInheritVector handles; | 
| 137         delegate, cmd_line, base::HandlesToInheritVector()); | 147     handles.push_back(client_handle.get().handle); | 
|  | 148     cmd_line->AppendSwitchASCII( | 
|  | 149         mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch, | 
|  | 150         base::UintToString(base::win::HandleToUint32(handles[0]))); | 
|  | 151     process = StartSandboxedProcess(delegate, cmd_line, handles); | 
| 138   } | 152   } | 
| 139 #elif defined(OS_POSIX) | 153 #elif defined(OS_POSIX) | 
| 140   std::string process_type = | 154   std::string process_type = | 
| 141       cmd_line->GetSwitchValueASCII(switches::kProcessType); | 155       cmd_line->GetSwitchValueASCII(switches::kProcessType); | 
| 142   scoped_ptr<FileDescriptorInfo> files_to_register( | 156   scoped_ptr<FileDescriptorInfo> files_to_register( | 
| 143       FileDescriptorInfoImpl::Create()); | 157       FileDescriptorInfoImpl::Create()); | 
| 144 | 158 | 
|  | 159   base::ScopedFD mojo_fd(client_handle.release().handle); | 
|  | 160   DCHECK(mojo_fd.is_valid()); | 
|  | 161 | 
| 145 #if defined(OS_ANDROID) | 162 #if defined(OS_ANDROID) | 
| 146   files_to_register->Share(kPrimaryIPCChannel, ipcfd.get()); | 163   files_to_register->Share(kPrimaryIPCChannel, ipcfd.get()); | 
|  | 164   files_to_register->Share(kMojoIPCChannel, mojo_fd.get()); | 
| 147 #else | 165 #else | 
| 148   files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd)); | 166   files_to_register->Transfer(kPrimaryIPCChannel, std::move(ipcfd)); | 
|  | 167   files_to_register->Transfer(kMojoIPCChannel, std::move(mojo_fd)); | 
| 149 #endif | 168 #endif | 
| 150 #endif | 169 #endif | 
| 151 | 170 | 
| 152 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 171 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 
| 153   std::map<int, base::MemoryMappedFile::Region> regions; | 172   std::map<int, base::MemoryMappedFile::Region> regions; | 
| 154   GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( | 173   GetContentClient()->browser()->GetAdditionalMappedFilesForChildProcess( | 
| 155       *cmd_line, child_process_id, files_to_register.get() | 174       *cmd_line, child_process_id, files_to_register.get() | 
| 156 #if defined(OS_ANDROID) | 175 #if defined(OS_ANDROID) | 
| 157       , ®ions | 176       , ®ions | 
| 158 #endif | 177 #endif | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 216       kAndroidICUDataDescriptor, | 235       kAndroidICUDataDescriptor, | 
| 217       base::i18n::GetIcuDataFileHandle(®ions[kAndroidICUDataDescriptor])); | 236       base::i18n::GetIcuDataFileHandle(®ions[kAndroidICUDataDescriptor])); | 
| 218 | 237 | 
| 219   // Android WebView runs in single process, ensure that we never get here | 238   // Android WebView runs in single process, ensure that we never get here | 
| 220   // when running in single process mode. | 239   // when running in single process mode. | 
| 221   CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); | 240   CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); | 
| 222 | 241 | 
| 223   StartChildProcess( | 242   StartChildProcess( | 
| 224       cmd_line->argv(), child_process_id, std::move(files_to_register), regions, | 243       cmd_line->argv(), child_process_id, std::move(files_to_register), regions, | 
| 225       base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id, | 244       base::Bind(&OnChildProcessStartedAndroid, callback, client_thread_id, | 
| 226                  begin_launch_time, base::Passed(&ipcfd))); | 245                  begin_launch_time, base::Passed(&ipcfd), | 
|  | 246                  base::Passed(&mojo_fd))); | 
| 227 | 247 | 
| 228 #elif defined(OS_POSIX) | 248 #elif defined(OS_POSIX) | 
| 229   // We need to close the client end of the IPC channel to reliably detect | 249   // We need to close the client end of the IPC channel to reliably detect | 
| 230   // child termination. | 250   // child termination. | 
| 231 | 251 | 
| 232 #if !defined(OS_MACOSX) | 252 #if !defined(OS_MACOSX) | 
| 233   ZygoteHandle* zygote_handle = delegate->GetZygote(); | 253   ZygoteHandle* zygote_handle = delegate->GetZygote(); | 
| 234   // If |zygote_handle| is null, a zygote should not be used. | 254   // If |zygote_handle| is null, a zygote should not be used. | 
| 235   if (zygote_handle) { | 255   if (zygote_handle) { | 
| 236     // This code runs on the PROCESS_LAUNCHER thread so race conditions are not | 256     // 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  Loading... | 
| 416          !cmd_line->HasSwitch(switches::kNoSandbox)); | 436          !cmd_line->HasSwitch(switches::kNoSandbox)); | 
| 417 | 437 | 
| 418   // We need to close the client end of the IPC channel to reliably detect | 438   // We need to close the client end of the IPC channel to reliably detect | 
| 419   // child termination. We will close this fd after we create the child | 439   // child termination. We will close this fd after we create the child | 
| 420   // process which is asynchronous on Android. | 440   // process which is asynchronous on Android. | 
| 421   base::ScopedFD ipcfd(delegate->TakeIpcFd().release()); | 441   base::ScopedFD ipcfd(delegate->TakeIpcFd().release()); | 
| 422 #endif | 442 #endif | 
| 423   NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch, | 443   NotifyCallback reply_callback(base::Bind(&ChildProcessLauncher::DidLaunch, | 
| 424                                            weak_factory_.GetWeakPtr(), | 444                                            weak_factory_.GetWeakPtr(), | 
| 425                                            terminate_child_on_shutdown_)); | 445                                            terminate_child_on_shutdown_)); | 
|  | 446   mojo::edk::ScopedPlatformHandle client_handle = | 
|  | 447       mojo_platform_channel_.PassClientHandle(); | 
| 426   BrowserThread::PostTask( | 448   BrowserThread::PostTask( | 
| 427       BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 449       BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 
| 428       base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_, | 450       base::Bind(&LaunchOnLauncherThread, reply_callback, client_thread_id_, | 
| 429                  child_process_id, delegate, | 451                  child_process_id, delegate, | 
| 430 #if defined(OS_ANDROID) | 452 #if defined(OS_ANDROID) | 
| 431                  base::Passed(&ipcfd), | 453                  base::Passed(&ipcfd), | 
| 432 #endif | 454 #endif | 
| 433                  cmd_line)); | 455                  base::Passed(&client_handle), cmd_line)); | 
| 434 } | 456 } | 
| 435 | 457 | 
| 436 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { | 458 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { | 
| 437   DCHECK(CalledOnValidThread()); | 459   DCHECK(CalledOnValidThread()); | 
| 438 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 460 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 
| 439   if (zygote_) { | 461   if (zygote_) { | 
| 440     termination_status_ = zygote_->GetTerminationStatus( | 462     termination_status_ = zygote_->GetTerminationStatus( | 
| 441         process_.Handle(), known_dead, &exit_code_); | 463         process_.Handle(), known_dead, &exit_code_); | 
| 442   } else if (known_dead) { | 464   } else if (known_dead) { | 
| 443     termination_status_ = | 465     termination_status_ = | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 467                           base::Bind(&SetProcessBackgroundedOnLauncherThread, | 489                           base::Bind(&SetProcessBackgroundedOnLauncherThread, | 
| 468                                      base::Passed(&to_pass), background)); | 490                                      base::Passed(&to_pass), background)); | 
| 469 } | 491 } | 
| 470 | 492 | 
| 471 void ChildProcessLauncher::DidLaunch( | 493 void ChildProcessLauncher::DidLaunch( | 
| 472     base::WeakPtr<ChildProcessLauncher> instance, | 494     base::WeakPtr<ChildProcessLauncher> instance, | 
| 473     bool terminate_on_shutdown, | 495     bool terminate_on_shutdown, | 
| 474     ZygoteHandle zygote, | 496     ZygoteHandle zygote, | 
| 475 #if defined(OS_ANDROID) | 497 #if defined(OS_ANDROID) | 
| 476     base::ScopedFD ipcfd, | 498     base::ScopedFD ipcfd, | 
|  | 499     base::ScopedFD mojo_fd, | 
| 477 #endif | 500 #endif | 
| 478     base::Process process) { | 501     base::Process process) { | 
| 479   if (!process.IsValid()) | 502   if (!process.IsValid()) | 
| 480     LOG(ERROR) << "Failed to launch child process"; | 503     LOG(ERROR) << "Failed to launch child process"; | 
| 481 | 504 | 
| 482   if (instance.get()) { | 505   if (instance.get()) { | 
| 483     instance->Notify(zygote, | 506     instance->Notify(zygote, | 
| 484 #if defined(OS_ANDROID) | 507 #if defined(OS_ANDROID) | 
| 485                      std::move(ipcfd), | 508                      std::move(ipcfd), | 
| 486 #endif | 509 #endif | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 498 | 521 | 
| 499 void ChildProcessLauncher::Notify(ZygoteHandle zygote, | 522 void ChildProcessLauncher::Notify(ZygoteHandle zygote, | 
| 500 #if defined(OS_ANDROID) | 523 #if defined(OS_ANDROID) | 
| 501                                   base::ScopedFD ipcfd, | 524                                   base::ScopedFD ipcfd, | 
| 502 #endif | 525 #endif | 
| 503                                   base::Process process) { | 526                                   base::Process process) { | 
| 504   DCHECK(CalledOnValidThread()); | 527   DCHECK(CalledOnValidThread()); | 
| 505   starting_ = false; | 528   starting_ = false; | 
| 506   process_ = std::move(process); | 529   process_ = std::move(process); | 
| 507 | 530 | 
|  | 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 | 
| 508 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 537 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 
| 509   zygote_ = zygote; | 538   zygote_ = zygote; | 
| 510 #endif | 539 #endif | 
| 511   if (process_.IsValid()) { | 540   if (process_.IsValid()) { | 
| 512     client_->OnProcessLaunched(); | 541     client_->OnProcessLaunched(); | 
| 513   } else { | 542   } else { | 
| 514     termination_status_ = base::TERMINATION_STATUS_LAUNCH_FAILED; | 543     termination_status_ = base::TERMINATION_STATUS_LAUNCH_FAILED; | 
| 515     client_->OnProcessLaunchFailed(); | 544     client_->OnProcessLaunchFailed(); | 
| 516   } | 545   } | 
| 517 } | 546 } | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 556 } | 585 } | 
| 557 | 586 | 
| 558 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest( | 587 ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest( | 
| 559     Client* client) { | 588     Client* client) { | 
| 560   Client* ret = client_; | 589   Client* ret = client_; | 
| 561   client_ = client; | 590   client_ = client; | 
| 562   return ret; | 591   return ret; | 
| 563 } | 592 } | 
| 564 | 593 | 
| 565 }  // namespace content | 594 }  // namespace content | 
| OLD | NEW | 
|---|