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 if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) { | |
| 34 helper->PostLaunchOnLauncherThread( | |
| 35 base::Process(handle), nullptr, launch_result, false); | |
| 36 return; | |
| 37 } | |
| 38 | |
| 39 bool on_client_thread = BrowserThread::CurrentlyOn( | |
| 40 static_cast<BrowserThread::ID>(helper->client_thread_id())); | |
| 41 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | |
| 42 base::Bind(&ChildProcessLauncher::Helper::PostLaunchOnLauncherThread, | |
| 43 helper, | |
| 44 base::Passed(base::Process(handle)), | |
| 45 nullptr, // zygote | |
| 46 launch_result, | |
| 47 on_client_thread)); | |
| 48 if (on_client_thread) { | |
| 49 helper->PostLaunchOnClientThread(base::Process(handle), | |
| 50 nullptr, // zygote | |
| 51 launch_result); | |
| 52 } | |
| 53 } | |
| 54 | |
| 55 } // namespace | |
| 56 | |
| 57 void ChildProcessLauncher::Helper::BeforeLaunchOnClientThread() { | |
| 58 // Android only supports renderer, sandboxed utility and gpu. | |
| 59 std::string process_type = | |
| 60 command_line()->GetSwitchValueASCII(switches::kProcessType); | |
| 61 CHECK(process_type == switches::kGpuProcess || | |
| 62 process_type == switches::kRendererProcess || | |
| 63 #if BUILDFLAG(ENABLE_PLUGINS) | |
| 64 process_type == switches::kPpapiPluginProcess || | |
| 65 #endif | |
| 66 process_type == switches::kUtilityProcess) | |
| 67 << "Unsupported process type: " << process_type; | |
| 68 | |
| 69 // Non-sandboxed utility or renderer process are currently not supported. | |
| 70 DCHECK(process_type == switches::kGpuProcess || | |
| 71 !command_line()->HasSwitch(switches::kNoSandbox)); | |
| 72 } | |
| 73 | |
| 74 mojo::edk::ScopedPlatformHandle | |
| 75 ChildProcessLauncher::Helper::PrepareMojoPipeHandlesOnClientThread() { | |
| 76 return mojo::edk::ScopedPlatformHandle(); | |
| 77 } | |
| 78 | |
| 79 std::unique_ptr<FileDescriptorInfo> | |
| 80 ChildProcessLauncher::Helper::GetFilesToMap() { | |
| 81 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | |
| 82 | |
| 83 // Android WebView runs in single process, ensure that we never get here when | |
| 84 // running in single process mode. | |
| 85 CHECK(!command_line()->HasSwitch(switches::kSingleProcess)); | |
| 86 | |
| 87 std::unique_ptr<FileDescriptorInfo> files_to_register = | |
| 88 CreateDefaultPosixFilesToMap(*command_line(), child_process_id(), | |
| 89 mojo_client_handle()); | |
| 90 | |
| 91 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) | |
| 92 base::MemoryMappedFile::Region region; | |
| 93 auto maybe_register = [®ion, &files_to_register](int key, int fd) { | |
| 94 if (fd != -1) | |
| 95 files_to_register->ShareWithRegion(key, fd, region); | |
| 96 }; | |
| 97 maybe_register( | |
| 98 kV8NativesDataDescriptor, | |
| 99 gin::V8Initializer::GetOpenNativesFileForChildProcesses(®ion)); | |
| 100 maybe_register( | |
| 101 kV8SnapshotDataDescriptor32, | |
| 102 gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(®ion, true)); | |
| 103 maybe_register( | |
| 104 kV8SnapshotDataDescriptor64, | |
| 105 gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(®ion, false)); | |
| 106 | |
| 107 command_line()->AppendSwitch(::switches::kV8NativesPassedByFD); | |
| 108 command_line()->AppendSwitch(::switches::kV8SnapshotPassedByFD); | |
| 109 #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) | |
| 110 | |
| 111 #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE | |
| 112 int fd = base::i18n::GetIcuDataFileHandle(®ion); | |
| 113 files_to_register->ShareWithRegion(kAndroidICUDataDescriptor, fd, region); | |
| 114 #endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE | |
| 115 | |
| 116 return files_to_register; | |
| 117 } | |
| 118 | |
| 119 bool ChildProcessLauncher::Helper::ShouldForkAsZygote() { | |
| 120 return false; | |
| 121 } | |
| 122 | |
| 123 ZygoteHandle ChildProcessLauncher::Helper::ForkAsZygote( | |
| 124 std::unique_ptr<FileDescriptorInfo> files_to_register, | |
| 125 base::Process* process) { | |
| 126 NOTREACHED(); | |
| 127 return nullptr; | |
| 128 } | |
| 129 | |
| 130 void ChildProcessLauncher::Helper::BeforeLaunchOnLauncherThread( | |
| 131 const FileDescriptorInfo& files_to_register, | |
| 132 base::LaunchOptions* options) { | |
| 133 } | |
| 134 | |
| 135 base::Process ChildProcessLauncher::Helper::LaunchProcessOnLauncherThread( | |
| 136 const base::LaunchOptions& options, | |
| 137 FileDescriptorInfo* files_to_register, | |
| 138 bool* is_synchronous_launch, | |
| 139 int* launch_result) { | |
| 140 *is_synchronous_launch = false; | |
| 141 | |
| 142 StartChildProcess(command_line()->argv(), | |
| 143 child_process_id(), | |
| 144 files_to_register, | |
| 145 base::Bind(&ChildProcessStartedCallback, Unretained(this))); | |
|
boliu
2017/01/13 19:00:56
you have to remove Unretained and change ChildProc
Jay Civelli
2017/01/17 17:50:03
Used RetainedRef.
| |
| 146 | |
| 147 return base::Process(); | |
| 148 } | |
| 149 | |
| 150 void ChildProcessLauncher::Helper::AfterLaunchOnLauncherThread( | |
| 151 const base::Process& process, | |
| 152 const base::LaunchOptions& options) { | |
| 153 } | |
| 154 | |
| 155 // static | |
| 156 bool ChildProcessLauncher::TerminateProcess( | |
| 157 const base::Process& process, int exit_code, bool wait) { | |
| 158 StopChildProcess(process.Handle()); | |
| 159 return true; | |
| 160 } | |
| 161 | |
| 162 // static | |
| 163 void ChildProcessLauncher::TerminateOnLauncherThread( | |
| 164 ZygoteHandle zygote, base::Process process) { | |
| 165 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); | |
| 166 VLOG(1) << "ChromeProcess: Stopping process with handle " | |
| 167 << process.Handle(); | |
| 168 StopChildProcess(process.Handle()); | |
| 169 } | |
| 170 | |
| 171 // static | |
| 172 void ChildProcessLauncher::SetProcessBackgroundedOnLauncherThread( | |
| 173 base::Process process, bool background) { | |
| 174 SetChildProcessInForeground(process.Handle(), !background); | |
| 175 } | |
| 176 | |
| 177 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) { | |
| 178 DCHECK(CalledOnValidThread()); | |
| 179 if (IsChildProcessOomProtected(process_.Handle())) { | |
| 180 termination_status_ = base::TERMINATION_STATUS_OOM_PROTECTED; | |
| 181 } else { | |
| 182 termination_status_ = | |
| 183 base::GetTerminationStatus(process_.Handle(), &exit_code_); | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 } // namespace content | |
| OLD | NEW |