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

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

Issue 2774163002: android: Java ChildProcessLauncherHelper instance (Closed)
Patch Set: explicit AddRef Created 3 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
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 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_helper_android.h" 5 #include "content/browser/child_process_launcher_helper_android.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/android/apk_assets.h" 9 #include "base/android/apk_assets.h"
10 #include "base/android/context_utils.h" 10 #include "base/android/context_utils.h"
11 #include "base/android/jni_array.h" 11 #include "base/android/jni_array.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/metrics/field_trial.h" 14 #include "base/metrics/field_trial.h"
15 #include "content/browser/child_process_launcher_helper.h" 15 #include "content/browser/child_process_launcher_helper.h"
16 #include "content/browser/child_process_launcher_helper_posix.h" 16 #include "content/browser/child_process_launcher_helper_posix.h"
17 #include "content/browser/file_descriptor_info_impl.h" 17 #include "content/browser/file_descriptor_info_impl.h"
18 #include "content/browser/web_contents/web_contents_impl.h" 18 #include "content/browser/web_contents/web_contents_impl.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/render_process_host.h" 20 #include "content/public/browser/render_process_host.h"
21 #include "content/public/common/content_descriptors.h" 21 #include "content/public/common/content_descriptors.h"
22 #include "content/public/common/content_switches.h" 22 #include "content/public/common/content_switches.h"
23 #include "gin/v8_initializer.h" 23 #include "gin/v8_initializer.h"
24 #include "jni/ChildProcessLauncher_jni.h" 24 #include "jni/ChildProcessLauncherHelper_jni.h"
25 25
26 using base::android::AttachCurrentThread; 26 using base::android::AttachCurrentThread;
27 using base::android::JavaParamRef; 27 using base::android::JavaParamRef;
28 using base::android::ScopedJavaGlobalRef; 28 using base::android::ScopedJavaGlobalRef;
29 using base::android::ScopedJavaLocalRef; 29 using base::android::ScopedJavaLocalRef;
30 using base::android::ToJavaArrayOfStrings; 30 using base::android::ToJavaArrayOfStrings;
31 31
32 namespace content { 32 namespace content {
33
34 typedef base::Callback<void(base::ProcessHandle, int /* launch result */)>
35 StartChildProcessCallback;
36
37 namespace internal { 33 namespace internal {
38
39 namespace { 34 namespace {
40 35
41 // Stops a child process based on the handle returned from StartChildProcess. 36 // Stops a child process based on the handle returned from StartChildProcess.
42 void StopChildProcess(base::ProcessHandle handle) { 37 void StopChildProcess(base::ProcessHandle handle) {
43 JNIEnv* env = AttachCurrentThread(); 38 JNIEnv* env = AttachCurrentThread();
44 DCHECK(env); 39 DCHECK(env);
45 Java_ChildProcessLauncher_stop(env, static_cast<jint>(handle)); 40 Java_ChildProcessLauncherHelper_stop(env, static_cast<jint>(handle));
46 }
47
48 // Callback invoked from Java once the process has been started.
49 void ChildProcessStartedCallback(
50 ChildProcessLauncherHelper* helper,
51 base::ProcessHandle handle,
52 int launch_result) {
53 // TODO(jcivelli): Remove this by defining better what happens on what thread
54 // in the corresponding Java code.
55 ChildProcessLauncherHelper::Process process;
56 process.process = base::Process(handle);
57 if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) {
58 helper->PostLaunchOnLauncherThread(
59 std::move(process),
60 launch_result,
61 false); // post_launch_on_client_thread_called
62 return;
63 }
64
65 bool on_client_thread = BrowserThread::CurrentlyOn(
66 static_cast<BrowserThread::ID>(helper->client_thread_id()));
67 BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
68 base::Bind(&ChildProcessLauncherHelper::PostLaunchOnLauncherThread,
69 helper,
70 base::Passed(std::move(process)),
71 launch_result,
72 on_client_thread));
73 if (on_client_thread) {
74 ChildProcessLauncherHelper::Process process;
75 process.process = base::Process(handle);
76 helper->PostLaunchOnClientThread(std::move(process), launch_result);
77 }
78 } 41 }
79 42
80 } // namespace 43 } // namespace
81 44
82 void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() { 45 void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
83 // Android only supports renderer, sandboxed utility and gpu. 46 // Android only supports renderer, sandboxed utility and gpu.
84 std::string process_type = 47 std::string process_type =
85 command_line()->GetSwitchValueASCII(switches::kProcessType); 48 command_line()->GetSwitchValueASCII(switches::kProcessType);
86 CHECK(process_type == switches::kGpuProcess || 49 CHECK(process_type == switches::kGpuProcess ||
87 process_type == switches::kRendererProcess || 50 process_type == switches::kRendererProcess ||
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 env, env->NewObjectArray(file_count, j_file_info_class.obj(), NULL)); 115 env, env->NewObjectArray(file_count, j_file_info_class.obj(), NULL));
153 base::android::CheckException(env); 116 base::android::CheckException(env);
154 117
155 for (size_t i = 0; i < file_count; ++i) { 118 for (size_t i = 0; i < file_count; ++i) {
156 int fd = files_to_register->GetFDAt(i); 119 int fd = files_to_register->GetFDAt(i);
157 PCHECK(0 <= fd); 120 PCHECK(0 <= fd);
158 int id = files_to_register->GetIDAt(i); 121 int id = files_to_register->GetIDAt(i);
159 const auto& region = files_to_register->GetRegionAt(i); 122 const auto& region = files_to_register->GetRegionAt(i);
160 bool auto_close = files_to_register->OwnsFD(fd); 123 bool auto_close = files_to_register->OwnsFD(fd);
161 ScopedJavaLocalRef<jobject> j_file_info = 124 ScopedJavaLocalRef<jobject> j_file_info =
162 Java_ChildProcessLauncher_makeFdInfo(env, id, fd, auto_close, 125 Java_ChildProcessLauncherHelper_makeFdInfo(env, id, fd, auto_close,
163 region.offset, region.size); 126 region.offset, region.size);
164 PCHECK(j_file_info.obj()); 127 PCHECK(j_file_info.obj());
165 env->SetObjectArrayElement(j_file_infos.obj(), i, j_file_info.obj()); 128 env->SetObjectArrayElement(j_file_infos.obj(), i, j_file_info.obj());
166 if (auto_close) { 129 if (auto_close) {
167 ignore_result(files_to_register->ReleaseFD(fd).release()); 130 ignore_result(files_to_register->ReleaseFD(fd).release());
168 } 131 }
169 } 132 }
170 133
171 constexpr int param_key = 0; // TODO(boliu): Use this. 134 constexpr int param_key = 0; // TODO(boliu): Use this.
172 Java_ChildProcessLauncher_start( 135 java_peer_.Reset(Java_ChildProcessLauncherHelper_create(
173 env, base::android::GetApplicationContext(), param_key, j_argv, 136 env, reinterpret_cast<intptr_t>(this),
174 child_process_id(), j_file_infos, 137 base::android::GetApplicationContext(), param_key, j_argv,
175 reinterpret_cast<intptr_t>(new StartChildProcessCallback( 138 child_process_id(), j_file_infos));
176 base::Bind(&ChildProcessStartedCallback, RetainedRef(this))))); 139 AddRef(); // Balanced by OnChildProcessStarted.
177 140
178 return Process(); 141 return Process();
179 } 142 }
180 143
181 void ChildProcessLauncherHelper::AfterLaunchOnLauncherThread( 144 void ChildProcessLauncherHelper::AfterLaunchOnLauncherThread(
182 const ChildProcessLauncherHelper::Process& process, 145 const ChildProcessLauncherHelper::Process& process,
183 const base::LaunchOptions& options) { 146 const base::LaunchOptions& options) {
184 } 147 }
185 148
186 // static
187 base::TerminationStatus ChildProcessLauncherHelper::GetTerminationStatus( 149 base::TerminationStatus ChildProcessLauncherHelper::GetTerminationStatus(
188 const ChildProcessLauncherHelper::Process& process, 150 const ChildProcessLauncherHelper::Process& process,
189 bool known_dead, 151 bool known_dead,
190 int* exit_code) { 152 int* exit_code) {
191 if (Java_ChildProcessLauncher_isOomProtected( 153 if (Java_ChildProcessLauncherHelper_isOomProtected(AttachCurrentThread(),
192 AttachCurrentThread(), static_cast<jint>(process.process.Handle()))) { 154 java_peer_)) {
193 return base::TERMINATION_STATUS_OOM_PROTECTED; 155 return base::TERMINATION_STATUS_OOM_PROTECTED;
194 } 156 }
195 return base::GetTerminationStatus(process.process.Handle(), exit_code); 157 return base::GetTerminationStatus(process.process.Handle(), exit_code);
196 } 158 }
197 159
198 // static 160 // static
199 bool ChildProcessLauncherHelper::TerminateProcess( 161 bool ChildProcessLauncherHelper::TerminateProcess(
200 const base::Process& process, int exit_code, bool wait) { 162 const base::Process& process, int exit_code, bool wait) {
201 StopChildProcess(process.Handle()); 163 StopChildProcess(process.Handle());
202 return true; 164 return true;
203 } 165 }
204 166
205 // static 167 // static
206 void ChildProcessLauncherHelper::ForceNormalProcessTerminationSync( 168 void ChildProcessLauncherHelper::ForceNormalProcessTerminationSync(
207 ChildProcessLauncherHelper::Process process) { 169 ChildProcessLauncherHelper::Process process) {
208 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 170 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
209 VLOG(1) << "ChromeProcess: Stopping process with handle " 171 VLOG(1) << "ChromeProcess: Stopping process with handle "
210 << process.process.Handle(); 172 << process.process.Handle();
211 StopChildProcess(process.process.Handle()); 173 StopChildProcess(process.process.Handle());
212 } 174 }
213 175
214 // static
215 void ChildProcessLauncherHelper::SetProcessBackgroundedOnLauncherThread( 176 void ChildProcessLauncherHelper::SetProcessBackgroundedOnLauncherThread(
216 base::Process process, 177 base::Process process,
217 bool background) { 178 bool background) {
218 JNIEnv* env = AttachCurrentThread(); 179 JNIEnv* env = AttachCurrentThread();
219 DCHECK(env); 180 DCHECK(env);
220 return Java_ChildProcessLauncher_setInForeground( 181 return Java_ChildProcessLauncherHelper_setInForeground(
221 env, static_cast<jint>(process.Handle()), !background); 182 env, java_peer_, process.Handle(), !background);
222 } 183 }
223 184
224 // static 185 // static
225 void ChildProcessLauncherHelper::SetRegisteredFilesForService( 186 void ChildProcessLauncherHelper::SetRegisteredFilesForService(
226 const std::string& service_name, 187 const std::string& service_name,
227 catalog::RequiredFileMap required_files) { 188 catalog::RequiredFileMap required_files) {
228 SetFilesToShareForServicePosix(service_name, std::move(required_files)); 189 SetFilesToShareForServicePosix(service_name, std::move(required_files));
229 } 190 }
230 191
231 // static 192 // static
232 void ChildProcessLauncherHelper::ResetRegisteredFilesForTesting() { 193 void ChildProcessLauncherHelper::ResetRegisteredFilesForTesting() {
233 ResetFilesToShareForTestingPosix(); 194 ResetFilesToShareForTestingPosix();
234 } 195 }
235 196
236 // static 197 // static
237 base::File OpenFileToShare(const base::FilePath& path, 198 base::File OpenFileToShare(const base::FilePath& path,
238 base::MemoryMappedFile::Region* region) { 199 base::MemoryMappedFile::Region* region) {
239 return base::File(base::android::OpenApkAsset(path.value(), region)); 200 return base::File(base::android::OpenApkAsset(path.value(), region));
240 } 201 }
241 202
242 // Called from ChildProcessLauncher.java when the ChildProcess was 203 // Called from ChildProcessLauncher.java when the ChildProcess was
243 // started. 204 // started.
244 // |client_context| is the pointer to StartChildProcessCallback which was
245 // passed in from StartChildProcess.
246 // |handle| is the processID of the child process as originated in Java, 0 if 205 // |handle| is the processID of the child process as originated in Java, 0 if
247 // the ChildProcess could not be created. 206 // the ChildProcess could not be created.
248 static void OnChildProcessStarted(JNIEnv*, 207 void ChildProcessLauncherHelper::OnChildProcessStarted(
249 const JavaParamRef<jclass>&, 208 JNIEnv*,
250 jlong client_context, 209 const base::android::JavaParamRef<jobject>& obj,
251 jint handle) { 210 jint handle) {
252 StartChildProcessCallback* callback = 211 scoped_refptr<ChildProcessLauncherHelper> ref(this);
253 reinterpret_cast<StartChildProcessCallback*>(client_context); 212 Release(); // Balances with LaunchProcessOnLauncherThread.
213
254 int launch_result = (handle == base::kNullProcessHandle) 214 int launch_result = (handle == base::kNullProcessHandle)
255 ? LAUNCH_RESULT_FAILURE 215 ? LAUNCH_RESULT_FAILURE
256 : LAUNCH_RESULT_SUCCESS; 216 : LAUNCH_RESULT_SUCCESS;
257 callback->Run(static_cast<base::ProcessHandle>(handle), launch_result); 217
258 delete callback; 218 // TODO(jcivelli): Remove this by defining better what happens on what thread
219 // in the corresponding Java code.
220 ChildProcessLauncherHelper::Process process;
221 process.process = base::Process(handle);
222 if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) {
223 PostLaunchOnLauncherThread(std::move(process), launch_result,
224 false); // post_launch_on_client_thread_called
225 return;
226 }
227
228 bool on_client_thread = BrowserThread::CurrentlyOn(
229 static_cast<BrowserThread::ID>(client_thread_id()));
230 BrowserThread::PostTask(
231 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
232 base::Bind(&ChildProcessLauncherHelper::PostLaunchOnLauncherThread, this,
233 base::Passed(std::move(process)), launch_result,
234 on_client_thread));
235 if (on_client_thread) {
236 ChildProcessLauncherHelper::Process process;
237 process.process = base::Process(handle);
238 PostLaunchOnClientThread(std::move(process), launch_result);
239 }
259 } 240 }
260 241
261 } // namespace internal 242 } // namespace internal
262 243
263 bool RegisterChildProcessLauncher(JNIEnv* env) { 244 bool RegisterChildProcessLauncher(JNIEnv* env) {
264 return internal::RegisterNativesImpl(env); 245 return internal::RegisterNativesImpl(env);
265 } 246 }
266 247
267 } // namespace content 248 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_launcher_helper.h ('k') | content/browser/child_process_launcher_helper_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698