OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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.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.os.AsyncTask; | 11 import android.os.AsyncTask; |
12 import android.os.Bundle; | 12 import android.os.Bundle; |
13 import android.os.Handler; | 13 import android.os.Handler; |
14 import android.os.IBinder; | 14 import android.os.IBinder; |
15 import android.os.Looper; | 15 import android.os.Looper; |
16 import android.os.ParcelFileDescriptor; | 16 import android.os.ParcelFileDescriptor; |
17 import android.util.Log; | 17 import android.util.Log; |
18 | 18 |
19 import java.io.IOException; | 19 import java.io.IOException; |
20 import java.util.concurrent.atomic.AtomicBoolean; | 20 import java.util.concurrent.atomic.AtomicBoolean; |
21 | 21 |
22 import org.chromium.base.CalledByNative; | 22 import org.chromium.base.CalledByNative; |
23 import org.chromium.base.CpuFeatures; | 23 import org.chromium.base.CpuFeatures; |
24 import org.chromium.base.SysUtils; | 24 import org.chromium.base.SysUtils; |
25 import org.chromium.base.ThreadUtils; | 25 import org.chromium.base.ThreadUtils; |
26 import org.chromium.content.app.ChildProcessService; | 26 import org.chromium.content.app.ChildProcessService; |
| 27 import org.chromium.content.app.Linker; |
| 28 import org.chromium.content.app.LinkerParams; |
27 import org.chromium.content.common.CommandLine; | 29 import org.chromium.content.common.CommandLine; |
28 import org.chromium.content.common.IChildProcessCallback; | 30 import org.chromium.content.common.IChildProcessCallback; |
29 import org.chromium.content.common.IChildProcessService; | 31 import org.chromium.content.common.IChildProcessService; |
30 import org.chromium.content.common.TraceEvent; | 32 import org.chromium.content.common.TraceEvent; |
31 | 33 |
32 /** | 34 /** |
33 * Manages a connection between the browser activity and a child service. The cl
ass is responsible | 35 * Manages a connection between the browser activity and a child service. The cl
ass is responsible |
34 * for estabilishing the connection (start()), closing it (stop()) and increasin
g the priority of | 36 * for estabilishing the connection (start()), closing it (stop()) and increasin
g the priority of |
35 * the service when it is in active use (between calls to attachAsActive() and d
etachAsActive()). | 37 * the service when it is in active use (between calls to attachAsActive() and d
etachAsActive()). |
36 */ | 38 */ |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // the OS to be able to kill background renderers as it kills other backgrou
nd apps, so strong | 98 // the OS to be able to kill background renderers as it kills other backgrou
nd apps, so strong |
97 // bindings are maintained only for services that are active at the moment (
between | 99 // bindings are maintained only for services that are active at the moment (
between |
98 // attachAsActive() and detachAsActive()). | 100 // attachAsActive() and detachAsActive()). |
99 private ChildServiceConnection mStrongBinding = null; | 101 private ChildServiceConnection mStrongBinding = null; |
100 // Low priority binding maintained in the entire lifetime of the connection,
i.e. between calls | 102 // Low priority binding maintained in the entire lifetime of the connection,
i.e. between calls |
101 // to start() and stop(). | 103 // to start() and stop(). |
102 private ChildServiceConnection mWaivedBinding = null; | 104 private ChildServiceConnection mWaivedBinding = null; |
103 // Incremented on attachAsActive(), decremented on detachAsActive(). | 105 // Incremented on attachAsActive(), decremented on detachAsActive(). |
104 private int mAttachAsActiveCount = 0; | 106 private int mAttachAsActiveCount = 0; |
105 | 107 |
| 108 // Linker-related parameters. |
| 109 private LinkerParams mLinkerParams = null; |
| 110 |
106 private static final String TAG = "ChildProcessConnection"; | 111 private static final String TAG = "ChildProcessConnection"; |
107 | 112 |
108 private static class ConnectionParams { | 113 private static class ConnectionParams { |
109 final String[] mCommandLine; | 114 final String[] mCommandLine; |
110 final FileDescriptorInfo[] mFilesToBeMapped; | 115 final FileDescriptorInfo[] mFilesToBeMapped; |
111 final IChildProcessCallback mCallback; | 116 final IChildProcessCallback mCallback; |
| 117 final Bundle mSharedRelros; |
112 | 118 |
113 ConnectionParams(String[] commandLine, FileDescriptorInfo[] filesToBeMap
ped, | 119 ConnectionParams(String[] commandLine, FileDescriptorInfo[] filesToBeMap
ped, |
114 IChildProcessCallback callback) { | 120 IChildProcessCallback callback, Bundle sharedRelros) { |
115 mCommandLine = commandLine; | 121 mCommandLine = commandLine; |
116 mFilesToBeMapped = filesToBeMapped; | 122 mFilesToBeMapped = filesToBeMapped; |
117 mCallback = callback; | 123 mCallback = callback; |
| 124 mSharedRelros = sharedRelros; |
118 } | 125 } |
119 } | 126 } |
120 | 127 |
121 // This is set by the consumer of the class in setupConnection() and is late
r used in | 128 // This is set by the consumer of the class in setupConnection() and is late
r used in |
122 // doSetupConnection(), after which the variable is cleared. Therefore this
is only valid while | 129 // doSetupConnection(), after which the variable is cleared. Therefore this
is only valid while |
123 // the connection is being set up. | 130 // the connection is being set up. |
124 private ConnectionParams mConnectionParams; | 131 private ConnectionParams mConnectionParams; |
125 | 132 |
126 // Callbacks used to notify the consumer about connection events. This is al
so provided in | 133 // Callbacks used to notify the consumer about connection events. This is al
so provided in |
127 // setupConnection(), but remains valid after setup. | 134 // setupConnection(), but remains valid after setup. |
128 private ChildProcessConnection.ConnectionCallback mConnectionCallback; | 135 private ChildProcessConnection.ConnectionCallback mConnectionCallback; |
129 | 136 |
130 private class ChildServiceConnection implements ServiceConnection { | 137 private class ChildServiceConnection implements ServiceConnection { |
131 private boolean mBound = false; | 138 private boolean mBound = false; |
132 | 139 |
133 private final int mBindFlags; | 140 private final int mBindFlags; |
134 | 141 |
135 public ChildServiceConnection(int bindFlags) { | 142 public ChildServiceConnection(int bindFlags) { |
136 mBindFlags = bindFlags; | 143 mBindFlags = bindFlags; |
137 } | 144 } |
138 | 145 |
139 boolean bind(String[] commandLine) { | 146 boolean bind(String[] commandLine) { |
140 if (!mBound) { | 147 if (!mBound) { |
141 final Intent intent = createServiceBindIntent(); | 148 final Intent intent = createServiceBindIntent(); |
142 if (commandLine != null) { | 149 if (commandLine != null) { |
143 intent.putExtra(EXTRA_COMMAND_LINE, commandLine); | 150 intent.putExtra(EXTRA_COMMAND_LINE, commandLine); |
144 } | 151 } |
| 152 if (mLinkerParams != null) |
| 153 mLinkerParams.addIntentExtras(intent); |
145 mBound = mContext.bindService(intent, this, mBindFlags); | 154 mBound = mContext.bindService(intent, this, mBindFlags); |
146 } | 155 } |
147 return mBound; | 156 return mBound; |
148 } | 157 } |
149 | 158 |
150 void unbind() { | 159 void unbind() { |
151 if (mBound) { | 160 if (mBound) { |
152 mContext.unbindService(this); | 161 mContext.unbindService(this); |
153 mBound = false; | 162 mBound = false; |
154 } | 163 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 } | 206 } |
198 // TODO(ppi): does anyone know why we need to do that? | 207 // TODO(ppi): does anyone know why we need to do that? |
199 if (disconnectedWhileBeingSetUp && mConnectionCallback != null) { | 208 if (disconnectedWhileBeingSetUp && mConnectionCallback != null) { |
200 mConnectionCallback.onConnected(0); | 209 mConnectionCallback.onConnected(0); |
201 } | 210 } |
202 } | 211 } |
203 } | 212 } |
204 | 213 |
205 ChildProcessConnection(Context context, int number, boolean inSandbox, | 214 ChildProcessConnection(Context context, int number, boolean inSandbox, |
206 ChildProcessConnection.DeathCallback deathCallback, | 215 ChildProcessConnection.DeathCallback deathCallback, |
207 Class<? extends ChildProcessService> serviceClass) { | 216 Class<? extends ChildProcessService> serviceClass, |
| 217 LinkerParams linkerParams) { |
208 mContext = context; | 218 mContext = context; |
209 mServiceNumber = number; | 219 mServiceNumber = number; |
210 mInSandbox = inSandbox; | 220 mInSandbox = inSandbox; |
211 mDeathCallback = deathCallback; | 221 mDeathCallback = deathCallback; |
212 mServiceClass = serviceClass; | 222 mServiceClass = serviceClass; |
| 223 mLinkerParams = linkerParams; |
213 mInitialBinding = new ChildServiceConnection(Context.BIND_AUTO_CREATE); | 224 mInitialBinding = new ChildServiceConnection(Context.BIND_AUTO_CREATE); |
214 mStrongBinding = new ChildServiceConnection( | 225 mStrongBinding = new ChildServiceConnection( |
215 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT); | 226 Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT); |
216 mWaivedBinding = new ChildServiceConnection( | 227 mWaivedBinding = new ChildServiceConnection( |
217 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY); | 228 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY); |
218 } | 229 } |
219 | 230 |
220 int getServiceNumber() { | 231 int getServiceNumber() { |
221 return mServiceNumber; | 232 return mServiceNumber; |
222 } | 233 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 * @param commandLine (Optional) will be ignored if the command line was alr
eady sent in bind() | 277 * @param commandLine (Optional) will be ignored if the command line was alr
eady sent in bind() |
267 * @param fileToBeMapped a list of file descriptors that should be registere
d | 278 * @param fileToBeMapped a list of file descriptors that should be registere
d |
268 * @param callback Used for status updates regarding this process connection
. | 279 * @param callback Used for status updates regarding this process connection
. |
269 * @param connectionCallbacks will notify the consumer about the connection
being established | 280 * @param connectionCallbacks will notify the consumer about the connection
being established |
270 * and the status of the out-of-memory bindings being bound for the connecti
on. | 281 * and the status of the out-of-memory bindings being bound for the connecti
on. |
271 */ | 282 */ |
272 void setupConnection( | 283 void setupConnection( |
273 String[] commandLine, | 284 String[] commandLine, |
274 FileDescriptorInfo[] filesToBeMapped, | 285 FileDescriptorInfo[] filesToBeMapped, |
275 IChildProcessCallback processCallback, | 286 IChildProcessCallback processCallback, |
276 ConnectionCallback connectionCallbacks) { | 287 ConnectionCallback connectionCallbacks, |
| 288 Bundle sharedRelros) { |
277 synchronized(mLock) { | 289 synchronized(mLock) { |
278 TraceEvent.begin(); | 290 TraceEvent.begin(); |
279 assert mConnectionParams == null; | 291 assert mConnectionParams == null; |
280 mConnectionCallback = connectionCallbacks; | 292 mConnectionCallback = connectionCallbacks; |
281 mConnectionParams = new ConnectionParams(commandLine, filesToBeMappe
d, processCallback); | 293 mConnectionParams = new ConnectionParams( |
| 294 commandLine, filesToBeMapped, processCallback, sharedRelros)
; |
282 // Make sure that the service is already connected. If not, doConnec
tionSetup() will be | 295 // Make sure that the service is already connected. If not, doConnec
tionSetup() will be |
283 // called from onServiceConnected(). | 296 // called from onServiceConnected(). |
284 if (mServiceConnectComplete) { | 297 if (mServiceConnectComplete) { |
285 doConnectionSetup(); | 298 doConnectionSetup(); |
286 } | 299 } |
287 TraceEvent.end(); | 300 TraceEvent.end(); |
288 } | 301 } |
289 } | 302 } |
290 | 303 |
291 /** | 304 /** |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 } | 367 } |
355 | 368 |
356 } | 369 } |
357 bundle.putParcelable(fdName, parcelFiles[i]); | 370 bundle.putParcelable(fdName, parcelFiles[i]); |
358 bundle.putInt(idName, fileInfos[i].mId); | 371 bundle.putInt(idName, fileInfos[i].mId); |
359 } | 372 } |
360 // Add the CPU properties now. | 373 // Add the CPU properties now. |
361 bundle.putInt(EXTRA_CPU_COUNT, CpuFeatures.getCount()); | 374 bundle.putInt(EXTRA_CPU_COUNT, CpuFeatures.getCount()); |
362 bundle.putLong(EXTRA_CPU_FEATURES, CpuFeatures.getMask()); | 375 bundle.putLong(EXTRA_CPU_FEATURES, CpuFeatures.getMask()); |
363 | 376 |
| 377 bundle.putBundle(Linker.EXTRA_LINKER_SHARED_RELROS, |
| 378 mConnectionParams.mSharedRelros); |
| 379 |
364 try { | 380 try { |
365 mPID = mService.setupConnection(bundle, mConnectionParams.mCallb
ack); | 381 mPID = mService.setupConnection(bundle, mConnectionParams.mCallb
ack); |
366 } catch (android.os.RemoteException re) { | 382 } catch (android.os.RemoteException re) { |
367 Log.e(TAG, "Failed to setup connection.", re); | 383 Log.e(TAG, "Failed to setup connection.", re); |
368 } | 384 } |
369 // We proactively close the FDs rather than wait for GC & finalizer. | 385 // We proactively close the FDs rather than wait for GC & finalizer. |
370 try { | 386 try { |
371 for (ParcelFileDescriptor parcelFile : parcelFiles) { | 387 for (ParcelFileDescriptor parcelFile : parcelFiles) { |
372 if (parcelFile != null) parcelFile.close(); | 388 if (parcelFile != null) parcelFile.close(); |
373 } | 389 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 | 474 |
459 /** | 475 /** |
460 * @return The connection PID, or 0 if not yet connected. | 476 * @return The connection PID, or 0 if not yet connected. |
461 */ | 477 */ |
462 int getPid() { | 478 int getPid() { |
463 synchronized(mLock) { | 479 synchronized(mLock) { |
464 return mPID; | 480 return mPID; |
465 } | 481 } |
466 } | 482 } |
467 } | 483 } |
OLD | NEW |