summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java4
-rw-r--r--core/java/android/app/servertransaction/ClientTransaction.java5
-rw-r--r--core/java/android/app/servertransaction/ObjectPool.java22
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java3
-rw-r--r--services/core/java/com/android/server/am/ClientLifecycleManager.java9
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();
+ }
}
/**