Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/browser/child_process_launcher.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 | |
| 9 #include "base/i18n/icu_util.h" | |
| 10 #include "base/logging.h" | |
| 11 #include "base/metrics/field_trial.h" | |
| 12 #include "content/browser/android/child_process_launcher_android_jni.h" | |
| 13 #include "content/browser/child_process_launcher_posix.h" | |
| 14 #include "content/browser/file_descriptor_info_impl.h" | |
| 15 #include "content/browser/web_contents/web_contents_impl.h" | |
| 16 #include "content/public/browser/browser_thread.h" | |
| 17 #include "content/public/browser/render_process_host.h" | |
| 18 #include "content/public/common/content_descriptors.h" | |
| 19 #include "content/public/common/content_switches.h" | |
| 20 #include "gin/v8_initializer.h" | |
| 21 | |
| 22 namespace content { | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 // Callback invoked from Java once the process has been started. | |
| 27 void ChildProcessStartedCallback( | |
| 28 ChildProcessLauncher::Helper* helper, | |
| 29 base::ProcessHandle handle, | |
| 30 int launch_result) { | |
| 31 // TODO(jcivelli): Remove this by defining better what happens on what thread | |
| 32 // in the corresponding Java code. | |
| 33 | |
| 34 // Keep the helper alive for the duration of this method. | |
| 35 scoped_refptr<ChildProcessLauncher::Helper> helper_deleter = helper; | |
| 36 // Now unref for the ref we added in LaunchProcessOnLauncherThread. | |
| 37 helper->Release(); | |
| 38 | |
| 39 if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) { | |
| 40 helper->PostLaunchOnLauncherThread( | |
| 41 base::Process(handle), nullptr, launch_result, false); | |
|
boliu
2017/01/13 19:00:55
/* post_launch_on_client_thread_called */ on false
Jay Civelli
2017/01/17 17:50:02
Done.
| |
| 42 return; | |
| 43 } | |
| 44 | |
| 45 bool on_client_thread = BrowserThread::CurrentlyOn( | |
| 46 static_cast<BrowserThread::ID>(helper->client_thread_id())); | |
| 47 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | |
| 48 base::Bind(&ChildProcessLauncher::Helper::PostLaunchOnLauncherThread, | |
| 49 helper, | |
| 50 base::Passed(base::Process(handle)), | |
| 51 nullptr, // zygote | |
| 52 launch_result, | |
| 53 on_client_thread)); | |
| 54 if (on_client_thread) { | |
| 55 helper->PostLaunchOnClientThread(base::Process(handle), | |
| 56 nullptr, // zygote | |
| 57 launch_result); | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 } // namespace | |
| 62 | |
| 63 void ChildProcessLauncher::Helper::BeforeLaunchOnClientThread() { | |
| 64 // Android only supports renderer, sandboxed utility and gpu. | |
| 65 std::string process_type = | |
| 66 command_line()->GetSwitchValueASCII(switches::kProcessType); | |
| 67 CHECK(process_type == switches::kGpuProcess || | |
| 68 process_type == switches::kRendererProcess || | |
| 69 #if BUILDFLAG(ENABLE_PLUGINS) | |
| 70 process_type == switches::kPpapiPluginProcess || | |
| 71 #endif | |
| 72 process_type == switches::kUtilityProcess) | |
| 73 << "Unsupported process type: " << process_type; | |
| 74 | |
| 75 // Non-sandboxed utility or renderer process are currently not supported. | |
| 76 DCHECK(process_type == switches::kGpuProcess || | |
| 77 !command_line()->HasSwitch(switches::kNoSandbox)); | |
| 78 } | |
| 79 | |
| 80 mojo::edk::ScopedPlatformHandle | |
| 81 ChildProcessLauncher::Helper::PrepareMojoPipeHandlesOnClientThread() { | |
| 82 return mojo::edk::ScopedPlatformHandle(); | |
| 83 } | |
| 84 | |
| 85 std::unique_ptr<FileDescriptorInfo> | |
| 86 ChildProcessLauncher::Helper::GetFilesToMap() { | |
| 87 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | |
| 88 | |
| 89 // Android WebView runs in single process, ensure that we never get here when | |
| 90 // running in single process mode. | |
| 91 CHECK(!command_line()->HasSwitch(switches::kSingleProcess)); | |
| 92 | |
| 93 std::unique_ptr<FileDescriptorInfo> files_to_register = | |
| 94 CreateDefaultPosixFilesToMap(*command_line(), child_process_id(), | |
| 95 mojo_client_handle()); | |
| 96 | |
| 97 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) | |
| 98 base::MemoryMappedFile::Region region; | |
| 99 auto maybe_register = [®ion, &files_to_register](int key, int fd) { | |
| 100 if (fd != -1) | |
| 101 files_to_register->ShareWithRegion(key, fd, region); | |
| 102 }; | |
| 103 maybe_register( | |
| 104 kV8NativesDataDescriptor, | |
| 105 gin::V8Initializer::GetOpenNativesFileForChildProcesses(®ion)); | |
| 106 maybe_register( | |
| 107 kV8SnapshotDataDescriptor32, | |
| 108 gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(®ion, true)); | |
| 109 maybe_register( | |
| 110 kV8SnapshotDataDescriptor64, | |
| 111 gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(®ion, false)); | |
| 112 | |
| 113 command_line()->AppendSwitch(::switches::kV8NativesPassedByFD); | |
| 114 command_line()->AppendSwitch(::switches::kV8SnapshotPassedByFD); | |
| 115 #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) | |
| 116 | |
| 117 #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE | |
| 118 int fd = base::i18n::GetIcuDataFileHandle(®ion); | |
| 119 files_to_register->ShareWithRegion(kAndroidICUDataDescriptor, fd, region); | |
| 120 #endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE | |
| 121 | |
| 122 return files_to_register; | |
| 123 } | |
| 124 | |
| 125 bool ChildProcessLauncher::Helper::ShouldForkAsZygote() { | |
| 126 return false; | |
| 127 } | |
| 128 | |
| 129 ZygoteHandle ChildProcessLauncher::Helper::ForkAsZygote( | |
| 130 std::unique_ptr<FileDescriptorInfo> files_to_register, | |
| 131 base::Process* process) { | |
| 132 NOTREACHED(); | |
| 133 return nullptr; | |
| 134 } | |
| 135 | |
| 136 void ChildProcessLauncher::Helper::BeforeLaunchOnLauncherThread( | |
| 137 const FileDescriptorInfo& files_to_register, | |
| 138 base::LaunchOptions* options) { | |
| 139 } | |
| 140 | |
| 141 base::Process ChildProcessLauncher::Helper::LaunchProcessOnLauncherThread( | |
| 142 const base::LaunchOptions& options, | |
| 143 FileDescriptorInfo* files_to_register, | |
| 144 bool* is_synchronous_launch, | |
| 145 int* launch_result) { | |
| 146 *is_synchronous_launch = false; | |
| 147 | |
| 148 // Increase the current instance's ref count so it stays alive while Java is | |
| 149 // starting the process. We'll release in ChildProcessStartedCallback. | |
| 150 AddRef(); | |
| 151 | |
| 152 StartChildProcess(command_line()->argv(), | |
| 153 child_process_id(), | |
| 154 files_to_register, | |
| 155 base::Bind(&ChildProcessStartedCallback, Unretained(this))); | |
| 156 | |
| 157 return base::Process(); | |
| 158 } | |
| 159 | |
| 160 void ChildProcessLauncher::Helper::AfterLaunchOnLauncherThread( | |
| 161 const base::Process& process, | |
| 162 const base::LaunchOptions& options) { | |
| 163 } | |
| 164 | |
| 165 // static | |
| 166 bool ChildProcessLauncher::TerminateProcess( | |
| 167 const base::Process& process, int exit_code, bool wait) { | |
| 168 StopChildProcess(process.Handle()); | |
| 169 return true; | |
| 170 } | |
| 171 | |
| 172 // static | |
| 173 void ChildProcessLauncher::TerminateOnLauncherThread( | |
| 174 ZygoteHandle zygote, base::Process process) { | |
| 175 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | |
| 176 VLOG(1) << "ChromeProcess: Stopping process with handle " | |
| 177 << process.Handle(); | |
| 178 StopChildProcess(process.Handle()); | |
| 179 } | |
| 180 | |
| 181 // static | |
| 182 void ChildProcessLauncher::SetProcessBackgroundedOnLauncherThread( | |
| 183 base::Process process, bool background) { | |
| 184 SetChildProcessInForeground(process.Handle(), !background); | |
| 185 } | |
| 186 | |
| 187 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { | |
| 188 DCHECK(CalledOnValidThread()); | |
| 189 if (IsChildProcessOomProtected(process_.Handle())) { | |
| 190 termination_status_ = base::TERMINATION_STATUS_OOM_PROTECTED; | |
| 191 } else { | |
| 192 termination_status_ = | |
| 193 base::GetTerminationStatus(process_.Handle(), &exit_code_); | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 } // namespace content | |
| OLD | NEW |