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

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

Issue 2774163002: android: Java ChildProcessLauncherHelper instance (Closed)
Patch Set: cleanups Created 3 years, 8 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,
174 child_process_id(), j_file_infos, 137 reinterpret_cast<intptr_t>(
175 reinterpret_cast<intptr_t>(new StartChildProcessCallback( 138 new scoped_refptr<ChildProcessLauncherHelper>(this)),
176 base::Bind(&ChildProcessStartedCallback, RetainedRef(this))))); 139 base::android::GetApplicationContext(), param_key, j_argv,
140 child_process_id(), j_file_infos));
177 141
178 return Process(); 142 return Process();
179 } 143 }
180 144
181 void ChildProcessLauncherHelper::AfterLaunchOnLauncherThread( 145 void ChildProcessLauncherHelper::AfterLaunchOnLauncherThread(
182 const ChildProcessLauncherHelper::Process& process, 146 const ChildProcessLauncherHelper::Process& process,
183 const base::LaunchOptions& options) { 147 const base::LaunchOptions& options) {
184 } 148 }
185 149
186 // static
187 base::TerminationStatus ChildProcessLauncherHelper::GetTerminationStatus( 150 base::TerminationStatus ChildProcessLauncherHelper::GetTerminationStatus(
188 const ChildProcessLauncherHelper::Process& process, 151 const ChildProcessLauncherHelper::Process& process,
189 bool known_dead, 152 bool known_dead,
190 int* exit_code) { 153 int* exit_code) {
191 if (Java_ChildProcessLauncher_isOomProtected( 154 if (Java_ChildProcessLauncherHelper_isOomProtected(AttachCurrentThread(),
192 AttachCurrentThread(), static_cast<jint>(process.process.Handle()))) { 155 java_peer_)) {
193 return base::TERMINATION_STATUS_OOM_PROTECTED; 156 return base::TERMINATION_STATUS_OOM_PROTECTED;
194 } 157 }
195 return base::GetTerminationStatus(process.process.Handle(), exit_code); 158 return base::GetTerminationStatus(process.process.Handle(), exit_code);
196 } 159 }
197 160
198 // static 161 // static
199 bool ChildProcessLauncherHelper::TerminateProcess( 162 bool ChildProcessLauncherHelper::TerminateProcess(
200 const base::Process& process, int exit_code, bool wait) { 163 const base::Process& process, int exit_code, bool wait) {
201 StopChildProcess(process.Handle()); 164 StopChildProcess(process.Handle());
202 return true; 165 return true;
203 } 166 }
204 167
205 // static 168 // static
206 void ChildProcessLauncherHelper::ForceNormalProcessTerminationSync( 169 void ChildProcessLauncherHelper::ForceNormalProcessTerminationSync(
207 ChildProcessLauncherHelper::Process process) { 170 ChildProcessLauncherHelper::Process process) {
208 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 171 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
209 VLOG(1) << "ChromeProcess: Stopping process with handle " 172 VLOG(1) << "ChromeProcess: Stopping process with handle "
210 << process.process.Handle(); 173 << process.process.Handle();
211 StopChildProcess(process.process.Handle()); 174 StopChildProcess(process.process.Handle());
212 } 175 }
213 176
214 // static
215 void ChildProcessLauncherHelper::SetProcessBackgroundedOnLauncherThread( 177 void ChildProcessLauncherHelper::SetProcessBackgroundedOnLauncherThread(
216 base::Process process, 178 base::Process process,
217 bool background) { 179 bool background) {
218 JNIEnv* env = AttachCurrentThread(); 180 JNIEnv* env = AttachCurrentThread();
219 DCHECK(env); 181 DCHECK(env);
220 return Java_ChildProcessLauncher_setInForeground( 182 return Java_ChildProcessLauncherHelper_setInForeground(
221 env, static_cast<jint>(process.Handle()), !background); 183 env, java_peer_, process.Handle(), !background);
222 } 184 }
223 185
224 // static 186 // static
225 void ChildProcessLauncherHelper::SetRegisteredFilesForService( 187 void ChildProcessLauncherHelper::SetRegisteredFilesForService(
226 const std::string& service_name, 188 const std::string& service_name,
227 catalog::RequiredFileMap required_files) { 189 catalog::RequiredFileMap required_files) {
228 SetFilesToShareForServicePosix(service_name, std::move(required_files)); 190 SetFilesToShareForServicePosix(service_name, std::move(required_files));
229 } 191 }
230 192
231 // static 193 // static
232 void ChildProcessLauncherHelper::ResetRegisteredFilesForTesting() { 194 void ChildProcessLauncherHelper::ResetRegisteredFilesForTesting() {
233 ResetFilesToShareForTestingPosix(); 195 ResetFilesToShareForTestingPosix();
234 } 196 }
235 197
236 // static 198 // static
237 base::File OpenFileToShare(const base::FilePath& path, 199 base::File OpenFileToShare(const base::FilePath& path,
238 base::MemoryMappedFile::Region* region) { 200 base::MemoryMappedFile::Region* region) {
239 return base::File(base::android::OpenApkAsset(path.value(), region)); 201 return base::File(base::android::OpenApkAsset(path.value(), region));
240 } 202 }
241 203
242 // Called from ChildProcessLauncher.java when the ChildProcess was 204 // Called from ChildProcessLauncher.java when the ChildProcess was
243 // started. 205 // 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 206 // |handle| is the processID of the child process as originated in Java, 0 if
247 // the ChildProcess could not be created. 207 // the ChildProcess could not be created.
248 static void OnChildProcessStarted(JNIEnv*, 208 static void OnChildProcessStarted(JNIEnv*,
249 const JavaParamRef<jclass>&, 209 const JavaParamRef<jclass>&,
250 jlong client_context, 210 jlong pointer,
251 jint handle) { 211 jint handle) {
252 StartChildProcessCallback* callback = 212 scoped_refptr<ChildProcessLauncherHelper> helper = std::move(
253 reinterpret_cast<StartChildProcessCallback*>(client_context); 213 *reinterpret_cast<scoped_refptr<ChildProcessLauncherHelper>*>(pointer));
214 delete reinterpret_cast<scoped_refptr<ChildProcessLauncherHelper>*>(pointer);
Maria 2017/03/27 19:22:51 these two lines look really odd to me. Do you want
Jay Civelli 2017/03/27 19:49:48 Could OnChildProcessStarted be a non static method
boliu 2017/03/27 20:47:53 Ahh, good suggestion. I guess only down side is mo
254 int launch_result = (handle == base::kNullProcessHandle) 215 int launch_result = (handle == base::kNullProcessHandle)
255 ? LAUNCH_RESULT_FAILURE 216 ? LAUNCH_RESULT_FAILURE
256 : LAUNCH_RESULT_SUCCESS; 217 : LAUNCH_RESULT_SUCCESS;
257 callback->Run(static_cast<base::ProcessHandle>(handle), launch_result); 218
258 delete callback; 219 // TODO(jcivelli): Remove this by defining better what happens on what thread
220 // in the corresponding Java code.
221 ChildProcessLauncherHelper::Process process;
222 process.process = base::Process(handle);
223 if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) {
224 helper->PostLaunchOnLauncherThread(
225 std::move(process), launch_result,
226 false); // post_launch_on_client_thread_called
227 return;
228 }
229
230 bool on_client_thread = BrowserThread::CurrentlyOn(
231 static_cast<BrowserThread::ID>(helper->client_thread_id()));
232 BrowserThread::PostTask(
233 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
234 base::Bind(&ChildProcessLauncherHelper::PostLaunchOnLauncherThread,
235 helper, base::Passed(std::move(process)), launch_result,
236 on_client_thread));
237 if (on_client_thread) {
238 ChildProcessLauncherHelper::Process process;
239 process.process = base::Process(handle);
240 helper->PostLaunchOnClientThread(std::move(process), launch_result);
241 }
259 } 242 }
260 243
261 } // namespace internal 244 } // namespace internal
262 245
263 bool RegisterChildProcessLauncher(JNIEnv* env) { 246 bool RegisterChildProcessLauncher(JNIEnv* env) {
264 return internal::RegisterNativesImpl(env); 247 return internal::RegisterNativesImpl(env);
265 } 248 }
266 249
267 } // namespace content 250 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698