OLD | NEW |
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.ComponentName; | 7 import android.content.ComponentName; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.pm.ApplicationInfo; | 9 import android.content.pm.ApplicationInfo; |
10 import android.content.pm.PackageManager; | 10 import android.content.pm.PackageManager; |
(...skipping 30 matching lines...) Expand all Loading... |
41 // Map from package name to ChildConnectionAllocator. | 41 // Map from package name to ChildConnectionAllocator. |
42 private static Map<String, ChildConnectionAllocator> sSandboxedChildConnecti
onAllocatorMap; | 42 private static Map<String, ChildConnectionAllocator> sSandboxedChildConnecti
onAllocatorMap; |
43 | 43 |
44 // Allocator used for non-sandboxed services. | 44 // Allocator used for non-sandboxed services. |
45 private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator; | 45 private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator; |
46 | 46 |
47 // Used by test to override the default sandboxed service settings. | 47 // Used by test to override the default sandboxed service settings. |
48 private static int sSandboxedServicesCountForTesting = -1; | 48 private static int sSandboxedServicesCountForTesting = -1; |
49 private static String sSandboxedServicesNameForTesting; | 49 private static String sSandboxedServicesNameForTesting; |
50 | 50 |
| 51 // The factory used to create BaseChildProcessConnection instances. |
| 52 private final BaseChildProcessConnection.Factory mConnectionFactory; |
| 53 |
51 // Connections to services. Indices of the array correspond to the service n
umbers. | 54 // Connections to services. Indices of the array correspond to the service n
umbers. |
52 private final ChildProcessConnection[] mChildProcessConnections; | 55 private final BaseChildProcessConnection[] mChildProcessConnections; |
53 | 56 |
54 private final String mChildClassName; | 57 private final String mChildClassName; |
55 private final boolean mInSandbox; | 58 private final boolean mInSandbox; |
56 | 59 |
57 // The list of free (not bound) service indices. | 60 // The list of free (not bound) service indices. |
58 private final ArrayList<Integer> mFreeConnectionIndices; | 61 private final ArrayList<Integer> mFreeConnectionIndices; |
59 | 62 |
60 // Each Allocator keeps a queue for the pending spawn data. Once a connectio
n is free, we | 63 // Each Allocator keeps a queue for the pending spawn data. Once a connectio
n is free, we |
61 // dequeue the pending spawn data from the same allocator as the connection. | 64 // dequeue the pending spawn data from the same allocator as the connection. |
62 private final Queue<ChildSpawnData> mPendingSpawnQueue = new LinkedList<>(); | 65 private final Queue<ChildSpawnData> mPendingSpawnQueue = new LinkedList<>(); |
63 | 66 |
64 @SuppressFBWarnings("LI_LAZY_INIT_STATIC") // Method is single thread. | 67 @SuppressFBWarnings("LI_LAZY_INIT_STATIC") // Method is single thread. |
65 public static ChildConnectionAllocator getAllocator( | 68 public static ChildConnectionAllocator getAllocator( |
66 Context context, String packageName, boolean inSandbox) { | 69 Context context, String packageName, boolean sandboxed) { |
67 assert LauncherThread.runningOnLauncherThread(); | 70 assert LauncherThread.runningOnLauncherThread(); |
68 if (!inSandbox) { | 71 if (!sandboxed) { |
69 if (sPrivilegedChildConnectionAllocator == null) { | 72 if (sPrivilegedChildConnectionAllocator == null) { |
70 sPrivilegedChildConnectionAllocator = new ChildConnectionAllocat
or(false, | 73 sPrivilegedChildConnectionAllocator = new ChildConnectionAllocat
or( |
| 74 ImportantChildProcessConnection.FACTORY, false /* sandbo
xed */, |
71 getNumberOfServices(context, false, packageName), | 75 getNumberOfServices(context, false, packageName), |
72 getClassNameOfService(context, false, packageName)); | 76 getClassNameOfService(context, false, packageName)); |
73 } | 77 } |
74 return sPrivilegedChildConnectionAllocator; | 78 return sPrivilegedChildConnectionAllocator; |
75 } | 79 } |
76 | 80 |
77 if (sSandboxedChildConnectionAllocatorMap == null) { | 81 if (sSandboxedChildConnectionAllocatorMap == null) { |
78 sSandboxedChildConnectionAllocatorMap = new HashMap<String, ChildCon
nectionAllocator>(); | 82 sSandboxedChildConnectionAllocatorMap = new HashMap<String, ChildCon
nectionAllocator>(); |
79 } | 83 } |
80 if (!sSandboxedChildConnectionAllocatorMap.containsKey(packageName)) { | 84 if (!sSandboxedChildConnectionAllocatorMap.containsKey(packageName)) { |
81 Log.w(TAG, | 85 Log.w(TAG, |
82 "Create a new ChildConnectionAllocator with package name = %
s," | 86 "Create a new ChildConnectionAllocator with package name = %
s," |
83 + " inSandbox = true", | 87 + " inSandbox = true", |
84 packageName); | 88 packageName); |
85 sSandboxedChildConnectionAllocatorMap.put(packageName, | 89 sSandboxedChildConnectionAllocatorMap.put(packageName, |
86 new ChildConnectionAllocator(true, | 90 new ChildConnectionAllocator(ManagedChildProcessConnection.F
ACTORY, |
87 getNumberOfServices(context, true, packageName), | 91 true /* sandboxed */, getNumberOfServices(context, t
rue, packageName), |
88 getClassNameOfService(context, true, packageName))); | 92 getClassNameOfService(context, true, packageName))); |
89 } | 93 } |
90 return sSandboxedChildConnectionAllocatorMap.get(packageName); | 94 return sSandboxedChildConnectionAllocatorMap.get(packageName); |
91 // TODO(pkotwicz|hanxi): Figure out when old allocators should be remove
d from | 95 // TODO(pkotwicz|hanxi): Figure out when old allocators should be remove
d from |
92 // {@code sSandboxedChildConnectionAllocatorMap}. | 96 // {@code sSandboxedChildConnectionAllocatorMap}. |
93 } | 97 } |
94 | 98 |
95 private static String getClassNameOfService( | 99 private static String getClassNameOfService( |
96 Context context, boolean inSandbox, String packageName) { | 100 Context context, boolean inSandbox, String packageName) { |
97 if (!inSandbox) { | 101 if (!inSandbox) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 157 } |
154 return numServices; | 158 return numServices; |
155 } | 159 } |
156 | 160 |
157 @VisibleForTesting | 161 @VisibleForTesting |
158 public static void setSandboxServicesSettingsForTesting(int serviceCount, St
ring serviceName) { | 162 public static void setSandboxServicesSettingsForTesting(int serviceCount, St
ring serviceName) { |
159 sSandboxedServicesCountForTesting = serviceCount; | 163 sSandboxedServicesCountForTesting = serviceCount; |
160 sSandboxedServicesNameForTesting = serviceName; | 164 sSandboxedServicesNameForTesting = serviceName; |
161 } | 165 } |
162 | 166 |
163 private ChildConnectionAllocator( | 167 private ChildConnectionAllocator(BaseChildProcessConnection.Factory connecti
onFactory, |
164 boolean inSandbox, int numChildServices, String serviceClassName) { | 168 boolean inSandbox, int numChildServices, String serviceClassName) { |
165 mChildProcessConnections = new ChildProcessConnectionImpl[numChildServic
es]; | 169 mConnectionFactory = connectionFactory; |
| 170 mChildProcessConnections = new BaseChildProcessConnection[numChildServic
es]; |
166 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); | 171 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); |
167 for (int i = 0; i < numChildServices; i++) { | 172 for (int i = 0; i < numChildServices; i++) { |
168 mFreeConnectionIndices.add(i); | 173 mFreeConnectionIndices.add(i); |
169 } | 174 } |
170 mChildClassName = serviceClassName; | 175 mChildClassName = serviceClassName; |
171 mInSandbox = inSandbox; | 176 mInSandbox = inSandbox; |
172 } | 177 } |
173 | 178 |
174 // Allocates or enqueues. If there are no free slots, returns null and enque
ues the spawn data. | 179 // Allocates or enqueues. If there are no free slots, returns null and enque
ues the spawn data. |
175 public ChildProcessConnection allocate(ChildSpawnData spawnData, | 180 public BaseChildProcessConnection allocate(ChildSpawnData spawnData, |
176 ChildProcessConnection.DeathCallback deathCallback, Bundle childProc
essCommonParameters, | 181 BaseChildProcessConnection.DeathCallback deathCallback, |
177 boolean queueIfNoSlotAvailable) { | 182 Bundle childProcessCommonParameters, boolean queueIfNoSlotAvailable)
{ |
178 assert LauncherThread.runningOnLauncherThread(); | 183 assert LauncherThread.runningOnLauncherThread(); |
179 assert spawnData.isInSandbox() == mInSandbox; | 184 assert spawnData.isInSandbox() == mInSandbox; |
180 if (mFreeConnectionIndices.isEmpty()) { | 185 if (mFreeConnectionIndices.isEmpty()) { |
181 Log.d(TAG, "Ran out of services to allocate."); | 186 Log.d(TAG, "Ran out of services to allocate."); |
182 if (queueIfNoSlotAvailable) { | 187 if (queueIfNoSlotAvailable) { |
183 mPendingSpawnQueue.add(spawnData); | 188 mPendingSpawnQueue.add(spawnData); |
184 } | 189 } |
185 return null; | 190 return null; |
186 } | 191 } |
187 int slot = mFreeConnectionIndices.remove(0); | 192 int slot = mFreeConnectionIndices.remove(0); |
188 assert mChildProcessConnections[slot] == null; | 193 assert mChildProcessConnections[slot] == null; |
189 mChildProcessConnections[slot] = new ChildProcessConnectionImpl(spawnDat
a.getContext(), | 194 mChildProcessConnections[slot] = mConnectionFactory.create(spawnData.get
Context(), slot, |
190 slot, mInSandbox, deathCallback, mChildClassName, childProcessCo
mmonParameters, | 195 mInSandbox, deathCallback, mChildClassName, childProcessCommonPa
rameters, |
191 spawnData.isAlwaysInForeground(), spawnData.getCreationParams())
; | 196 spawnData.getCreationParams()); |
192 Log.d(TAG, "Allocator allocated a connection, sandbox: %b, slot: %d", mI
nSandbox, slot); | 197 Log.d(TAG, "Allocator allocated a connection, sandbox: %b, slot: %d", mI
nSandbox, slot); |
193 return mChildProcessConnections[slot]; | 198 return mChildProcessConnections[slot]; |
194 } | 199 } |
195 | 200 |
196 // Also return the first ChildSpawnData in the pending queue, if any. | 201 // Also return the first ChildSpawnData in the pending queue, if any. |
197 public ChildSpawnData free(ChildProcessConnection connection) { | 202 public ChildSpawnData free(BaseChildProcessConnection connection) { |
198 assert LauncherThread.runningOnLauncherThread(); | 203 assert LauncherThread.runningOnLauncherThread(); |
199 int slot = connection.getServiceNumber(); | 204 int slot = connection.getServiceNumber(); |
200 if (mChildProcessConnections[slot] != connection) { | 205 if (mChildProcessConnections[slot] != connection) { |
201 int occupier = mChildProcessConnections[slot] == null | 206 int occupier = mChildProcessConnections[slot] == null |
202 ? -1 | 207 ? -1 |
203 : mChildProcessConnections[slot].getServiceNumber(); | 208 : mChildProcessConnections[slot].getServiceNumber(); |
204 Log.e(TAG, | 209 Log.e(TAG, |
205 "Unable to find connection to free in slot: %d " | 210 "Unable to find connection to free in slot: %d " |
206 + "already occupied by service: %d", | 211 + "already occupied by service: %d", |
207 slot, occupier); | 212 slot, occupier); |
(...skipping 13 matching lines...) Expand all Loading... |
221 } | 226 } |
222 | 227 |
223 /** @return the count of connections managed by the allocator */ | 228 /** @return the count of connections managed by the allocator */ |
224 @VisibleForTesting | 229 @VisibleForTesting |
225 int allocatedConnectionsCountForTesting() { | 230 int allocatedConnectionsCountForTesting() { |
226 assert LauncherThread.runningOnLauncherThread(); | 231 assert LauncherThread.runningOnLauncherThread(); |
227 return mChildProcessConnections.length - mFreeConnectionIndices.size(); | 232 return mChildProcessConnections.length - mFreeConnectionIndices.size(); |
228 } | 233 } |
229 | 234 |
230 @VisibleForTesting | 235 @VisibleForTesting |
231 ChildProcessConnection[] connectionArrayForTesting() { | 236 BaseChildProcessConnection[] connectionArrayForTesting() { |
232 return mChildProcessConnections; | 237 return mChildProcessConnections; |
233 } | 238 } |
234 | 239 |
235 @VisibleForTesting | 240 @VisibleForTesting |
236 void enqueuePendingQueueForTesting(ChildSpawnData spawnData) { | 241 void enqueuePendingQueueForTesting(ChildSpawnData spawnData) { |
237 assert LauncherThread.runningOnLauncherThread(); | 242 assert LauncherThread.runningOnLauncherThread(); |
238 mPendingSpawnQueue.add(spawnData); | 243 mPendingSpawnQueue.add(spawnData); |
239 } | 244 } |
240 | 245 |
241 @VisibleForTesting | 246 @VisibleForTesting |
242 int pendingSpawnsCountForTesting() { | 247 int pendingSpawnsCountForTesting() { |
243 assert LauncherThread.runningOnLauncherThread(); | 248 assert LauncherThread.runningOnLauncherThread(); |
244 return mPendingSpawnQueue.size(); | 249 return mPendingSpawnQueue.size(); |
245 } | 250 } |
246 } | 251 } |
OLD | NEW |