Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 259e3482 authored by Eric Lin's avatar Eric Lin
Browse files

Deprecate ObjectPool and ObjectPoolItem (1/n).

Begin deprecating the ObjectPool class and ObjectPoolItem interface.
Direct object instantiation is now preferred over using the pool.
This change is the first in a series of changes to remove the
object pool mechanism and simplifying object management.

Bug: 311089192
Test: atest FrameworksCoreTests:ObjectPoolTests
Flag: EXEMPT removing com.android.window.flags.disable_object_pool
Change-Id: If04abad2263be437691b99c4ed166b91dcab3a7f
parent 78297ef2
Loading
Loading
Loading
Loading
+18 −49
Original line number Diff line number Diff line
@@ -16,70 +16,39 @@

package android.app.servertransaction;

import com.android.window.flags.Flags;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * An object pool that can provide reused objects if available.
 *
 * @hide
 * @deprecated This class is deprecated. Directly create new instances of objects instead of
 * obtaining them from this pool.
 * TODO(b/311089192): Clean up usages of the pool.
 */
@Deprecated
class ObjectPool {

    private static final Object sPoolSync = new Object();
    private static final Map<Class, ArrayList<? extends ObjectPoolItem>> sPoolMap =
            new HashMap<>();

    private static final int MAX_POOL_SIZE = 50;

    /**
     * Obtain an instance of a specific class from the pool
     * @param itemClass The class of the object we're looking for.
     *
     * @param ignoredItemClass The class of the object we're looking for.
     * @return An instance or null if there is none.
     * @deprecated This method is deprecated. Directly create new instances of objects instead of
     * obtaining them from this pool.
     */
    public static <T extends ObjectPoolItem> T obtain(Class<T> itemClass) {
        if (Flags.disableObjectPool()) {
            return null;
        }
        synchronized (sPoolSync) {
            @SuppressWarnings("unchecked")
            final ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(itemClass);
            if (itemPool != null && !itemPool.isEmpty()) {
                return itemPool.remove(itemPool.size() - 1);
            }
    @Deprecated
    public static <T extends ObjectPoolItem> T obtain(Class<T> ignoredItemClass) {
        return null;
    }
    }

    /**
     * Recycle the object to the pool. The object should be properly cleared before this.
     * @param item The object to recycle.
     *
     * @param ignoredItem The object to recycle.
     * @see ObjectPoolItem#recycle()
     * @deprecated This method is deprecated. The object pool is no longer used, so there's
     * no need to recycle objects.
     */
    public static <T extends ObjectPoolItem> void recycle(T item) {
        if (Flags.disableObjectPool()) {
            return;
        }
        synchronized (sPoolSync) {
            @SuppressWarnings("unchecked")
            ArrayList<T> itemPool = (ArrayList<T>) sPoolMap.get(item.getClass());
            if (itemPool == null) {
                itemPool = new ArrayList<>();
                sPoolMap.put(item.getClass(), itemPool);
            }
            // 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 (size < MAX_POOL_SIZE) {
                itemPool.add(item);
            }
        }
    @Deprecated
    public static <T extends ObjectPoolItem> void recycle(T ignoredItem) {
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -18,12 +18,20 @@ package android.app.servertransaction;

/**
 * Base interface for all lifecycle items that can be put in object pool.
 *
 * @hide
 * @deprecated This interface is deprecated. Objects should no longer be pooled.
 * TODO(b/311089192): Clean up usages of this interface.
 */
@Deprecated
public interface ObjectPoolItem {
    /**
     * Clear the contents of the item and putting it to a pool. The implementation should call
     * {@link ObjectPool#recycle(ObjectPoolItem)} passing itself.
     *
     * @deprecated This method is deprecated. The object pool is no longer used, so there's
     * no need to recycle objects.
     */
    @Deprecated
    void recycle();
}
+3 −46
Original line number Diff line number Diff line
@@ -21,12 +21,7 @@ import static android.app.servertransaction.TestUtils.mergedConfig;
import static android.app.servertransaction.TestUtils.referrerIntentList;
import static android.app.servertransaction.TestUtils.resultInfoList;

import static com.android.window.flags.Flags.FLAG_DISABLE_OBJECT_POOL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;

import android.annotation.NonNull;
import android.app.ActivityOptions;
@@ -41,14 +36,11 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
import android.window.ActivityWindowInfo;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.window.flags.Flags;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -56,12 +48,8 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

import java.util.List;
import java.util.function.Supplier;

import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;

/**
 * Tests for {@link ObjectPool}.
 *
@@ -71,31 +59,19 @@ import platform.test.runner.parameterized.Parameters;
 * <p>This test class is a part of Window Manager Service tests and specified in
 * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
 */
@RunWith(ParameterizedAndroidJunit4.class)
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
public class ObjectPoolTests {

    @Parameters(name = "{0}")
    public static List<FlagsParameterization> getParams() {
        return FlagsParameterization.allCombinationsOf(FLAG_DISABLE_OBJECT_POOL);
    }

    @Rule
    public final MockitoRule mocks = MockitoJUnit.rule();

    @Rule
    public SetFlagsRule mSetFlagsRule;

    @Mock
    private IApplicationThread mApplicationThread;
    @Mock
    private IBinder mActivityToken;

    public ObjectPoolTests(FlagsParameterization flags) {
        mSetFlagsRule = new SetFlagsRule(flags);
    }

    // 1. Check if two obtained objects from pool are not the same.
    // 2. Check if the state of the object is cleared after recycling.
    // 3. Check if the same object is obtained from pool after recycling.
@@ -219,30 +195,11 @@ public class ObjectPoolTests {
        item.recycle();
        final ObjectPoolItem item2 = obtain.get();

        if (Flags.disableObjectPool()) {
        assertNotSame(item, item2);  // Different instance.
        } else {
            assertSame(item, item2);
        }

        // Create new object when the pool is empty.
        final ObjectPoolItem item3 = obtain.get();

        assertNotSame(item, item3);
        if (Flags.disableObjectPool()) {
            // Skip recycle if flag enabled, compare unnecessary.
            return;
        }
        assertEquals(item, item3);

        // Reset fields after recycle.
        item.recycle();

        assertNotEquals(item, item3);

        // Recycled objects are equal.
        item3.recycle();

        assertEquals(item, item3);
    }
}