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