OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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.base.process_launcher; |
6 | 6 |
7 import android.content.ComponentName; | 7 import android.content.ComponentName; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.content.ServiceConnection; | 10 import android.content.ServiceConnection; |
11 import android.content.pm.PackageManager; | 11 import android.content.pm.PackageManager; |
12 import android.content.pm.ServiceInfo; | 12 import android.content.pm.ServiceInfo; |
13 import android.os.Build; | 13 import android.os.Build; |
14 import android.os.Bundle; | 14 import android.os.Bundle; |
15 import android.os.Handler; | |
15 import android.os.IBinder; | 16 import android.os.IBinder; |
17 import android.os.Looper; | |
16 import android.os.RemoteException; | 18 import android.os.RemoteException; |
17 | 19 |
18 import org.chromium.base.Log; | 20 import org.chromium.base.Log; |
19 import org.chromium.base.TraceEvent; | 21 import org.chromium.base.TraceEvent; |
20 import org.chromium.base.VisibleForTesting; | 22 import org.chromium.base.VisibleForTesting; |
21 import org.chromium.base.process_launcher.ChildProcessCreationParams; | |
22 import org.chromium.base.process_launcher.FileDescriptorInfo; | |
23 import org.chromium.base.process_launcher.ICallbackInt; | |
24 import org.chromium.base.process_launcher.IChildProcessService; | |
25 | 23 |
26 import java.io.IOException; | 24 import java.io.IOException; |
27 | 25 |
28 import javax.annotation.Nullable; | 26 import javax.annotation.Nullable; |
29 | 27 |
30 /** | 28 /** |
31 * Manages a connection between the browser activity and a child service. | 29 * Manages a connection between the browser activity and a child service. |
30 * Most calls should happen on the connection's thread, the one specified in the constructor. | |
32 */ | 31 */ |
33 public abstract class BaseChildProcessConnection { | 32 public abstract class BaseChildProcessConnection { |
34 private static final String TAG = "BaseChildProcessConn"; | 33 private static final String TAG = "BaseChildProcessConn"; |
35 | 34 |
36 /** | 35 /** |
37 * Used to notify the consumer about disconnection of the service. This call back is provided | 36 * Used to notify the consumer about disconnection of the service. This call back is provided |
38 * earlier than ConnectionCallbacks below, as a child process might die befo re the connection is | 37 * earlier than ConnectionCallbacks below, as a child process might die befo re the connection is |
39 * fully set up. | 38 * fully set up. |
40 */ | 39 */ |
41 interface DeathCallback { | 40 public interface DeathCallback { |
42 // Called on Launcher thread. | 41 // Called on the connection's thread. |
43 void onChildProcessDied(BaseChildProcessConnection connection); | 42 void onChildProcessDied(BaseChildProcessConnection connection); |
44 } | 43 } |
45 | 44 |
46 /** | 45 /** |
47 * Used to notify the consumer about the process start. These callbacks will be invoked before | 46 * Used to notify the consumer about the process start. These callbacks will be invoked before |
48 * the ConnectionCallbacks. | 47 * the ConnectionCallbacks. |
49 */ | 48 */ |
50 interface StartCallback { | 49 public interface StartCallback { |
51 /** | 50 /** |
52 * Called when the child process has successfully started and is ready f or connection | 51 * Called when the child process has successfully started and is ready f or connection |
53 * setup. | 52 * setup. |
54 */ | 53 */ |
55 void onChildStarted(); | 54 void onChildStarted(); |
56 | 55 |
57 /** | 56 /** |
58 * Called when the child process failed to start. This can happen if the process is already | 57 * Called when the child process failed to start. This can happen if the process is already |
59 * in use by another client. | 58 * in use by another client. |
60 */ | 59 */ |
61 void onChildStartFailed(); | 60 void onChildStartFailed(); |
62 } | 61 } |
63 | 62 |
64 /** | 63 /** |
65 * Used to notify the consumer about the connection being established. | 64 * Used to notify the consumer about the connection being setup and establis hed. |
66 */ | 65 */ |
67 interface ConnectionCallback { | 66 public interface ConnectionCallback { |
67 /** | |
68 * Called before the connection to the service is established. This give s clients an | |
69 * opportunity to add custom parameters to params which is passed on to the service. | |
70 * @param params a bundle passed to the service. | |
71 */ | |
72 void onConnectionSetup(Bundle params); | |
73 | |
68 /** | 74 /** |
69 * Called when the connection to the service is established. | 75 * Called when the connection to the service is established. |
70 * @param connecion the connection object to the child process | 76 * @param connection the connection object to the child process |
71 */ | 77 */ |
72 void onConnected(BaseChildProcessConnection connection); | 78 void onConnected(BaseChildProcessConnection connection); |
73 } | 79 } |
74 | 80 |
75 /** Used to create specialization connection instances. */ | 81 /** Used to create specialization of connection instances. */ |
76 interface Factory { | 82 public interface Factory { |
77 BaseChildProcessConnection create(Context context, int number, boolean s andboxed, | 83 BaseChildProcessConnection create(Handler handler, Context context, int number, |
78 DeathCallback deathCallback, String serviceClassName, | 84 boolean sandboxed, DeathCallback deathCallback, String serviceCl assName, |
79 Bundle childProcessCommonParameters, ChildProcessCreationParams creationParams); | 85 Bundle childProcessCommonParameters, ChildProcessCreationParams creationParams); |
80 } | 86 } |
81 | 87 |
82 /** Interface representing a connection to the Android service. Can be mocke d in unit-tests. */ | 88 /** Interface representing a connection to the Android service. Can be mocke d in unit-tests. */ |
83 protected interface ChildServiceConnection { | 89 protected interface ChildServiceConnection { |
84 boolean bind(); | 90 boolean bind(); |
85 void unbind(); | 91 void unbind(); |
86 boolean isBound(); | 92 boolean isBound(); |
87 } | 93 } |
88 | 94 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 } | 136 } |
131 } | 137 } |
132 | 138 |
133 @Override | 139 @Override |
134 public boolean isBound() { | 140 public boolean isBound() { |
135 return mBound; | 141 return mBound; |
136 } | 142 } |
137 | 143 |
138 @Override | 144 @Override |
139 public void onServiceConnected(ComponentName className, final IBinder se rvice) { | 145 public void onServiceConnected(ComponentName className, final IBinder se rvice) { |
140 LauncherThread.post(new Runnable() { | 146 mHandler.post(new Runnable() { |
141 @Override | 147 @Override |
142 public void run() { | 148 public void run() { |
143 BaseChildProcessConnection.this.onServiceConnectedOnLauncher Thread(service); | 149 BaseChildProcessConnection.this.onServiceConnected(service); |
144 } | 150 } |
145 }); | 151 }); |
146 } | 152 } |
147 | 153 |
148 // Called on the main thread to notify that the child service did not di sconnect gracefully. | 154 // Called on the main thread to notify that the child service did not di sconnect gracefully. |
149 @Override | 155 @Override |
150 public void onServiceDisconnected(ComponentName className) { | 156 public void onServiceDisconnected(ComponentName className) { |
151 LauncherThread.post(new Runnable() { | 157 mHandler.post(new Runnable() { |
152 @Override | 158 @Override |
153 public void run() { | 159 public void run() { |
154 BaseChildProcessConnection.this.onServiceDisconnectedOnLaunc herThread(); | 160 BaseChildProcessConnection.this.onServiceDisconnected(); |
155 } | 161 } |
156 }); | 162 }); |
157 } | 163 } |
158 } | 164 } |
159 | 165 |
160 // Caches whether non-sandboxed and sandboxed services require an extra | 166 // Caches whether non-sandboxed and sandboxed services require an extra |
161 // binding flag provided via ChildProcessCreationParams. | 167 // binding flag provided via ChildProcessCreationParams. |
162 // TODO(mnaganov): Get rid of it after the release of the next Android SDK. | 168 // TODO(mnaganov): Get rid of it after the release of the next Android SDK. |
163 private static Boolean sNeedsExtrabindFlags[] = new Boolean[2]; | 169 private static Boolean sNeedsExtrabindFlags[] = new Boolean[2]; |
164 private final Context mContext; | 170 private final Context mContext; |
(...skipping 15 matching lines...) Expand all Loading... | |
180 final IBinder mCallback; | 186 final IBinder mCallback; |
181 | 187 |
182 ConnectionParams( | 188 ConnectionParams( |
183 String[] commandLine, FileDescriptorInfo[] filesToBeMapped, IBin der callback) { | 189 String[] commandLine, FileDescriptorInfo[] filesToBeMapped, IBin der callback) { |
184 mCommandLine = commandLine; | 190 mCommandLine = commandLine; |
185 mFilesToBeMapped = filesToBeMapped; | 191 mFilesToBeMapped = filesToBeMapped; |
186 mCallback = callback; | 192 mCallback = callback; |
187 } | 193 } |
188 } | 194 } |
189 | 195 |
196 // The handler for the thread the connection should be accessed on. | |
197 private final Handler mHandler; | |
198 | |
190 // This is set in start() and is used in onServiceConnected(). | 199 // This is set in start() and is used in onServiceConnected(). |
191 private StartCallback mStartCallback; | 200 private StartCallback mStartCallback; |
192 | 201 |
193 // This is set in setupConnection() and is later used in doConnectionSetupLo cked(), after which | 202 // This is set in setupConnection() and is later used in doConnectionSetupLo cked(), after which |
194 // the variable is cleared. Therefore this is only valid while the connectio n is being set up. | 203 // the variable is cleared. Therefore this is only valid while the connectio n is being set up. |
195 private ConnectionParams mConnectionParams; | 204 private ConnectionParams mConnectionParams; |
196 | 205 |
197 // Callback provided in setupConnection() that will communicate the result t o the caller. This | 206 // Callback provided in setupConnection() that will communicate the result t o the caller. This |
198 // has to be called exactly once after setupConnection(), even if setup fail s, so that the | 207 // has to be called exactly once after setupConnection(), even if setup fail s, so that the |
199 // caller can free up resources associated with the setup attempt. This is s et to null after the | 208 // caller can free up resources associated with the setup attempt. This is s et to null after the |
200 // call. | 209 // call. |
201 private ConnectionCallback mConnectionCallback; | 210 private ConnectionCallback mConnectionCallback; |
202 | 211 |
203 private IChildProcessService mService; | 212 private IChildProcessService mService; |
204 | 213 |
205 // Set to true when the service connection callback runs. This differs from | 214 // Set to true when the service connection callback runs. This differs from |
206 // mServiceConnectComplete, which tracks that the connection completed succe ssfully. | 215 // mServiceConnectComplete, which tracks that the connection completed succe ssfully. |
207 private boolean mDidOnServiceConnected; | 216 private boolean mDidOnServiceConnected; |
208 | 217 |
209 // Set to true when the service connected successfully. | 218 // Set to true when the service connected successfully. |
210 private boolean mServiceConnectComplete; | 219 private boolean mServiceConnectComplete; |
211 | 220 |
212 // Set to true when the service disconnects, as opposed to being properly cl osed. This happens | 221 // Set to true when the service disconnects, as opposed to being properly cl osed. This happens |
213 // when the process crashes or gets killed by the system out-of-memory kille r. | 222 // when the process crashes or gets killed by the system out-of-memory kille r. |
214 private boolean mServiceDisconnected; | 223 private boolean mServiceDisconnected; |
215 | 224 |
216 // Process ID of the corresponding child process. | 225 // Process ID of the corresponding child process. |
217 private int mPid; | 226 private int mPid; |
218 | 227 |
219 protected BaseChildProcessConnection(Context context, int number, boolean sa ndboxed, | 228 protected BaseChildProcessConnection(Handler handler, Context context, int n umber, |
220 DeathCallback deathCallback, String serviceClassName, | 229 boolean sandboxed, DeathCallback deathCallback, String serviceClassN ame, |
221 Bundle childProcessCommonParameters, ChildProcessCreationParams crea tionParams) { | 230 Bundle childProcessCommonParameters, ChildProcessCreationParams crea tionParams) { |
222 assert LauncherThread.runningOnLauncherThread(); | 231 mHandler = handler; |
223 mContext = context; | 232 mContext = context; |
224 mServiceNumber = number; | 233 mServiceNumber = number; |
225 mSandboxed = sandboxed; | 234 mSandboxed = sandboxed; |
226 mDeathCallback = deathCallback; | 235 mDeathCallback = deathCallback; |
227 String packageName = | 236 String packageName = |
228 creationParams != null ? creationParams.getPackageName() : conte xt.getPackageName(); | 237 creationParams != null ? creationParams.getPackageName() : conte xt.getPackageName(); |
229 mServiceName = new ComponentName(packageName, serviceClassName + mServic eNumber); | 238 mServiceName = new ComponentName(packageName, serviceClassName + mServic eNumber); |
230 mChildProcessCommonParameters = childProcessCommonParameters; | 239 mChildProcessCommonParameters = childProcessCommonParameters; |
231 mCreationParams = creationParams; | 240 mCreationParams = creationParams; |
232 } | 241 } |
233 | 242 |
234 public final Context getContext() { | 243 public final Context getContext() { |
235 assert LauncherThread.runningOnLauncherThread(); | 244 checkOnValidThread(); |
236 return mContext; | 245 return mContext; |
237 } | 246 } |
238 | 247 |
239 public final int getServiceNumber() { | 248 public final int getServiceNumber() { |
240 assert LauncherThread.runningOnLauncherThread(); | 249 checkOnValidThread(); |
241 return mServiceNumber; | 250 return mServiceNumber; |
242 } | 251 } |
243 | 252 |
244 public final boolean isSandboxed() { | 253 public final boolean isSandboxed() { |
245 assert LauncherThread.runningOnLauncherThread(); | 254 checkOnValidThread(); |
246 return mSandboxed; | 255 return mSandboxed; |
247 } | 256 } |
248 | 257 |
249 public final String getPackageName() { | 258 public final String getPackageName() { |
250 assert LauncherThread.runningOnLauncherThread(); | 259 checkOnValidThread(); |
251 return mCreationParams != null ? mCreationParams.getPackageName() | 260 return mCreationParams != null ? mCreationParams.getPackageName() |
252 : mContext.getPackageName(); | 261 : mContext.getPackageName(); |
253 } | 262 } |
254 | 263 |
255 public final ChildProcessCreationParams getCreationParams() { | 264 public final ChildProcessCreationParams getCreationParams() { |
256 assert LauncherThread.runningOnLauncherThread(); | 265 checkOnValidThread(); |
257 return mCreationParams; | 266 return mCreationParams; |
258 } | 267 } |
259 | 268 |
260 public final IChildProcessService getService() { | 269 public final IChildProcessService getService() { |
261 assert LauncherThread.runningOnLauncherThread(); | 270 checkOnValidThread(); |
262 return mService; | 271 return mService; |
263 } | 272 } |
264 | 273 |
265 public final ComponentName getServiceName() { | 274 public final ComponentName getServiceName() { |
266 assert LauncherThread.runningOnLauncherThread(); | 275 checkOnValidThread(); |
267 return mServiceName; | 276 return mServiceName; |
268 } | 277 } |
269 | 278 |
270 /** | 279 /** |
271 * @return the connection pid, or 0 if not yet connected | 280 * @return the connection pid, or 0 if not yet connected |
272 */ | 281 */ |
273 public int getPid() { | 282 public int getPid() { |
274 assert LauncherThread.runningOnLauncherThread(); | 283 checkOnValidThread(); |
275 return mPid; | 284 return mPid; |
276 } | 285 } |
277 | 286 |
278 /** | 287 /** |
279 * Starts a connection to an IChildProcessService. This must be followed by a call to | 288 * Starts a connection to an IChildProcessService. This must be followed by a call to |
280 * setupConnection() to setup the connection parameters. start() and setupCo nnection() are | 289 * setupConnection() to setup the connection parameters. start() and setupCo nnection() are |
281 * separate to allow to pass whatever parameters are available in start(), a nd complete the | 290 * separate to allow to pass whatever parameters are available in start(), a nd complete the |
282 * remainder later while reducing the connection setup latency. | 291 * remainder later while reducing the connection setup latency. |
283 * @param startCallback (optional) callback when the child process starts or fails to start. | 292 * @param startCallback (optional) callback when the child process starts or fails to start. |
284 */ | 293 */ |
285 public void start(StartCallback startCallback) { | 294 public void start(StartCallback startCallback) { |
286 assert LauncherThread.runningOnLauncherThread(); | 295 checkOnValidThread(); |
287 try { | 296 try { |
288 TraceEvent.begin("BaseChildProcessConnection.start"); | 297 TraceEvent.begin("BaseChildProcessConnection.start"); |
289 assert LauncherThread.runningOnLauncherThread(); | 298 checkOnValidThread(); |
boliu
2017/04/28 17:16:27
no need to repeat this :p
| |
290 assert mConnectionParams | 299 assert mConnectionParams |
291 == null | 300 == null |
292 : "setupConnection() called before start() in BaseChildProce ssConnection."; | 301 : "setupConnection() called before start() in BaseChildProce ssConnection."; |
293 | 302 |
294 mStartCallback = startCallback; | 303 mStartCallback = startCallback; |
295 | 304 |
296 if (!bind()) { | 305 if (!bind()) { |
297 Log.e(TAG, "Failed to establish the service connection."); | 306 Log.e(TAG, "Failed to establish the service connection."); |
298 // We have to notify the caller so that they can free-up associa ted resources. | 307 // We have to notify the caller so that they can free-up associa ted resources. |
299 // TODO(ppi): Can we hard-fail here? | 308 // TODO(ppi): Can we hard-fail here? |
300 mDeathCallback.onChildProcessDied(BaseChildProcessConnection.thi s); | 309 mDeathCallback.onChildProcessDied(BaseChildProcessConnection.thi s); |
301 } | 310 } |
302 } finally { | 311 } finally { |
303 TraceEvent.end("BaseChildProcessConnection.start"); | 312 TraceEvent.end("BaseChildProcessConnection.start"); |
304 } | 313 } |
305 } | 314 } |
306 | 315 |
307 /** | 316 /** |
308 * Setups the connection after it was started with start(). | 317 * Setups the connection after it was started with start(). |
309 * @param commandLine (optional) will be ignored if the command line was alr eady sent in start() | 318 * @param commandLine (optional) will be ignored if the command line was alr eady sent in start() |
310 * @param filesToBeMapped a list of file descriptors that should be register ed | 319 * @param filesToBeMapped a list of file descriptors that should be register ed |
311 * @param callback optional client specified callbacks that the child can us e to communicate | 320 * @param callback optional client specified callbacks that the child can us e to communicate |
312 * with the parent process | 321 * with the parent process |
313 * @param connectionCallback will be called exactly once after the connectio n is set up or the | 322 * @param connectionCallback will be called exactly once after the connectio n is set up or the |
314 * setup fails | 323 * setup fails |
315 */ | 324 */ |
316 public void setupConnection(String[] commandLine, FileDescriptorInfo[] files ToBeMapped, | 325 public void setupConnection(String[] commandLine, FileDescriptorInfo[] files ToBeMapped, |
317 @Nullable IBinder callback, ConnectionCallback connectionCallback) { | 326 @Nullable IBinder callback, ConnectionCallback connectionCallback) { |
318 assert LauncherThread.runningOnLauncherThread(); | 327 checkOnValidThread(); |
319 assert mConnectionParams == null; | 328 assert mConnectionParams == null; |
320 if (mServiceDisconnected) { | 329 if (mServiceDisconnected) { |
321 Log.w(TAG, "Tried to setup a connection that already disconnected.") ; | 330 Log.w(TAG, "Tried to setup a connection that already disconnected.") ; |
322 connectionCallback.onConnected(null); | 331 connectionCallback.onConnected(null); |
323 return; | 332 return; |
324 } | 333 } |
325 try { | 334 try { |
326 TraceEvent.begin("BaseChildProcessConnection.setupConnection"); | 335 TraceEvent.begin("BaseChildProcessConnection.setupConnection"); |
327 mConnectionCallback = connectionCallback; | 336 mConnectionCallback = connectionCallback; |
328 mConnectionParams = new ConnectionParams(commandLine, filesToBeMappe d, callback); | 337 mConnectionParams = new ConnectionParams(commandLine, filesToBeMappe d, callback); |
329 // Run the setup if the service is already connected. If not, | 338 // Run the setup if the service is already connected. If not, |
330 // doConnectionSetupLocked() will be called from onServiceConnected( ). | 339 // doConnectionSetupLocked() will be called from onServiceConnected( ). |
331 if (mServiceConnectComplete) { | 340 if (mServiceConnectComplete) { |
332 doConnectionSetupLocked(); | 341 doConnectionSetupLocked(); |
333 } | 342 } |
334 } finally { | 343 } finally { |
335 TraceEvent.end("BaseChildProcessConnection.setupConnection"); | 344 TraceEvent.end("BaseChildProcessConnection.setupConnection"); |
336 } | 345 } |
337 } | 346 } |
338 | 347 |
339 /** | 348 /** |
340 * Terminates the connection to IChildProcessService, closing all bindings. It is safe to call | 349 * Terminates the connection to IChildProcessService, closing all bindings. It is safe to call |
341 * this multiple times. | 350 * this multiple times. |
342 */ | 351 */ |
343 public void stop() { | 352 public void stop() { |
344 assert LauncherThread.runningOnLauncherThread(); | 353 checkOnValidThread(); |
345 unbind(); | 354 unbind(); |
346 mService = null; | 355 mService = null; |
347 mConnectionParams = null; | 356 mConnectionParams = null; |
348 } | 357 } |
349 | 358 |
350 private void onServiceConnectedOnLauncherThread(IBinder service) { | 359 private void onServiceConnected(IBinder service) { |
351 assert LauncherThread.runningOnLauncherThread(); | 360 checkOnValidThread(); |
352 // A flag from the parent class ensures we run the post-connection logic only once | 361 // A flag from the parent class ensures we run the post-connection logic only once |
353 // (instead of once per each ChildServiceConnection). | 362 // (instead of once per each ChildServiceConnection). |
354 if (mDidOnServiceConnected) { | 363 if (mDidOnServiceConnected) { |
355 return; | 364 return; |
356 } | 365 } |
357 try { | 366 try { |
358 TraceEvent.begin( | 367 TraceEvent.begin( |
359 "BaseChildProcessConnection.ChildServiceConnection.onService Connected"); | 368 "BaseChildProcessConnection.ChildServiceConnection.onService Connected"); |
360 mDidOnServiceConnected = true; | 369 mDidOnServiceConnected = true; |
361 mService = IChildProcessService.Stub.asInterface(service); | 370 mService = IChildProcessService.Stub.asInterface(service); |
(...skipping 30 matching lines...) Expand all Loading... | |
392 // Run the setup if the connection parameters have already been prov ided. If | 401 // Run the setup if the connection parameters have already been prov ided. If |
393 // not, doConnectionSetupLocked() will be called from setupConnectio n(). | 402 // not, doConnectionSetupLocked() will be called from setupConnectio n(). |
394 if (mConnectionParams != null) { | 403 if (mConnectionParams != null) { |
395 doConnectionSetupLocked(); | 404 doConnectionSetupLocked(); |
396 } | 405 } |
397 } finally { | 406 } finally { |
398 TraceEvent.end("BaseChildProcessConnection.ChildServiceConnection.on ServiceConnected"); | 407 TraceEvent.end("BaseChildProcessConnection.ChildServiceConnection.on ServiceConnected"); |
399 } | 408 } |
400 } | 409 } |
401 | 410 |
402 private void onServiceDisconnectedOnLauncherThread() { | 411 private void onServiceDisconnected() { |
403 assert LauncherThread.runningOnLauncherThread(); | 412 checkOnValidThread(); |
404 // Ensure that the disconnection logic runs only once (instead of once p er each | 413 // Ensure that the disconnection logic runs only once (instead of once p er each |
405 // ChildServiceConnection). | 414 // ChildServiceConnection). |
406 if (mServiceDisconnected) { | 415 if (mServiceDisconnected) { |
407 return; | 416 return; |
408 } | 417 } |
409 mServiceDisconnected = true; | 418 mServiceDisconnected = true; |
410 Log.w(TAG, "onServiceDisconnected (crash or killed by oom): pid=%d", mPi d); | 419 Log.w(TAG, "onServiceDisconnected (crash or killed by oom): pid=%d", mPi d); |
411 stop(); // We don't want to auto-restart on crash. Let the browser do th at. | 420 stop(); // We don't want to auto-restart on crash. Let the browser do th at. |
412 mDeathCallback.onChildProcessDied(BaseChildProcessConnection.this); | 421 mDeathCallback.onChildProcessDied(BaseChildProcessConnection.this); |
413 // If we have a pending connection callback, we need to communicate the failure to | 422 // If we have a pending connection callback, we need to communicate the failure to |
(...skipping 18 matching lines...) Expand all Loading... | |
432 * Called after the connection parameters have been set (in setupConnection( )) *and* a | 441 * Called after the connection parameters have been set (in setupConnection( )) *and* a |
433 * connection has been established (as signaled by onServiceConnected()). Th ese two events can | 442 * connection has been established (as signaled by onServiceConnected()). Th ese two events can |
434 * happen in any order. Has to be called with mLock. | 443 * happen in any order. Has to be called with mLock. |
435 */ | 444 */ |
436 private void doConnectionSetupLocked() { | 445 private void doConnectionSetupLocked() { |
437 try { | 446 try { |
438 TraceEvent.begin("BaseChildProcessConnection.doConnectionSetupLocked "); | 447 TraceEvent.begin("BaseChildProcessConnection.doConnectionSetupLocked "); |
439 assert mServiceConnectComplete && mService != null; | 448 assert mServiceConnectComplete && mService != null; |
440 assert mConnectionParams != null; | 449 assert mConnectionParams != null; |
441 | 450 |
442 Bundle bundle = ChildProcessLauncher.createsServiceBundle( | 451 Bundle bundle = new Bundle(); |
443 mConnectionParams.mCommandLine, mConnectionParams.mFilesToBe Mapped); | 452 bundle.putStringArray( |
453 ChildProcessConstants.EXTRA_COMMAND_LINE, mConnectionParams. mCommandLine); | |
454 bundle.putParcelableArray( | |
455 ChildProcessConstants.EXTRA_FILES, mConnectionParams.mFilesT oBeMapped); | |
456 | |
457 if (mConnectionCallback != null) { | |
boliu
2017/04/28 17:16:27
is this check needed? should this be an assert ins
| |
458 mConnectionCallback.onConnectionSetup(bundle); | |
459 } | |
460 | |
444 ICallbackInt pidCallback = new ICallbackInt.Stub() { | 461 ICallbackInt pidCallback = new ICallbackInt.Stub() { |
445 @Override | 462 @Override |
446 public void call(final int pid) { | 463 public void call(final int pid) { |
447 LauncherThread.post(new Runnable() { | 464 mHandler.post(new Runnable() { |
448 @Override | 465 @Override |
449 public void run() { | 466 public void run() { |
450 onSetupConnectionResult(pid); | 467 onSetupConnectionResult(pid); |
451 } | 468 } |
452 }); | 469 }); |
453 } | 470 } |
454 }; | 471 }; |
455 try { | 472 try { |
456 mService.setupConnection(bundle, pidCallback, mConnectionParams. mCallback); | 473 mService.setupConnection(bundle, pidCallback, mConnectionParams. mCallback); |
457 } catch (RemoteException re) { | 474 } catch (RemoteException re) { |
(...skipping 11 matching lines...) Expand all Loading... | |
469 } finally { | 486 } finally { |
470 TraceEvent.end("BaseChildProcessConnection.doConnectionSetupLocked") ; | 487 TraceEvent.end("BaseChildProcessConnection.doConnectionSetupLocked") ; |
471 } | 488 } |
472 } | 489 } |
473 | 490 |
474 /** Subclasses should implement this method to bind/unbind to the actual ser vice. */ | 491 /** Subclasses should implement this method to bind/unbind to the actual ser vice. */ |
475 protected abstract boolean bind(); | 492 protected abstract boolean bind(); |
476 protected abstract void unbind(); | 493 protected abstract void unbind(); |
477 | 494 |
478 protected ChildServiceConnection createServiceConnection(int bindFlags) { | 495 protected ChildServiceConnection createServiceConnection(int bindFlags) { |
479 assert LauncherThread.runningOnLauncherThread(); | 496 checkOnValidThread(); |
480 return new ChildServiceConnectionImpl(bindFlags); | 497 return new ChildServiceConnectionImpl(bindFlags); |
481 } | 498 } |
482 | 499 |
483 protected boolean shouldBindAsExportedService() { | 500 protected boolean shouldBindAsExportedService() { |
484 assert LauncherThread.runningOnLauncherThread(); | 501 checkOnValidThread(); |
485 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && getCreationPara ms() != null | 502 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && getCreationPara ms() != null |
486 && getCreationParams().getIsExternalService() | 503 && getCreationParams().getIsExternalService() |
487 && isExportedService(isSandboxed(), getContext(), getServiceName ()); | 504 && isExportedService(isSandboxed(), getContext(), getServiceName ()); |
488 } | 505 } |
489 | 506 |
490 private static boolean isExportedService( | 507 private static boolean isExportedService( |
491 boolean inSandbox, Context context, ComponentName serviceName) { | 508 boolean inSandbox, Context context, ComponentName serviceName) { |
492 // Check for the cached value first. It is assumed that all pooled child services | 509 // Check for the cached value first. It is assumed that all pooled child services |
493 // have identical attributes in the manifest. | 510 // have identical attributes in the manifest. |
494 final int arrayIndex = inSandbox ? 1 : 0; | 511 final int arrayIndex = inSandbox ? 1 : 0; |
495 if (sNeedsExtrabindFlags[arrayIndex] != null) { | 512 if (sNeedsExtrabindFlags[arrayIndex] != null) { |
496 return sNeedsExtrabindFlags[arrayIndex].booleanValue(); | 513 return sNeedsExtrabindFlags[arrayIndex].booleanValue(); |
497 } | 514 } |
498 boolean result = false; | 515 boolean result = false; |
499 try { | 516 try { |
500 PackageManager packageManager = context.getPackageManager(); | 517 PackageManager packageManager = context.getPackageManager(); |
501 ServiceInfo serviceInfo = packageManager.getServiceInfo(serviceName, 0); | 518 ServiceInfo serviceInfo = packageManager.getServiceInfo(serviceName, 0); |
502 result = serviceInfo.exported; | 519 result = serviceInfo.exported; |
503 } catch (PackageManager.NameNotFoundException e) { | 520 } catch (PackageManager.NameNotFoundException e) { |
504 Log.e(TAG, "Could not retrieve info about service %s", serviceName, e); | 521 Log.e(TAG, "Could not retrieve info about service %s", serviceName, e); |
505 } | 522 } |
506 sNeedsExtrabindFlags[arrayIndex] = Boolean.valueOf(result); | 523 sNeedsExtrabindFlags[arrayIndex] = Boolean.valueOf(result); |
507 return result; | 524 return result; |
508 } | 525 } |
509 | 526 |
527 /** Checks whether the caller is running on the thread specified at creation time. */ | |
528 protected final void checkOnValidThread() { | |
529 assert mHandler.getLooper() == Looper.myLooper(); | |
530 } | |
531 | |
510 @VisibleForTesting | 532 @VisibleForTesting |
511 public void crashServiceForTesting() throws RemoteException { | 533 public void crashServiceForTesting() throws RemoteException { |
512 mService.crashIntentionallyForTesting(); | 534 mService.crashIntentionallyForTesting(); |
513 } | 535 } |
514 | 536 |
515 @VisibleForTesting | 537 @VisibleForTesting |
516 boolean isConnected() { | 538 public boolean isConnected() { |
517 return mService != null; | 539 return mService != null; |
518 } | 540 } |
519 } | 541 } |
OLD | NEW |