| 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; |
| 11 import android.os.Bundle; | |
| 12 | 11 |
| 13 import org.chromium.base.Log; | 12 import org.chromium.base.Log; |
| 14 import org.chromium.base.VisibleForTesting; | 13 import org.chromium.base.VisibleForTesting; |
| 15 | 14 |
| 16 import java.util.ArrayList; | 15 import java.util.ArrayList; |
| 17 import java.util.Arrays; | 16 import java.util.Arrays; |
| 18 import java.util.LinkedList; | 17 import java.util.LinkedList; |
| 19 import java.util.Queue; | 18 import java.util.Queue; |
| 20 | 19 |
| 21 /** | 20 /** |
| 22 * This class is responsible for allocating and managing connections to child | 21 * This class is responsible for allocating and managing connections to child |
| 23 * process services. These connections are in a pool (the services are defined | 22 * process services. These connections are in a pool (the services are defined |
| 24 * in the AndroidManifest.xml). | 23 * in the AndroidManifest.xml). |
| 25 */ | 24 */ |
| 26 public class ChildConnectionAllocator { | 25 public class ChildConnectionAllocator { |
| 27 private static final String TAG = "ChildConnAllocator"; | 26 private static final String TAG = "ChildConnAllocator"; |
| 28 | 27 |
| 29 /** Factory interface. Used by tests to specialize created connections. */ | 28 /** Factory interface. Used by tests to specialize created connections. */ |
| 30 @VisibleForTesting | 29 @VisibleForTesting |
| 31 protected interface ConnectionFactory { | 30 protected interface ConnectionFactory { |
| 32 ChildProcessConnection createConnection(ChildSpawnData spawnData, | 31 ChildProcessConnection createConnection(ChildSpawnData spawnData, |
| 33 ChildProcessConnection.DeathCallback deathCallback, | 32 ChildProcessConnection.DeathCallback deathCallback, String servi
ceClassName); |
| 34 Bundle childProcessCommonParameters, String serviceClassName); | |
| 35 } | 33 } |
| 36 | 34 |
| 37 /** Default implementation of the ConnectionFactory that creates actual conn
ections. */ | 35 /** Default implementation of the ConnectionFactory that creates actual conn
ections. */ |
| 38 private static class ConnectionFactoryImpl implements ConnectionFactory { | 36 private static class ConnectionFactoryImpl implements ConnectionFactory { |
| 39 public ChildProcessConnection createConnection(ChildSpawnData spawnData, | 37 public ChildProcessConnection createConnection(ChildSpawnData spawnData, |
| 40 ChildProcessConnection.DeathCallback deathCallback, | 38 ChildProcessConnection.DeathCallback deathCallback, String servi
ceClassName) { |
| 41 Bundle childProcessCommonParameters, String serviceClassName) { | |
| 42 return new ChildProcessConnection(spawnData.getContext(), deathCallb
ack, | 39 return new ChildProcessConnection(spawnData.getContext(), deathCallb
ack, |
| 43 serviceClassName, childProcessCommonParameters, spawnData.ge
tCreationParams()); | 40 serviceClassName, spawnData.getServiceBundle(), spawnData.ge
tCreationParams()); |
| 44 } | 41 } |
| 45 } | 42 } |
| 46 | 43 |
| 47 // Connections to services. Indices of the array correspond to the service n
umbers. | 44 // Connections to services. Indices of the array correspond to the service n
umbers. |
| 48 private final ChildProcessConnection[] mChildProcessConnections; | 45 private final ChildProcessConnection[] mChildProcessConnections; |
| 49 | 46 |
| 50 private final String mServiceClassName; | 47 private final String mServiceClassName; |
| 51 | 48 |
| 52 // The list of free (not bound) service indices. | 49 // The list of free (not bound) service indices. |
| 53 private final ArrayList<Integer> mFreeConnectionIndices; | 50 private final ArrayList<Integer> mFreeConnectionIndices; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 mServiceClassName = serviceClassName; | 127 mServiceClassName = serviceClassName; |
| 131 mChildProcessConnections = new ChildProcessConnection[numChildServices]; | 128 mChildProcessConnections = new ChildProcessConnection[numChildServices]; |
| 132 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); | 129 mFreeConnectionIndices = new ArrayList<Integer>(numChildServices); |
| 133 for (int i = 0; i < numChildServices; i++) { | 130 for (int i = 0; i < numChildServices; i++) { |
| 134 mFreeConnectionIndices.add(i); | 131 mFreeConnectionIndices.add(i); |
| 135 } | 132 } |
| 136 } | 133 } |
| 137 | 134 |
| 138 // Allocates or enqueues. If there are no free slots, returns null and enque
ues the spawn data. | 135 // Allocates or enqueues. If there are no free slots, returns null and enque
ues the spawn data. |
| 139 public ChildProcessConnection allocate(ChildSpawnData spawnData, | 136 public ChildProcessConnection allocate(ChildSpawnData spawnData, |
| 140 ChildProcessConnection.DeathCallback deathCallback, Bundle childProc
essCommonParameters, | 137 ChildProcessConnection.DeathCallback deathCallback, boolean queueIfN
oSlotAvailable) { |
| 141 boolean queueIfNoSlotAvailable) { | |
| 142 assert LauncherThread.runningOnLauncherThread(); | 138 assert LauncherThread.runningOnLauncherThread(); |
| 143 if (mFreeConnectionIndices.isEmpty()) { | 139 if (mFreeConnectionIndices.isEmpty()) { |
| 144 Log.d(TAG, "Ran out of services to allocate."); | 140 Log.d(TAG, "Ran out of services to allocate."); |
| 145 if (queueIfNoSlotAvailable) { | 141 if (queueIfNoSlotAvailable) { |
| 146 mPendingSpawnQueue.add(spawnData); | 142 mPendingSpawnQueue.add(spawnData); |
| 147 } | 143 } |
| 148 return null; | 144 return null; |
| 149 } | 145 } |
| 150 int slot = mFreeConnectionIndices.remove(0); | 146 int slot = mFreeConnectionIndices.remove(0); |
| 151 assert mChildProcessConnections[slot] == null; | 147 assert mChildProcessConnections[slot] == null; |
| 152 String serviceClassName = mServiceClassName + slot; | 148 String serviceClassName = mServiceClassName + slot; |
| 153 mChildProcessConnections[slot] = mConnectionFactory.createConnection( | 149 mChildProcessConnections[slot] = |
| 154 spawnData, deathCallback, childProcessCommonParameters, serviceC
lassName); | 150 mConnectionFactory.createConnection(spawnData, deathCallback, se
rviceClassName); |
| 155 Log.d(TAG, "Allocator allocated a connection, name: %s, slot: %d", mServ
iceClassName, slot); | 151 Log.d(TAG, "Allocator allocated a connection, name: %s, slot: %d", mServ
iceClassName, slot); |
| 156 return mChildProcessConnections[slot]; | 152 return mChildProcessConnections[slot]; |
| 157 } | 153 } |
| 158 | 154 |
| 159 // Also return the first ChildSpawnData in the pending queue, if any. | 155 // Also return the first ChildSpawnData in the pending queue, if any. |
| 160 public ChildSpawnData free(ChildProcessConnection connection) { | 156 public ChildSpawnData free(ChildProcessConnection connection) { |
| 161 assert LauncherThread.runningOnLauncherThread(); | 157 assert LauncherThread.runningOnLauncherThread(); |
| 162 // mChildProcessConnections is relatively short (20 items at max at this
point). | 158 // mChildProcessConnections is relatively short (20 items at max at this
point). |
| 163 // We are better of iterating than caching in a map. | 159 // We are better of iterating than caching in a map. |
| 164 int slot = Arrays.asList(mChildProcessConnections).indexOf(connection); | 160 int slot = Arrays.asList(mChildProcessConnections).indexOf(connection); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 assert LauncherThread.runningOnLauncherThread(); | 201 assert LauncherThread.runningOnLauncherThread(); |
| 206 mPendingSpawnQueue.add(spawnData); | 202 mPendingSpawnQueue.add(spawnData); |
| 207 } | 203 } |
| 208 | 204 |
| 209 @VisibleForTesting | 205 @VisibleForTesting |
| 210 int pendingSpawnsCountForTesting() { | 206 int pendingSpawnsCountForTesting() { |
| 211 assert LauncherThread.runningOnLauncherThread(); | 207 assert LauncherThread.runningOnLauncherThread(); |
| 212 return mPendingSpawnQueue.size(); | 208 return mPendingSpawnQueue.size(); |
| 213 } | 209 } |
| 214 } | 210 } |
| OLD | NEW |