diff options
5 files changed, 29 insertions, 14 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 84f032d432ea..5e9cc70bde65 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1650,7 +1650,9 @@ public final class ActivityThread extends ClientTransactionHandler { (String[]) ((SomeArgs) msg.obj).arg2); break; case EXECUTE_TRANSACTION: - mTransactionExecutor.execute(((ClientTransaction) msg.obj)); + final ClientTransaction transaction = (ClientTransaction) msg.obj; + mTransactionExecutor.execute(transaction); + transaction.recycle(); break; } Object obj = msg.obj; diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java index 764ceede5d20..3c96f06945c5 100644 --- a/core/java/android/app/servertransaction/ClientTransaction.java +++ b/core/java/android/app/servertransaction/ClientTransaction.java @@ -54,6 +54,11 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { /** Target client activity. Might be null if the entire transaction is targeting an app. */ private IBinder mActivityToken; + /** Get the target client of the transaction. */ + public IApplicationThread getClient() { + return mClient; + } + /** * Add a message to the end of the sequence of callbacks. * @param activityCallback A single message that can contain a lifecycle request/callback. diff --git a/core/java/android/app/servertransaction/ObjectPool.java b/core/java/android/app/servertransaction/ObjectPool.java index 98121253f486..2fec30a0dde7 100644 --- a/core/java/android/app/servertransaction/ObjectPool.java +++ b/core/java/android/app/servertransaction/ObjectPool.java @@ -16,8 +16,8 @@ package android.app.servertransaction; +import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.Map; /** @@ -27,7 +27,7 @@ import java.util.Map; class ObjectPool { private static final Object sPoolSync = new Object(); - private static final Map<Class, LinkedList<? extends ObjectPoolItem>> sPoolMap = + private static final Map<Class, ArrayList<? extends ObjectPoolItem>> sPoolMap = new HashMap<>(); private static final int MAX_POOL_SIZE = 50; @@ -40,9 +40,9 @@ class ObjectPool { public static <T extends ObjectPoolItem> T obtain(Class<T> itemClass) { synchronized (sPoolSync) { @SuppressWarnings("unchecked") - LinkedList<T> itemPool = (LinkedList<T>) sPoolMap.get(itemClass); + final ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(itemClass); if (itemPool != null && !itemPool.isEmpty()) { - return itemPool.poll(); + return itemPool.remove(itemPool.size() - 1); } return null; } @@ -56,16 +56,20 @@ class ObjectPool { public static <T extends ObjectPoolItem> void recycle(T item) { synchronized (sPoolSync) { @SuppressWarnings("unchecked") - LinkedList<T> itemPool = (LinkedList<T>) sPoolMap.get(item.getClass()); + ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(item.getClass()); if (itemPool == null) { - itemPool = new LinkedList<>(); + itemPool = new ArrayList<>(); sPoolMap.put(item.getClass(), itemPool); } - if (itemPool.contains(item)) { - throw new IllegalStateException("Trying to recycle already recycled item"); + // Check if the item is already in the pool + final int size = itemPool.size(); + for (int i = 0; i < size; i++) { + if (itemPool.get(i) == item) { + throw new IllegalStateException("Trying to recycle already recycled item"); + } } - if (itemPool.size() < MAX_POOL_SIZE) { + if (size < MAX_POOL_SIZE) { itemPool.add(item); } } diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java index c19a343957c0..aefc47e95512 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java @@ -42,8 +42,7 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest -// TODO: b/70616950 -//@Presubmit +@Presubmit public class ObjectPoolTests { // 1. Check if two obtained objects from pool are not the same. diff --git a/services/core/java/com/android/server/am/ClientLifecycleManager.java b/services/core/java/com/android/server/am/ClientLifecycleManager.java index 014f7086efa3..1e7080980d9e 100644 --- a/services/core/java/com/android/server/am/ClientLifecycleManager.java +++ b/services/core/java/com/android/server/am/ClientLifecycleManager.java @@ -21,6 +21,7 @@ import android.app.IApplicationThread; import android.app.servertransaction.ClientTransaction; import android.app.servertransaction.ClientTransactionItem; import android.app.servertransaction.ActivityLifecycleItem; +import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -43,8 +44,12 @@ class ClientLifecycleManager { */ void scheduleTransaction(ClientTransaction transaction) throws RemoteException { transaction.schedule(); - // TODO: b/70616950 - //transaction.recycle(); + if (!(transaction.getClient() instanceof Binder)) { + // If client is not an instance of Binder - it's a remote call and at this point it is + // safe to recycle the object. All objects used for local calls will be recycled after + // the transaction is executed on client in ActivityThread. + transaction.recycle(); + } } /** |