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.Context; | 7 import android.content.Context; |
8 import android.util.Log; | 8 import android.util.Log; |
| 9 import android.util.SparseIntArray; |
9 import android.view.Surface; | 10 import android.view.Surface; |
10 | 11 |
11 import java.util.ArrayList; | 12 import java.util.ArrayList; |
12 import java.util.Map; | 13 import java.util.Map; |
13 import java.util.concurrent.ConcurrentHashMap; | 14 import java.util.concurrent.ConcurrentHashMap; |
14 | 15 |
15 import org.chromium.base.CalledByNative; | 16 import org.chromium.base.CalledByNative; |
16 import org.chromium.base.JNINamespace; | 17 import org.chromium.base.JNINamespace; |
17 import org.chromium.base.ThreadUtils; | 18 import org.chromium.base.ThreadUtils; |
18 import org.chromium.content.app.ChildProcessService; | 19 import org.chromium.content.app.ChildProcessService; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 return; | 168 return; |
168 } | 169 } |
169 | 170 |
170 // Represents an invalid process handle; same as base/process/process.h kNul
lProcessHandle. | 171 // Represents an invalid process handle; same as base/process/process.h kNul
lProcessHandle. |
171 private static final int NULL_PROCESS_HANDLE = 0; | 172 private static final int NULL_PROCESS_HANDLE = 0; |
172 | 173 |
173 // Map from pid to ChildService connection. | 174 // Map from pid to ChildService connection. |
174 private static Map<Integer, ChildProcessConnection> mServiceMap = | 175 private static Map<Integer, ChildProcessConnection> mServiceMap = |
175 new ConcurrentHashMap<Integer, ChildProcessConnection>(); | 176 new ConcurrentHashMap<Integer, ChildProcessConnection>(); |
176 | 177 |
| 178 // Map from pid to the count of oom bindings. "Oom binding" is a binding tha
t raises the process |
| 179 // oom priority so that it shouldn't be killed by the OS out-of-memory kille
r under normal |
| 180 // conditions (it can still be killed under drastic memory pressure). |
| 181 private static SparseIntArray sOomBindingCount = new SparseIntArray(); |
| 182 |
177 // A pre-allocated and pre-bound connection ready for connection setup, or n
ull. | 183 // A pre-allocated and pre-bound connection ready for connection setup, or n
ull. |
178 static ChildProcessConnection mSpareSandboxedConnection = null; | 184 static ChildProcessConnection mSpareSandboxedConnection = null; |
179 | 185 |
180 /** | 186 /** |
181 * Returns the child process service interface for the given pid. This may b
e called on | 187 * Returns the child process service interface for the given pid. This may b
e called on |
182 * any thread, but the caller must assume that the service can disconnect at
any time. All | 188 * any thread, but the caller must assume that the service can disconnect at
any time. All |
183 * service calls should catch and handle android.os.RemoteException. | 189 * service calls should catch and handle android.os.RemoteException. |
184 * | 190 * |
185 * @param pid The pid (process handle) of the service obtained from {@link #
start}. | 191 * @param pid The pid (process handle) of the service obtained from {@link #
start}. |
186 * @return The IChildProcessService or null if the service no longer exists. | 192 * @return The IChildProcessService or null if the service no longer exists. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 if (allocatedConnection == null) { | 279 if (allocatedConnection == null) { |
274 allocatedConnection = allocateBoundConnection(context, commandLine,
inSandbox); | 280 allocatedConnection = allocateBoundConnection(context, commandLine,
inSandbox); |
275 if (allocatedConnection == null) { | 281 if (allocatedConnection == null) { |
276 // Notify the native code so it can free the heap allocated call
back. | 282 // Notify the native code so it can free the heap allocated call
back. |
277 nativeOnChildProcessStarted(clientContext, 0); | 283 nativeOnChildProcessStarted(clientContext, 0); |
278 return; | 284 return; |
279 } | 285 } |
280 } | 286 } |
281 final ChildProcessConnection connection = allocatedConnection; | 287 final ChildProcessConnection connection = allocatedConnection; |
282 Log.d(TAG, "Setting up connection to process: slot=" + connection.getSer
viceNumber()); | 288 Log.d(TAG, "Setting up connection to process: slot=" + connection.getSer
viceNumber()); |
283 // Note: This runnable will be executed when the child connection is set
up. | 289 |
284 final Runnable onConnect = new Runnable() { | 290 ChildProcessConnection.ConnectionCallbacks connectionCallbacks = |
285 @Override | 291 new ChildProcessConnection.ConnectionCallbacks() { |
286 public void run() { | 292 public void onConnected(int pid, int oomBindingCount) { |
287 final int pid = connection.getPid(); | |
288 Log.d(TAG, "on connect callback, pid=" + pid + " context=" + cli
entContext); | 293 Log.d(TAG, "on connect callback, pid=" + pid + " context=" + cli
entContext); |
289 if (pid != NULL_PROCESS_HANDLE) { | 294 if (pid != NULL_PROCESS_HANDLE) { |
| 295 sOomBindingCount.put(pid, oomBindingCount); |
290 mServiceMap.put(pid, connection); | 296 mServiceMap.put(pid, connection); |
291 } else { | 297 } else { |
292 freeConnection(connection); | 298 freeConnection(connection); |
293 } | 299 } |
294 nativeOnChildProcessStarted(clientContext, pid); | 300 nativeOnChildProcessStarted(clientContext, pid); |
295 } | 301 } |
| 302 |
| 303 public void onOomBindingAdded(int pid) { |
| 304 if (pid != NULL_PROCESS_HANDLE) { |
| 305 sOomBindingCount.put(pid, sOomBindingCount.get(pid) + 1); |
| 306 } |
| 307 } |
| 308 |
| 309 public void onOomBindingRemoved(int pid) { |
| 310 if (pid != NULL_PROCESS_HANDLE) { |
| 311 int count = sOomBindingCount.get(pid, -1); |
| 312 assert count > 0; |
| 313 count--; |
| 314 if (count > 0) { |
| 315 sOomBindingCount.put(pid, count); |
| 316 } else { |
| 317 sOomBindingCount.delete(pid); |
| 318 } |
| 319 } |
| 320 } |
296 }; | 321 }; |
| 322 |
297 // TODO(sievers): Revisit this as it doesn't correctly handle the utilit
y process | 323 // TODO(sievers): Revisit this as it doesn't correctly handle the utilit
y process |
298 // assert callbackType != CALLBACK_FOR_UNKNOWN_PROCESS; | 324 // assert callbackType != CALLBACK_FOR_UNKNOWN_PROCESS; |
299 | 325 |
300 connection.setupConnection( | 326 connection.setupConnection(commandLine, filesToBeMapped, createCallback(
callbackType), |
301 commandLine, filesToBeMapped, createCallback(callbackType), onCo
nnect); | 327 connectionCallbacks); |
302 } | 328 } |
303 | 329 |
304 /** | 330 /** |
305 * Terminates a child process. This may be called from any thread. | 331 * Terminates a child process. This may be called from any thread. |
306 * | 332 * |
307 * @param pid The pid (process handle) of the service connection obtained fr
om {@link #start}. | 333 * @param pid The pid (process handle) of the service connection obtained fr
om {@link #start}. |
308 */ | 334 */ |
309 @CalledByNative | 335 @CalledByNative |
310 static void stop(int pid) { | 336 static void stop(int pid) { |
311 Log.d(TAG, "stopping child connection: pid=" + pid); | 337 Log.d(TAG, "stopping child connection: pid=" + pid); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 static void unbindAsHighPriority(int pid) { | 382 static void unbindAsHighPriority(int pid) { |
357 ChildProcessConnection connection = mServiceMap.get(pid); | 383 ChildProcessConnection connection = mServiceMap.get(pid); |
358 if (connection == null) { | 384 if (connection == null) { |
359 LogPidWarning(pid, "Tried to unbind non-existent connection"); | 385 LogPidWarning(pid, "Tried to unbind non-existent connection"); |
360 return; | 386 return; |
361 } | 387 } |
362 connection.detachAsActive(); | 388 connection.detachAsActive(); |
363 } | 389 } |
364 | 390 |
365 /** | 391 /** |
| 392 * @return True iff the given service process is protected from the out-of-m
emory killing, or it |
| 393 * was protected from it when it died. |
| 394 */ |
| 395 public static boolean isOomProtected(int pid) { |
| 396 return sOomBindingCount.get(pid) > 0; |
| 397 } |
| 398 |
| 399 /** |
366 * This implementation is used to receive callbacks from the remote service. | 400 * This implementation is used to receive callbacks from the remote service. |
367 */ | 401 */ |
368 private static IChildProcessCallback createCallback(final int callbackType)
{ | 402 private static IChildProcessCallback createCallback(final int callbackType)
{ |
369 return new IChildProcessCallback.Stub() { | 403 return new IChildProcessCallback.Stub() { |
370 /** | 404 /** |
371 * This is called by the remote service regularly to tell us about n
ew values. Note that | 405 * This is called by the remote service regularly to tell us about n
ew values. Note that |
372 * IPC calls are dispatched through a thread pool running in each pr
ocess, so the code | 406 * IPC calls are dispatched through a thread pool running in each pr
ocess, so the code |
373 * executing here will NOT be running in our main thread -- so, to u
pdate the UI, we | 407 * executing here will NOT be running in our main thread -- so, to u
pdate the UI, we |
374 * need to use a Handler. | 408 * need to use a Handler. |
375 */ | 409 */ |
(...skipping 29 matching lines...) Expand all Loading... |
405 Log.w(TAG, message + ", pid=" + pid); | 439 Log.w(TAG, message + ", pid=" + pid); |
406 } | 440 } |
407 } | 441 } |
408 | 442 |
409 private static native void nativeOnChildProcessStarted(int clientContext, in
t pid); | 443 private static native void nativeOnChildProcessStarted(int clientContext, in
t pid); |
410 private static native Surface nativeGetViewSurface(int surfaceId); | 444 private static native Surface nativeGetViewSurface(int surfaceId); |
411 private static native void nativeEstablishSurfacePeer( | 445 private static native void nativeEstablishSurfacePeer( |
412 int pid, Surface surface, int primaryID, int secondaryID); | 446 int pid, Surface surface, int primaryID, int secondaryID); |
413 private static native boolean nativeIsSingleProcess(); | 447 private static native boolean nativeIsSingleProcess(); |
414 } | 448 } |
OLD | NEW |