| 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.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
| 8 import android.app.Service; |
| 8 import android.content.Context; | 9 import android.content.Context; |
| 9 import android.content.Intent; | 10 import android.content.Intent; |
| 10 import android.content.pm.ApplicationInfo; | 11 import android.content.pm.ApplicationInfo; |
| 11 import android.content.pm.PackageManager; | 12 import android.content.pm.PackageManager; |
| 12 import android.graphics.SurfaceTexture; | 13 import android.graphics.SurfaceTexture; |
| 13 import android.os.Build; | 14 import android.os.Build; |
| 14 import android.os.Bundle; | 15 import android.os.Bundle; |
| 15 import android.os.ParcelFileDescriptor; | 16 import android.os.ParcelFileDescriptor; |
| 16 import android.os.RemoteException; | 17 import android.os.RemoteException; |
| 17 import android.text.TextUtils; | 18 import android.text.TextUtils; |
| 18 import android.util.Pair; | 19 import android.util.Pair; |
| 19 import android.view.Surface; | 20 import android.view.Surface; |
| 20 | 21 |
| 21 import org.chromium.base.CommandLine; | 22 import org.chromium.base.CommandLine; |
| 22 import org.chromium.base.CpuFeatures; | 23 import org.chromium.base.CpuFeatures; |
| 23 import org.chromium.base.Log; | 24 import org.chromium.base.Log; |
| 24 import org.chromium.base.ThreadUtils; | 25 import org.chromium.base.ThreadUtils; |
| 25 import org.chromium.base.TraceEvent; | 26 import org.chromium.base.TraceEvent; |
| 26 import org.chromium.base.VisibleForTesting; | 27 import org.chromium.base.VisibleForTesting; |
| 27 import org.chromium.base.annotations.CalledByNative; | 28 import org.chromium.base.annotations.CalledByNative; |
| 28 import org.chromium.base.annotations.JNINamespace; | 29 import org.chromium.base.annotations.JNINamespace; |
| 29 import org.chromium.base.library_loader.Linker; | 30 import org.chromium.base.library_loader.Linker; |
| 30 import org.chromium.content.app.ChildProcessService; | |
| 31 import org.chromium.content.app.ChromiumLinkerParams; | 31 import org.chromium.content.app.ChromiumLinkerParams; |
| 32 import org.chromium.content.app.DownloadProcessService; | 32 import org.chromium.content.app.DownloadProcessService; |
| 33 import org.chromium.content.app.PrivilegedProcessService; | 33 import org.chromium.content.app.PrivilegedProcessService; |
| 34 import org.chromium.content.app.SandboxedProcessService; | 34 import org.chromium.content.app.SandboxedProcessService; |
| 35 import org.chromium.content.common.ContentSwitches; | 35 import org.chromium.content.common.ContentSwitches; |
| 36 import org.chromium.content.common.IChildProcessCallback; | 36 import org.chromium.content.common.IChildProcessCallback; |
| 37 import org.chromium.content.common.SurfaceWrapper; | 37 import org.chromium.content.common.SurfaceWrapper; |
| 38 | 38 |
| 39 import java.io.IOException; | 39 import java.io.IOException; |
| 40 import java.util.ArrayList; | 40 import java.util.ArrayList; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 58 | 58 |
| 59 private static class ChildConnectionAllocator { | 59 private static class ChildConnectionAllocator { |
| 60 // Connections to services. Indices of the array correspond to the servi
ce numbers. | 60 // Connections to services. Indices of the array correspond to the servi
ce numbers. |
| 61 private final ChildProcessConnection[] mChildProcessConnections; | 61 private final ChildProcessConnection[] mChildProcessConnections; |
| 62 | 62 |
| 63 // The list of free (not bound) service indices. | 63 // The list of free (not bound) service indices. |
| 64 // SHOULD BE ACCESSED WITH mConnectionLock. | 64 // SHOULD BE ACCESSED WITH mConnectionLock. |
| 65 private final ArrayList<Integer> mFreeConnectionIndices; | 65 private final ArrayList<Integer> mFreeConnectionIndices; |
| 66 private final Object mConnectionLock = new Object(); | 66 private final Object mConnectionLock = new Object(); |
| 67 | 67 |
| 68 private Class<? extends ChildProcessService> mChildClass; | 68 private Class<? extends Service> mChildClass; |
| 69 private final boolean mInSandbox; | 69 private final boolean mInSandbox; |
| 70 // Each Allocator keeps a queue for the pending spawn data. Once a conne
ction is free, we | 70 // Each Allocator keeps a queue for the pending spawn data. Once a conne
ction is free, we |
| 71 // dequeue the pending spawn data from the same allocator as the connect
ion. | 71 // dequeue the pending spawn data from the same allocator as the connect
ion. |
| 72 private final PendingSpawnQueue mPendingSpawnQueue = new PendingSpawnQue
ue(); | 72 private final PendingSpawnQueue mPendingSpawnQueue = new PendingSpawnQue
ue(); |
| 73 | 73 |
| 74 public ChildConnectionAllocator(boolean inSandbox, int numChildServices)
{ | 74 public ChildConnectionAllocator(boolean inSandbox, int numChildServices, |
| 75 Class<? extends Service> serviceName) { |
| 75 mChildProcessConnections = new ChildProcessConnectionImpl[numChildSe
rvices]; | 76 mChildProcessConnections = new ChildProcessConnectionImpl[numChildSe
rvices]; |
| 76 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); | 77 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); |
| 77 for (int i = 0; i < numChildServices; i++) { | 78 for (int i = 0; i < numChildServices; i++) { |
| 78 mFreeConnectionIndices.add(i); | 79 mFreeConnectionIndices.add(i); |
| 79 } | 80 } |
| 80 mChildClass = | 81 if (serviceName == null) { |
| 81 inSandbox ? SandboxedProcessService.class : PrivilegedProces
sService.class; | 82 mChildClass = inSandbox ? SandboxedProcessService.class |
| 83 : PrivilegedProcessService.class; |
| 84 } else { |
| 85 mChildClass = serviceName; |
| 86 } |
| 82 mInSandbox = inSandbox; | 87 mInSandbox = inSandbox; |
| 83 } | 88 } |
| 84 | 89 |
| 85 public ChildProcessConnection allocate( | 90 public ChildProcessConnection allocate( |
| 86 Context context, ChildProcessConnection.DeathCallback deathCallb
ack, | 91 Context context, ChildProcessConnection.DeathCallback deathCallb
ack, |
| 87 ChromiumLinkerParams chromiumLinkerParams, | 92 ChromiumLinkerParams chromiumLinkerParams, |
| 88 boolean alwaysInForeground, | 93 boolean alwaysInForeground, |
| 89 ChildProcessCreationParams creationParams) { | 94 ChildProcessCreationParams creationParams) { |
| 90 synchronized (mConnectionLock) { | 95 synchronized (mConnectionLock) { |
| 91 if (mFreeConnectionIndices.isEmpty()) { | 96 if (mFreeConnectionIndices.isEmpty()) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 if (numServices < 0) { | 271 if (numServices < 0) { |
| 267 throw new RuntimeException("Illegal meta data value for number o
f child services"); | 272 throw new RuntimeException("Illegal meta data value for number o
f child services"); |
| 268 } | 273 } |
| 269 return numServices; | 274 return numServices; |
| 270 } catch (PackageManager.NameNotFoundException e) { | 275 } catch (PackageManager.NameNotFoundException e) { |
| 271 throw new RuntimeException("Could not get application info"); | 276 throw new RuntimeException("Could not get application info"); |
| 272 } | 277 } |
| 273 } | 278 } |
| 274 | 279 |
| 275 private static void initConnectionAllocatorsIfNecessary( | 280 private static void initConnectionAllocatorsIfNecessary( |
| 276 Context context, boolean inSandbox, String packageName) { | 281 Context context, boolean inSandbox, String packageName, |
| 282 Class<? extends Service> serviceName) { |
| 277 // TODO(mariakhomenko): Uses an Object to lock the access. | 283 // TODO(mariakhomenko): Uses an Object to lock the access. |
| 278 synchronized (ChildProcessLauncher.class) { | 284 synchronized (ChildProcessLauncher.class) { |
| 279 if (inSandbox) { | 285 if (inSandbox) { |
| 280 if (sSandboxedChildConnectionAllocatorMap == null) { | 286 if (sSandboxedChildConnectionAllocatorMap == null) { |
| 281 sSandboxedChildConnectionAllocatorMap = | 287 sSandboxedChildConnectionAllocatorMap = |
| 282 new ConcurrentHashMap<String, ChildConnectionAllocat
or>(); | 288 new ConcurrentHashMap<String, ChildConnectionAllocat
or>(); |
| 283 } | 289 } |
| 284 if (!sSandboxedChildConnectionAllocatorMap.containsKey(packageNa
me)) { | 290 if (!sSandboxedChildConnectionAllocatorMap.containsKey(packageNa
me)) { |
| 285 Log.w(TAG, "Create a new ChildConnectionAllocator with packa
ge name = %s," | 291 Log.w(TAG, "Create a new ChildConnectionAllocator with packa
ge name = %s," |
| 286 + " inSandbox = true", | 292 + " inSandbox = true", |
| 287 packageName); | 293 packageName); |
| 288 sSandboxedChildConnectionAllocatorMap.put(packageName, | 294 sSandboxedChildConnectionAllocatorMap.put(packageName, |
| 289 new ChildConnectionAllocator(true, | 295 new ChildConnectionAllocator(true, |
| 290 getNumberOfServices(context, true, packageNa
me))); | 296 getNumberOfServices(context, true, packageNa
me), serviceName)); |
| 291 } | 297 } |
| 292 } else if (sPrivilegedChildConnectionAllocator == null) { | 298 } else if (sPrivilegedChildConnectionAllocator == null) { |
| 293 sPrivilegedChildConnectionAllocator = new ChildConnectionAllocat
or( | 299 sPrivilegedChildConnectionAllocator = new ChildConnectionAllocat
or( |
| 294 false, getNumberOfServices(context, false, packageName))
; | 300 false, getNumberOfServices(context, false, packageName),
serviceName); |
| 295 } | 301 } |
| 296 // TODO(pkotwicz|hanxi): Figure out when old allocators should be re
moved from | 302 // TODO(pkotwicz|hanxi): Figure out when old allocators should be re
moved from |
| 297 // {@code sSandboxedChildConnectionAllocatorMap}. | 303 // {@code sSandboxedChildConnectionAllocatorMap}. |
| 298 } | 304 } |
| 299 } | 305 } |
| 300 | 306 |
| 301 /** | 307 /** |
| 302 * Note: please make sure that the Allocator has been initialized before cal
ling this function. | 308 * Note: please make sure that the Allocator has been initialized before cal
ling this function. |
| 303 * Otherwise, always calls {@link initConnectionAllocatorsIfNecessary} first
. | 309 * Otherwise, always calls {@link initConnectionAllocatorsIfNecessary} first
. |
| 304 */ | 310 */ |
| 305 private static ChildConnectionAllocator getConnectionAllocator( | 311 private static ChildConnectionAllocator getConnectionAllocator( |
| 306 String packageName, boolean inSandbox) { | 312 String packageName, boolean inSandbox) { |
| 307 if (!inSandbox) { | 313 if (!inSandbox) { |
| 308 return sPrivilegedChildConnectionAllocator; | 314 return sPrivilegedChildConnectionAllocator; |
| 309 } | 315 } |
| 310 return sSandboxedChildConnectionAllocatorMap.get(packageName); | 316 return sSandboxedChildConnectionAllocatorMap.get(packageName); |
| 311 } | 317 } |
| 312 | 318 |
| 313 /** | 319 /** |
| 314 * Get the PendingSpawnQueue of the Allocator. Initialize the Allocator if n
eeded. | 320 * Get the PendingSpawnQueue of the Allocator. Initialize the Allocator if n
eeded. |
| 315 */ | 321 */ |
| 316 private static PendingSpawnQueue getPendingSpawnQueue(Context context, Strin
g packageName, | 322 private static PendingSpawnQueue getPendingSpawnQueue(Context context, Strin
g packageName, |
| 317 boolean inSandbox) { | 323 boolean inSandbox, Class<? extends Service> serviceName) { |
| 318 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); | 324 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName, ser
viceName); |
| 319 return getConnectionAllocator(packageName, inSandbox).getPendingSpawnQue
ue(); | 325 return getConnectionAllocator(packageName, inSandbox).getPendingSpawnQue
ue(); |
| 320 } | 326 } |
| 321 | 327 |
| 322 private static ChildProcessConnection allocateConnection(Context context, bo
olean inSandbox, | 328 private static ChildProcessConnection allocateConnection(Context context, bo
olean inSandbox, |
| 323 ChromiumLinkerParams chromiumLinkerParams, boolean alwaysInForegroun
d, | 329 ChromiumLinkerParams chromiumLinkerParams, boolean alwaysInForegroun
d, |
| 324 ChildProcessCreationParams creationParams) { | 330 ChildProcessCreationParams creationParams) { |
| 325 ChildProcessConnection.DeathCallback deathCallback = | 331 ChildProcessConnection.DeathCallback deathCallback = |
| 326 new ChildProcessConnection.DeathCallback() { | 332 new ChildProcessConnection.DeathCallback() { |
| 327 @Override | 333 @Override |
| 328 public void onChildProcessDied(ChildProcessConnection connec
tion) { | 334 public void onChildProcessDied(ChildProcessConnection connec
tion) { |
| 329 if (connection.getPid() != 0) { | 335 if (connection.getPid() != 0) { |
| 330 stop(connection.getPid()); | 336 stop(connection.getPid()); |
| 331 } else { | 337 } else { |
| 332 freeConnection(connection); | 338 freeConnection(connection); |
| 333 } | 339 } |
| 334 } | 340 } |
| 335 }; | 341 }; |
| 336 String packageName = creationParams != null ? creationParams.getPackageN
ame() | 342 String packageName = creationParams != null ? creationParams.getPackageN
ame() |
| 337 : context.getPackageName(); | 343 : context.getPackageName(); |
| 338 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName); | 344 Class<? extends Service> serviceName = creationParams != null |
| 339 return getConnectionAllocator(packageName, inSandbox) | 345 ? creationParams.getServiceName() : null; |
| 340 .allocate(context, deathCallback, chromiumLinkerParams, alwaysIn
Foreground, | 346 initConnectionAllocatorsIfNecessary(context, inSandbox, packageName, ser
viceName); |
| 341 creationParams); | 347 return getConnectionAllocator(packageName, inSandbox).allocate( |
| 348 context, deathCallback, chromiumLinkerParams, alwaysInForeground
, |
| 349 creationParams); |
| 342 } | 350 } |
| 343 | 351 |
| 344 private static boolean sLinkerInitialized = false; | 352 private static boolean sLinkerInitialized = false; |
| 345 private static long sLinkerLoadAddress = 0; | 353 private static long sLinkerLoadAddress = 0; |
| 346 | 354 |
| 347 private static ChromiumLinkerParams getLinkerParamsForNewConnection() { | 355 private static ChromiumLinkerParams getLinkerParamsForNewConnection() { |
| 348 if (!sLinkerInitialized) { | 356 if (!sLinkerInitialized) { |
| 349 if (Linker.isUsed()) { | 357 if (Linker.isUsed()) { |
| 350 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress(); | 358 sLinkerLoadAddress = Linker.getInstance().getBaseLoadAddress(); |
| 351 if (sLinkerLoadAddress == 0) { | 359 if (sLinkerLoadAddress == 0) { |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 synchronized (ChildProcessLauncher.class) { | 731 synchronized (ChildProcessLauncher.class) { |
| 724 if (inSandbox && sSpareSandboxedConnection != null | 732 if (inSandbox && sSpareSandboxedConnection != null |
| 725 && sSpareSandboxedConnection.getPackageName().equals(pac
kageName)) { | 733 && sSpareSandboxedConnection.getPackageName().equals(pac
kageName)) { |
| 726 allocatedConnection = sSpareSandboxedConnection; | 734 allocatedConnection = sSpareSandboxedConnection; |
| 727 sSpareSandboxedConnection = null; | 735 sSpareSandboxedConnection = null; |
| 728 } | 736 } |
| 729 } | 737 } |
| 730 if (allocatedConnection == null) { | 738 if (allocatedConnection == null) { |
| 731 boolean alwaysInForeground = false; | 739 boolean alwaysInForeground = false; |
| 732 if (callbackType == CALLBACK_FOR_GPU_PROCESS) alwaysInForeground
= true; | 740 if (callbackType == CALLBACK_FOR_GPU_PROCESS) alwaysInForeground
= true; |
| 741 Class<? extends Service> serviceName = creationParams != null |
| 742 ? creationParams.getServiceName() : null; |
| 733 PendingSpawnQueue pendingSpawnQueue = getPendingSpawnQueue( | 743 PendingSpawnQueue pendingSpawnQueue = getPendingSpawnQueue( |
| 734 context, packageName, inSandbox); | 744 context, packageName, inSandbox, serviceName); |
| 735 synchronized (pendingSpawnQueue.mPendingSpawnsLock) { | 745 synchronized (pendingSpawnQueue.mPendingSpawnsLock) { |
| 736 allocatedConnection = allocateBoundConnection( | 746 allocatedConnection = allocateBoundConnection( |
| 737 context, commandLine, inSandbox, alwaysInForeground,
creationParams); | 747 context, commandLine, inSandbox, alwaysInForeground,
creationParams); |
| 738 if (allocatedConnection == null) { | 748 if (allocatedConnection == null) { |
| 739 Log.d(TAG, "Allocation of new service failed. Queuing up
pending spawn."); | 749 Log.d(TAG, "Allocation of new service failed. Queuing up
pending spawn."); |
| 740 pendingSpawnQueue.enqueueLocked(new PendingSpawnData(con
text, commandLine, | 750 pendingSpawnQueue.enqueueLocked(new PendingSpawnData(con
text, commandLine, |
| 741 childProcessId, filesToBeMapped, clientContext, | 751 childProcessId, filesToBeMapped, clientContext, |
| 742 callbackType, inSandbox, creationParams)); | 752 callbackType, inSandbox, creationParams)); |
| 743 return; | 753 return; |
| 744 } | 754 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 ChildProcessCreationParams creationParams) { | 930 ChildProcessCreationParams creationParams) { |
| 921 return allocateBoundConnection(context, null, true, false, creationParam
s); | 931 return allocateBoundConnection(context, null, true, false, creationParam
s); |
| 922 } | 932 } |
| 923 | 933 |
| 924 /** | 934 /** |
| 925 * Queue up a spawn requests for testing. | 935 * Queue up a spawn requests for testing. |
| 926 */ | 936 */ |
| 927 @VisibleForTesting | 937 @VisibleForTesting |
| 928 static void enqueuePendingSpawnForTesting(Context context, String[] commandL
ine, | 938 static void enqueuePendingSpawnForTesting(Context context, String[] commandL
ine, |
| 929 ChildProcessCreationParams creationParams, boolean inSandbox) { | 939 ChildProcessCreationParams creationParams, boolean inSandbox) { |
| 940 String packageName = creationParams != null ? creationParams.getPackageN
ame() |
| 941 : context.getPackageName(); |
| 942 Class<? extends Service> serviceName = creationParams != null |
| 943 ? creationParams.getServiceName() : null; |
| 930 PendingSpawnQueue pendingSpawnQueue = getPendingSpawnQueue(context, | 944 PendingSpawnQueue pendingSpawnQueue = getPendingSpawnQueue(context, |
| 931 creationParams.getPackageName(), inSandbox); | 945 packageName, inSandbox, serviceName); |
| 932 synchronized (pendingSpawnQueue.mPendingSpawnsLock) { | 946 synchronized (pendingSpawnQueue.mPendingSpawnsLock) { |
| 933 pendingSpawnQueue.enqueueLocked(new PendingSpawnData(context, comman
dLine, 1, | 947 pendingSpawnQueue.enqueueLocked(new PendingSpawnData(context, comman
dLine, 1, |
| 934 new FileDescriptorInfo[0], 0, CALLBACK_FOR_RENDERER_PROCESS,
true, | 948 new FileDescriptorInfo[0], 0, CALLBACK_FOR_RENDERER_PROCESS,
true, |
| 935 creationParams)); | 949 creationParams)); |
| 936 } | 950 } |
| 937 } | 951 } |
| 938 | 952 |
| 939 /** | 953 /** |
| 940 * @return the number of sandboxed connections of given {@link packageName}
managed by the | 954 * @return the number of sandboxed connections of given {@link packageName}
managed by the |
| 941 * allocator. | 955 * allocator. |
| 942 */ | 956 */ |
| 943 @VisibleForTesting | 957 @VisibleForTesting |
| 944 static int allocatedSandboxedConnectionsCountForTesting(Context context, Str
ing packageName) { | 958 static int allocatedSandboxedConnectionsCountForTesting(Context context, Str
ing packageName) { |
| 945 initConnectionAllocatorsIfNecessary(context, true, packageName); | 959 initConnectionAllocatorsIfNecessary(context, true, packageName, null); |
| 946 return sSandboxedChildConnectionAllocatorMap.get(packageName) | 960 return sSandboxedChildConnectionAllocatorMap.get(packageName) |
| 947 .allocatedConnectionsCountForTesting(); | 961 .allocatedConnectionsCountForTesting(); |
| 948 } | 962 } |
| 949 | 963 |
| 950 /** @return the count of services set up and working */ | 964 /** @return the count of services set up and working */ |
| 951 @VisibleForTesting | 965 @VisibleForTesting |
| 952 static int connectedServicesCountForTesting() { | 966 static int connectedServicesCountForTesting() { |
| 953 return sServiceMap.size(); | 967 return sServiceMap.size(); |
| 954 } | 968 } |
| 955 | 969 |
| 956 /** | 970 /** |
| 957 * @param context The context. | 971 * @param context The context. |
| 958 * @param packageName The package name of the {@link ChildProcessAlocator}. | 972 * @param packageName The package name of the {@link ChildProcessAlocator}. |
| 959 * @param inSandbox Whether the connection is sandboxed. | 973 * @param inSandbox Whether the connection is sandboxed. |
| 960 * @return the count of pending spawns in the queue. | 974 * @return the count of pending spawns in the queue. |
| 961 */ | 975 */ |
| 962 @VisibleForTesting | 976 @VisibleForTesting |
| 963 static int pendingSpawnsCountForTesting(Context context, String packageName, | 977 static int pendingSpawnsCountForTesting(Context context, String packageName, |
| 964 boolean inSandbox) { | 978 boolean inSandbox) { |
| 965 PendingSpawnQueue pendingSpawnQueue = getPendingSpawnQueue(context, pack
ageName, inSandbox); | 979 PendingSpawnQueue pendingSpawnQueue = getPendingSpawnQueue(context, pack
ageName, inSandbox, |
| 980 null); |
| 966 synchronized (pendingSpawnQueue.mPendingSpawnsLock) { | 981 synchronized (pendingSpawnQueue.mPendingSpawnsLock) { |
| 967 return pendingSpawnQueue.sizeLocked(); | 982 return pendingSpawnQueue.sizeLocked(); |
| 968 } | 983 } |
| 969 } | 984 } |
| 970 | 985 |
| 971 /** | 986 /** |
| 972 * Kills the child process for testing. | 987 * Kills the child process for testing. |
| 973 * @return true iff the process was killed as expected | 988 * @return true iff the process was killed as expected |
| 974 */ | 989 */ |
| 975 @VisibleForTesting | 990 @VisibleForTesting |
| 976 public static boolean crashProcessForTesting(int pid) { | 991 public static boolean crashProcessForTesting(int pid) { |
| 977 if (sServiceMap.get(pid) == null) return false; | 992 if (sServiceMap.get(pid) == null) return false; |
| 978 | 993 |
| 979 try { | 994 try { |
| 980 ((ChildProcessConnectionImpl) sServiceMap.get(pid)).crashServiceForT
esting(); | 995 ((ChildProcessConnectionImpl) sServiceMap.get(pid)).crashServiceForT
esting(); |
| 981 } catch (RemoteException ex) { | 996 } catch (RemoteException ex) { |
| 982 return false; | 997 return false; |
| 983 } | 998 } |
| 984 | 999 |
| 985 return true; | 1000 return true; |
| 986 } | 1001 } |
| 987 | 1002 |
| 988 private static native void nativeOnChildProcessStarted(long clientContext, i
nt pid); | 1003 private static native void nativeOnChildProcessStarted(long clientContext, i
nt pid); |
| 989 private static native void nativeEstablishSurfacePeer( | 1004 private static native void nativeEstablishSurfacePeer( |
| 990 int pid, Surface surface, int primaryID, int secondaryID); | 1005 int pid, Surface surface, int primaryID, int secondaryID); |
| 991 private static native boolean nativeIsSingleProcess(); | 1006 private static native boolean nativeIsSingleProcess(); |
| 992 } | 1007 } |
| OLD | NEW |