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

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java

Issue 2882823002: Moving some CPL logic to CPLH. (Closed)
Patch Set: Moving some CPL logic to CPLH. Created 3 years, 7 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 package org.chromium.content.browser; 5 package org.chromium.content.browser;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.os.Bundle;
9 import android.os.IBinder;
8 import android.os.ParcelFileDescriptor; 10 import android.os.ParcelFileDescriptor;
9 11
10 import org.chromium.base.ContextUtils; 12 import org.chromium.base.ContextUtils;
13 import org.chromium.base.CpuFeatures;
11 import org.chromium.base.Log; 14 import org.chromium.base.Log;
15 import org.chromium.base.VisibleForTesting;
12 import org.chromium.base.annotations.CalledByNative; 16 import org.chromium.base.annotations.CalledByNative;
13 import org.chromium.base.annotations.JNINamespace; 17 import org.chromium.base.annotations.JNINamespace;
18 import org.chromium.base.library_loader.Linker;
14 import org.chromium.base.process_launcher.ChildProcessCreationParams; 19 import org.chromium.base.process_launcher.ChildProcessCreationParams;
15 import org.chromium.base.process_launcher.FileDescriptorInfo; 20 import org.chromium.base.process_launcher.FileDescriptorInfo;
21 import org.chromium.content.app.ChromiumLinkerParams;
22 import org.chromium.content.common.ContentSwitches;
16 23
17 import java.io.IOException; 24 import java.io.IOException;
18 25
19 /** 26 /**
20 * This is the java counterpart to ChildProcessLauncherHelper. It is owned by na tive side and 27 * This is the java counterpart to ChildProcessLauncherHelper. It is owned by na tive side and
21 * has an explicit destroy method. 28 * has an explicit destroy method.
22 * Each public or jni methods should have explicit documentation on what threads they are called. 29 * Each public or jni methods should have explicit documentation on what threads they are called.
23 */ 30 */
24 @JNINamespace("content::internal") 31 @JNINamespace("content::internal")
25 class ChildProcessLauncherHelper { 32 public class ChildProcessLauncherHelper {
26 private static final String TAG = "ChildProcLH"; 33 private static final String TAG = "ChildProcLH";
27 34
28 // Represents an invalid process handle; same as base/process/process.h kNul lProcessHandle. 35 // Represents an invalid process handle; same as base/process/process.h kNul lProcessHandle.
29 private static final int NULL_PROCESS_HANDLE = 0; 36 private static final int NULL_PROCESS_HANDLE = 0;
30 37
38 // The IBinder provided to the created service.
39 private final IBinder mIBinderCallback;
40
31 // Note native pointer is only guaranteed live until nativeOnChildProcessSta rted. 41 // Note native pointer is only guaranteed live until nativeOnChildProcessSta rted.
32 private long mNativeChildProcessLauncherHelper; 42 private long mNativeChildProcessLauncherHelper;
43
44 // The actual service connection. Set once we have connected to the service.
33 private ChildProcessConnection mChildProcessConnection; 45 private ChildProcessConnection mChildProcessConnection;
34 46
35 @CalledByNative 47 @CalledByNative
36 private static FileDescriptorInfo makeFdInfo( 48 private static FileDescriptorInfo makeFdInfo(
37 int id, int fd, boolean autoClose, long offset, long size) { 49 int id, int fd, boolean autoClose, long offset, long size) {
38 assert LauncherThread.runningOnLauncherThread(); 50 assert LauncherThread.runningOnLauncherThread();
39 ParcelFileDescriptor pFd; 51 ParcelFileDescriptor pFd;
40 if (autoClose) { 52 if (autoClose) {
41 // Adopt the FD, it will be closed when we close the ParcelFileDescr iptor. 53 // Adopt the FD, it will be closed when we close the ParcelFileDescr iptor.
42 pFd = ParcelFileDescriptor.adoptFd(fd); 54 pFd = ParcelFileDescriptor.adoptFd(fd);
43 } else { 55 } else {
44 try { 56 try {
45 pFd = ParcelFileDescriptor.fromFd(fd); 57 pFd = ParcelFileDescriptor.fromFd(fd);
46 } catch (IOException e) { 58 } catch (IOException e) {
47 Log.e(TAG, "Invalid FD provided for process connection, aborting connection.", e); 59 Log.e(TAG, "Invalid FD provided for process connection, aborting connection.", e);
48 return null; 60 return null;
49 } 61 }
50 } 62 }
51 return new FileDescriptorInfo(id, pFd, offset, size); 63 return new FileDescriptorInfo(id, pFd, offset, size);
52 } 64 }
53 65
66 @VisibleForTesting
54 @CalledByNative 67 @CalledByNative
55 private static ChildProcessLauncherHelper create(long nativePointer, int par amId, 68 public static ChildProcessLauncherHelper createAndStart(long nativePointer, int paramId,
56 final String[] commandLine, FileDescriptorInfo[] filesToBeMapped) { 69 final String[] commandLine, FileDescriptorInfo[] filesToBeMapped) {
57 assert LauncherThread.runningOnLauncherThread(); 70 assert LauncherThread.runningOnLauncherThread();
58 return new ChildProcessLauncherHelper(nativePointer, paramId, commandLin e, filesToBeMapped); 71 String processType =
72 ContentSwitches.getSwitchValue(commandLine, ContentSwitches.SWIT CH_PROCESS_TYPE);
73
74 ChildProcessCreationParams params = ChildProcessCreationParams.get(param Id);
75 if (paramId != ChildProcessCreationParams.DEFAULT_ID && params == null) {
76 throw new RuntimeException("CreationParams id " + paramId + " not fo und");
77 }
78
79 Context context = ContextUtils.getApplicationContext();
80 boolean sandboxed = true;
81 boolean alwaysInForeground = false;
82 if (!ContentSwitches.SWITCH_RENDERER_PROCESS.equals(processType)) {
83 if (params != null && !params.getPackageName().equals(context.getPac kageName())) {
84 // WebViews and WebAPKs have renderer processes running in their applications.
85 // When launching these renderer processes, {@link ManagedChildP rocessConnection}
86 // requires the package name of the application which holds the renderer process.
87 // Therefore, the package name in ChildProcessCreationParams cou ld be the package
88 // name of WebViews, WebAPKs, or Chrome, depending on the host a pplication.
89 // Except renderer process, all other child processes should use Chrome's package
90 // name. In WebAPK, ChildProcessCreationParams are initialized w ith WebAPK's
91 // package name. Make a copy of the WebAPK's params, but replace the package with
92 // Chrome's package to use when initializing a non-renderer proc esses.
93 // TODO(boliu): Should fold into |paramId|. Investigate why this is needed.
94 params = new ChildProcessCreationParams(context.getPackageName() ,
95 params.getIsExternalService(), params.getLibraryProcessT ype(),
96 params.getBindToCallerCheck());
97 }
98 if (ContentSwitches.SWITCH_GPU_PROCESS.equals(processType)) {
99 sandboxed = false;
100 alwaysInForeground = true;
101 } else {
102 // We only support sandboxed utility processes now.
103 assert ContentSwitches.SWITCH_UTILITY_PROCESS.equals(processType );
104 }
105 }
106
107 ChildProcessLauncherHelper process_launcher =
108 new ChildProcessLauncherHelper(nativePointer, processType);
109 process_launcher.start(
110 context, commandLine, filesToBeMapped, params, sandboxed, always InForeground);
111 return process_launcher;
59 } 112 }
60 113
61 private ChildProcessLauncherHelper(long nativePointer, int paramId, final St ring[] commandLine, 114 @VisibleForTesting
62 FileDescriptorInfo[] filesToBeMapped) { 115 public static ChildProcessLauncherHelper createAndStartForTesting(long nativ ePointer,
boliu 2017/05/15 21:38:22 nit: put test-only methods at the very end
Jay Civelli 2017/05/17 16:42:50 Done.
116 String[] commandLine, FileDescriptorInfo[] filesToBeMapped,
117 ChildProcessCreationParams creationParams, boolean sandboxed,
118 boolean alwaysInForeground) {
119 String processType =
120 ContentSwitches.getSwitchValue(commandLine, ContentSwitches.SWIT CH_PROCESS_TYPE);
121 ChildProcessLauncherHelper launcherHelper =
122 new ChildProcessLauncherHelper(nativePointer, processType);
123 launcherHelper.start(ContextUtils.getApplicationContext(), commandLine, filesToBeMapped,
124 creationParams, sandboxed, alwaysInForeground);
125 return launcherHelper;
126 }
127
128 private ChildProcessLauncherHelper(long nativePointer, String processType) {
63 assert LauncherThread.runningOnLauncherThread(); 129 assert LauncherThread.runningOnLauncherThread();
64 mNativeChildProcessLauncherHelper = nativePointer; 130 mNativeChildProcessLauncherHelper = nativePointer;
131 mIBinderCallback = ContentSwitches.SWITCH_GPU_PROCESS.equals(processType )
132 ? new GpuProcessCallback()
133 : null;
134 }
65 135
66 ChildProcessLauncher.start(ContextUtils.getApplicationContext(), paramId , commandLine, 136 private void start(Context context, String[] commandLine,
67 filesToBeMapped, new ChildProcessLauncher.LaunchCallback() { 137 final FileDescriptorInfo[] filesToBeMapped, ChildProcessCreationPara ms params,
138 boolean sandboxed, boolean alwaysInForeground) {
139 boolean bindToCallerCheck = params == null ? false : params.getBindToCal lerCheck();
140 Bundle serviceBundle = createServiceBundle(bindToCallerCheck);
141 onBeforeConnectionAllocated(serviceBundle);
142
143 Bundle connectionBundle = createConnectionBundle(commandLine, filesToBeM apped);
144 ChildProcessLauncher.start(context, serviceBundle,
145 connectionBundle, new ChildProcessLauncher.LaunchCallback() {
68 @Override 146 @Override
69 public void onChildProcessStarted(ChildProcessConnection con nection) { 147 public void onChildProcessStarted(ChildProcessConnection con nection) {
70 mChildProcessConnection = connection; 148 mChildProcessConnection = connection;
71 if (mNativeChildProcessLauncherHelper != 0) { 149 if (mNativeChildProcessLauncherHelper != 0) {
72 nativeOnChildProcessStarted( 150 nativeOnChildProcessStarted(
73 mNativeChildProcessLauncherHelper, getPid()) ; 151 mNativeChildProcessLauncherHelper, getPid()) ;
74 } 152 }
75 mNativeChildProcessLauncherHelper = 0; 153 mNativeChildProcessLauncherHelper = 0;
154 // Proactively close the FDs rather than waiting for the GC to do it.
155 try {
boliu 2017/05/15 21:38:22 hmm, I guess this is the earliest in this class. B
Jay Civelli 2017/05/17 16:42:50 Done.
156 for (FileDescriptorInfo fileInfo : filesToBeMapped) {
157 fileInfo.fd.close();
158 }
159 } catch (IOException ioe) {
160 Log.w(TAG, "Failed to close FD.", ioe);
161 }
76 } 162 }
77 }); 163 }, getIBinderCallback(), sandboxed, alwaysInForeground, params);
78 } 164 }
79 165
80 private int getPid() { 166 private int getPid() {
81 return mChildProcessConnection == null ? NULL_PROCESS_HANDLE 167 return mChildProcessConnection == null ? NULL_PROCESS_HANDLE
82 : mChildProcessConnection.getPid( ); 168 : mChildProcessConnection.getPid( );
83 } 169 }
84 170
85 // Called on client (UI or IO) thread. 171 // Called on client (UI or IO) thread.
86 @CalledByNative 172 @CalledByNative
87 private boolean isOomProtected() { 173 private boolean isOomProtected() {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } catch (RuntimeException e) { 209 } catch (RuntimeException e) {
124 // Unittest packages do not declare services. Some tests require a r ealistic number 210 // Unittest packages do not declare services. Some tests require a r ealistic number
125 // to test child process policies, so pick a high-ish number here. 211 // to test child process policies, so pick a high-ish number here.
126 return 65535; 212 return 65535;
127 } 213 }
128 } 214 }
129 215
130 // Can be called on a number of threads, including launcher, and binder. 216 // Can be called on a number of threads, including launcher, and binder.
131 private static native void nativeOnChildProcessStarted( 217 private static native void nativeOnChildProcessStarted(
132 long nativeChildProcessLauncherHelper, int pid); 218 long nativeChildProcessLauncherHelper, int pid);
219
220 private static boolean sLinkerInitialized;
221 private static long sLinkerLoadAddress;
222
223 private static ChromiumLinkerParams getLinkerParamsForNewConnection() {
boliu 2017/05/15 21:38:22 static method, can we have a thread assert?
Jay Civelli 2017/05/17 16:42:50 Done.
224 if (!sLinkerInitialized) {
225 if (Linker.isUsed()) {
226 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress();
227 if (sLinkerLoadAddress == 0) {
228 Log.i(TAG, "Shared RELRO support disabled!");
229 }
230 }
231 sLinkerInitialized = true;
232 }
233
234 if (sLinkerLoadAddress == 0) return null;
235
236 // Always wait for the shared RELROs in service processes.
237 final boolean waitForSharedRelros = true;
238 if (Linker.areTestsEnabled()) {
239 Linker linker = Linker.getInstance();
240 return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRel ros,
241 linker.getTestRunnerClassNameForTesting(),
242 linker.getImplementationForTesting());
243 } else {
244 return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRel ros);
245 }
246 }
247
248 /**
249 * Creates the common bundle to be passed to child processes through the ser vice binding intent.
250 * If the service gets recreated by the framework the intent will be reused, so these parameters
251 * should be common to all processes of that type.
252 *
253 * @param commandLine Command line params to be passed to the service.
254 * @param linkerParams Linker params to start the service.
255 */
256 // TODO(jcivelli): make private once warmup connection code is move from Chi ldProcessLauncher to
257 // this class.
258 static Bundle createServiceBundle(boolean bindToCallerCheck) {
259 Bundle bundle = new Bundle();
260 bundle.putBoolean(ChildProcessConstants.EXTRA_BIND_TO_CALLER, bindToCall erCheck);
261 return bundle;
262 }
263
264 @VisibleForTesting
265 public static Bundle createConnectionBundle(
266 String[] commandLine, FileDescriptorInfo[] filesToBeMapped) {
267 Bundle bundle = new Bundle();
268 bundle.putStringArray(ChildProcessConstants.EXTRA_COMMAND_LINE, commandL ine);
269 bundle.putParcelableArray(ChildProcessConstants.EXTRA_FILES, filesToBeMa pped);
270 // content specific parameters.
271 bundle.putInt(ChildProcessConstants.EXTRA_CPU_COUNT, CpuFeatures.getCoun t());
272 bundle.putLong(ChildProcessConstants.EXTRA_CPU_FEATURES, CpuFeatures.get Mask());
273 bundle.putBundle(Linker.EXTRA_LINKER_SHARED_RELROS, Linker.getInstance() .getSharedRelros());
boliu 2017/05/15 21:38:22 I don't know this code, but does this need to be o
Jay Civelli 2017/05/17 16:42:50 Good point. Now initializing the Linker in the con
274 return bundle;
275 }
276
277 // Below are methods that will eventually be moved to a content delegate cla ss.
278
279 private void onBeforeConnectionAllocated(Bundle commonParameters) {
280 // Add content specific parameters.
281 commonParameters.putParcelable(
282 ChildProcessConstants.EXTRA_LINKER_PARAMS, getLinkerParamsForNew Connection());
283 }
284
285 private IBinder getIBinderCallback() {
286 return mIBinderCallback;
287 }
288
289 // Testing only related methods.
290 @VisibleForTesting
291 public ChildProcessConnection getChildProcessConnection() {
292 return mChildProcessConnection;
293 }
133 } 294 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698