diff options
29 files changed, 1009 insertions, 263 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 20213199f53b..8a4d29bb7bdb 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2557,8 +2557,8 @@ public final class ActivityThread extends ClientTransactionHandler { + " req=" + requestCode + " res=" + resultCode + " data=" + data); ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); list.add(new ResultInfo(id, requestCode, resultCode, data)); - final ClientTransaction clientTransaction = new ClientTransaction(mAppThread, token); - clientTransaction.addCallback(new ActivityResultItem(list)); + final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread, token); + clientTransaction.addCallback(ActivityResultItem.obtain(list)); try { mAppThread.scheduleTransaction(clientTransaction); } catch (RemoteException e) { diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java index a3fe686c4a08..a2b7d5809c4d 100644 --- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java +++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java @@ -25,17 +25,15 @@ import android.os.IBinder; import android.os.Parcel; import android.os.Trace; +import java.util.Objects; + /** * Activity configuration changed callback. * @hide */ public class ActivityConfigurationChangeItem extends ClientTransactionItem { - private final Configuration mConfiguration; - - public ActivityConfigurationChangeItem(Configuration configuration) { - mConfiguration = configuration; - } + private Configuration mConfiguration; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -47,6 +45,29 @@ public class ActivityConfigurationChangeItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private ActivityConfigurationChangeItem() {} + + /** Obtain an instance initialized with provided params. */ + public static ActivityConfigurationChangeItem obtain(Configuration config) { + ActivityConfigurationChangeItem instance = + ObjectPool.obtain(ActivityConfigurationChangeItem.class); + if (instance == null) { + instance = new ActivityConfigurationChangeItem(); + } + instance.mConfiguration = config; + + return instance; + } + + @Override + public void recycle() { + mConfiguration = null; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ @@ -80,7 +101,7 @@ public class ActivityConfigurationChangeItem extends ClientTransactionItem { return false; } final ActivityConfigurationChangeItem other = (ActivityConfigurationChangeItem) o; - return mConfiguration.equals(other.mConfiguration); + return Objects.equals(mConfiguration, other.mConfiguration); } @Override diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java index 3a3d5b981fb4..73b5ec440441 100644 --- a/core/java/android/app/servertransaction/ActivityResultItem.java +++ b/core/java/android/app/servertransaction/ActivityResultItem.java @@ -27,6 +27,7 @@ import android.os.Parcelable; import android.os.Trace; import java.util.List; +import java.util.Objects; /** * Activity result delivery callback. @@ -34,11 +35,7 @@ import java.util.List; */ public class ActivityResultItem extends ClientTransactionItem { - private final List<ResultInfo> mResultInfoList; - - public ActivityResultItem(List<ResultInfo> resultInfos) { - mResultInfoList = resultInfos; - } + private List<ResultInfo> mResultInfoList; @Override public int getPreExecutionState() { @@ -54,6 +51,28 @@ public class ActivityResultItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private ActivityResultItem() {} + + /** Obtain an instance initialized with provided params. */ + public static ActivityResultItem obtain(List<ResultInfo> resultInfoList) { + ActivityResultItem instance = ObjectPool.obtain(ActivityResultItem.class); + if (instance == null) { + instance = new ActivityResultItem(); + } + instance.mResultInfoList = resultInfoList; + + return instance; + } + + @Override + public void recycle() { + mResultInfoList = null; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ @@ -87,7 +106,7 @@ public class ActivityResultItem extends ClientTransactionItem { return false; } final ActivityResultItem other = (ActivityResultItem) o; - return mResultInfoList.equals(other.mResultInfoList); + return Objects.equals(mResultInfoList, other.mResultInfoList); } @Override diff --git a/core/java/android/app/servertransaction/BaseClientRequest.java b/core/java/android/app/servertransaction/BaseClientRequest.java index e3473bfd0ae8..c91e0ca5ffc1 100644 --- a/core/java/android/app/servertransaction/BaseClientRequest.java +++ b/core/java/android/app/servertransaction/BaseClientRequest.java @@ -24,7 +24,7 @@ import android.os.IBinder; * Each of them can be prepared before scheduling and, eventually, executed. * @hide */ -public interface BaseClientRequest { +public interface BaseClientRequest extends ObjectPoolItem { /** * Prepare the client request before scheduling. diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java index 7a5896261aac..764ceede5d20 100644 --- a/core/java/android/app/servertransaction/ClientTransaction.java +++ b/core/java/android/app/servertransaction/ClientTransaction.java @@ -37,7 +37,7 @@ import java.util.Objects; * @see ActivityLifecycleItem * @hide */ -public class ClientTransaction implements Parcelable { +public class ClientTransaction implements Parcelable, ObjectPoolItem { /** A list of individual callbacks to a client. */ private List<ClientTransactionItem> mActivityCallbacks; @@ -54,11 +54,6 @@ public class ClientTransaction implements Parcelable { /** Target client activity. Might be null if the entire transaction is targeting an app. */ private IBinder mActivityToken; - public ClientTransaction(IApplicationThread client, IBinder activityToken) { - mClient = client; - mActivityToken = activityToken; - } - /** * Add a message to the end of the sequence of callbacks. * @param activityCallback A single message that can contain a lifecycle request/callback. @@ -127,6 +122,41 @@ public class ClientTransaction implements Parcelable { } + // ObjectPoolItem implementation + + private ClientTransaction() {} + + /** Obtain an instance initialized with provided params. */ + public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) { + ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class); + if (instance == null) { + instance = new ClientTransaction(); + } + instance.mClient = client; + instance.mActivityToken = activityToken; + + return instance; + } + + @Override + public void recycle() { + if (mActivityCallbacks != null) { + int size = mActivityCallbacks.size(); + for (int i = 0; i < size; i++) { + mActivityCallbacks.get(i).recycle(); + } + mActivityCallbacks.clear(); + } + if (mLifecycleStateRequest != null) { + mLifecycleStateRequest.recycle(); + mLifecycleStateRequest = null; + } + mClient = null; + mActivityToken = null; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ diff --git a/core/java/android/app/servertransaction/ConfigurationChangeItem.java b/core/java/android/app/servertransaction/ConfigurationChangeItem.java index ee1effa6c2ab..4ab7251e4d8a 100644 --- a/core/java/android/app/servertransaction/ConfigurationChangeItem.java +++ b/core/java/android/app/servertransaction/ConfigurationChangeItem.java @@ -21,17 +21,15 @@ import android.content.res.Configuration; import android.os.IBinder; import android.os.Parcel; +import java.util.Objects; + /** * App configuration change message. * @hide */ public class ConfigurationChangeItem extends ClientTransactionItem { - private final Configuration mConfiguration; - - public ConfigurationChangeItem(Configuration configuration) { - mConfiguration = new Configuration(configuration); - } + private Configuration mConfiguration; @Override public void preExecute(android.app.ClientTransactionHandler client, IBinder token) { @@ -44,6 +42,29 @@ public class ConfigurationChangeItem extends ClientTransactionItem { client.handleConfigurationChanged(mConfiguration); } + + // ObjectPoolItem implementation + + private ConfigurationChangeItem() {} + + /** Obtain an instance initialized with provided params. */ + public static ConfigurationChangeItem obtain(Configuration config) { + ConfigurationChangeItem instance = ObjectPool.obtain(ConfigurationChangeItem.class); + if (instance == null) { + instance = new ConfigurationChangeItem(); + } + instance.mConfiguration = config; + + return instance; + } + + @Override + public void recycle() { + mConfiguration = null; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ @@ -77,7 +98,7 @@ public class ConfigurationChangeItem extends ClientTransactionItem { return false; } final ConfigurationChangeItem other = (ConfigurationChangeItem) o; - return mConfiguration.equals(other.mConfiguration); + return Objects.equals(mConfiguration, other.mConfiguration); } @Override diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java index 3012a7a474e6..83da5f33c62a 100644 --- a/core/java/android/app/servertransaction/DestroyActivityItem.java +++ b/core/java/android/app/servertransaction/DestroyActivityItem.java @@ -29,13 +29,8 @@ import android.os.Trace; */ public class DestroyActivityItem extends ActivityLifecycleItem { - private final boolean mFinished; - private final int mConfigChanges; - - public DestroyActivityItem(boolean finished, int configChanges) { - mFinished = finished; - mConfigChanges = configChanges; - } + private boolean mFinished; + private int mConfigChanges; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -52,6 +47,30 @@ public class DestroyActivityItem extends ActivityLifecycleItem { } + // ObjectPoolItem implementation + + private DestroyActivityItem() {} + + /** Obtain an instance initialized with provided params. */ + public static DestroyActivityItem obtain(boolean finished, int configChanges) { + DestroyActivityItem instance = ObjectPool.obtain(DestroyActivityItem.class); + if (instance == null) { + instance = new DestroyActivityItem(); + } + instance.mFinished = finished; + instance.mConfigChanges = configChanges; + + return instance; + } + + @Override + public void recycle() { + mFinished = false; + mConfigChanges = 0; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java index e39042f43d51..7be82bf9f505 100644 --- a/core/java/android/app/servertransaction/LaunchActivityItem.java +++ b/core/java/android/app/servertransaction/LaunchActivityItem.java @@ -45,43 +45,21 @@ import java.util.Objects; */ public class LaunchActivityItem extends ClientTransactionItem { - private final Intent mIntent; - private final int mIdent; - private final ActivityInfo mInfo; - private final Configuration mCurConfig; - private final Configuration mOverrideConfig; - private final CompatibilityInfo mCompatInfo; - private final String mReferrer; - private final IVoiceInteractor mVoiceInteractor; - private final int mProcState; - private final Bundle mState; - private final PersistableBundle mPersistentState; - private final List<ResultInfo> mPendingResults; - private final List<ReferrerIntent> mPendingNewIntents; - private final boolean mIsForward; - private final ProfilerInfo mProfilerInfo; - - public LaunchActivityItem(Intent intent, int ident, ActivityInfo info, - Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, - String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, - PersistableBundle persistentState, List<ResultInfo> pendingResults, - List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo) { - mIntent = intent; - mIdent = ident; - mInfo = info; - mCurConfig = curConfig; - mOverrideConfig = overrideConfig; - mCompatInfo = compatInfo; - mReferrer = referrer; - mVoiceInteractor = voiceInteractor; - mProcState = procState; - mState = state; - mPersistentState = persistentState; - mPendingResults = pendingResults; - mPendingNewIntents = pendingNewIntents; - mIsForward = isForward; - mProfilerInfo = profilerInfo; - } + private Intent mIntent; + private int mIdent; + private ActivityInfo mInfo; + private Configuration mCurConfig; + private Configuration mOverrideConfig; + private CompatibilityInfo mCompatInfo; + private String mReferrer; + private IVoiceInteractor mVoiceInteractor; + private int mProcState; + private Bundle mState; + private PersistableBundle mPersistentState; + private List<ResultInfo> mPendingResults; + private List<ReferrerIntent> mPendingNewIntents; + private boolean mIsForward; + private ProfilerInfo mProfilerInfo; @Override public void preExecute(ClientTransactionHandler client, IBinder token) { @@ -102,6 +80,35 @@ public class LaunchActivityItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private LaunchActivityItem() {} + + /** Obtain an instance initialized with provided params. */ + public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info, + Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, + String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, + PersistableBundle persistentState, List<ResultInfo> pendingResults, + List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo) { + LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class); + if (instance == null) { + instance = new LaunchActivityItem(); + } + setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer, + voiceInteractor, procState, state, persistentState, pendingResults, + pendingNewIntents, isForward, profilerInfo); + + return instance; + } + + @Override + public void recycle() { + setValues(this, null, 0, null, null, null, null, null, null, 0, null, null, null, null, + false, null); + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write from Parcel. */ @@ -114,7 +121,7 @@ public class LaunchActivityItem extends ClientTransactionItem { dest.writeTypedObject(mOverrideConfig, flags); dest.writeTypedObject(mCompatInfo, flags); dest.writeString(mReferrer); - dest.writeStrongBinder(mVoiceInteractor != null ? mVoiceInteractor.asBinder() : null); + dest.writeStrongInterface(mVoiceInteractor); dest.writeInt(mProcState); dest.writeBundle(mState); dest.writePersistableBundle(mPersistentState); @@ -126,21 +133,16 @@ public class LaunchActivityItem extends ClientTransactionItem { /** Read from Parcel. */ private LaunchActivityItem(Parcel in) { - mIntent = in.readTypedObject(Intent.CREATOR); - mIdent = in.readInt(); - mInfo = in.readTypedObject(ActivityInfo.CREATOR); - mCurConfig = in.readTypedObject(Configuration.CREATOR); - mOverrideConfig = in.readTypedObject(Configuration.CREATOR); - mCompatInfo = in.readTypedObject(CompatibilityInfo.CREATOR); - mReferrer = in.readString(); - mVoiceInteractor = (IVoiceInteractor) in.readStrongBinder(); - mProcState = in.readInt(); - mState = in.readBundle(getClass().getClassLoader()); - mPersistentState = in.readPersistableBundle(getClass().getClassLoader()); - mPendingResults = in.createTypedArrayList(ResultInfo.CREATOR); - mPendingNewIntents = in.createTypedArrayList(ReferrerIntent.CREATOR); - mIsForward = in.readBoolean(); - mProfilerInfo = in.readTypedObject(ProfilerInfo.CREATOR); + setValues(this, in.readTypedObject(Intent.CREATOR), in.readInt(), + in.readTypedObject(ActivityInfo.CREATOR), in.readTypedObject(Configuration.CREATOR), + in.readTypedObject(Configuration.CREATOR), + in.readTypedObject(CompatibilityInfo.CREATOR), in.readString(), + IVoiceInteractor.Stub.asInterface(in.readStrongBinder()), in.readInt(), + in.readBundle(getClass().getClassLoader()), + in.readPersistableBundle(getClass().getClassLoader()), + in.createTypedArrayList(ResultInfo.CREATOR), + in.createTypedArrayList(ReferrerIntent.CREATOR), in.readBoolean(), + in.readTypedObject(ProfilerInfo.CREATOR)); } public static final Creator<LaunchActivityItem> CREATOR = @@ -163,7 +165,9 @@ public class LaunchActivityItem extends ClientTransactionItem { return false; } final LaunchActivityItem other = (LaunchActivityItem) o; - return mIntent.filterEquals(other.mIntent) && mIdent == other.mIdent + final boolean intentsEqual = (mIntent == null && other.mIntent == null) + || (mIntent != null && mIntent.filterEquals(other.mIntent)); + return intentsEqual && mIdent == other.mIdent && activityInfoEqual(other.mInfo) && Objects.equals(mCurConfig, other.mCurConfig) && Objects.equals(mOverrideConfig, other.mOverrideConfig) && Objects.equals(mCompatInfo, other.mCompatInfo) @@ -196,7 +200,11 @@ public class LaunchActivityItem extends ClientTransactionItem { } private boolean activityInfoEqual(ActivityInfo other) { - return mInfo.flags == other.flags && mInfo.maxAspectRatio == other.maxAspectRatio + if (mInfo == null) { + return other == null; + } + return other != null && mInfo.flags == other.flags + && mInfo.maxAspectRatio == other.maxAspectRatio && Objects.equals(mInfo.launchToken, other.launchToken) && Objects.equals(mInfo.getComponentName(), other.getComponentName()); } @@ -231,4 +239,28 @@ public class LaunchActivityItem extends ClientTransactionItem { + ",pendingNewIntents=" + mPendingNewIntents + ",profilerInfo=" + mProfilerInfo + "}"; } + + // Using the same method to set and clear values to make sure we don't forget anything + private static void setValues(LaunchActivityItem instance, Intent intent, int ident, + ActivityInfo info, Configuration curConfig, Configuration overrideConfig, + CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, + int procState, Bundle state, PersistableBundle persistentState, + List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, + boolean isForward, ProfilerInfo profilerInfo) { + instance.mIntent = intent; + instance.mIdent = ident; + instance.mInfo = info; + instance.mCurConfig = curConfig; + instance.mOverrideConfig = overrideConfig; + instance.mCompatInfo = compatInfo; + instance.mReferrer = referrer; + instance.mVoiceInteractor = voiceInteractor; + instance.mProcState = procState; + instance.mState = state; + instance.mPersistentState = persistentState; + instance.mPendingResults = pendingResults; + instance.mPendingNewIntents = pendingNewIntents; + instance.mIsForward = isForward; + instance.mProfilerInfo = profilerInfo; + } } diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java index ee87261217fa..b3dddfb37eaa 100644 --- a/core/java/android/app/servertransaction/MoveToDisplayItem.java +++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java @@ -24,19 +24,16 @@ import android.os.IBinder; import android.os.Parcel; import android.os.Trace; +import java.util.Objects; + /** * Activity move to a different display message. * @hide */ public class MoveToDisplayItem extends ClientTransactionItem { - private final int mTargetDisplayId; - private final Configuration mConfiguration; - - public MoveToDisplayItem(int targetDisplayId, Configuration configuration) { - mTargetDisplayId = targetDisplayId; - mConfiguration = configuration; - } + private int mTargetDisplayId; + private Configuration mConfiguration; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -47,6 +44,30 @@ public class MoveToDisplayItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private MoveToDisplayItem() {} + + /** Obtain an instance initialized with provided params. */ + public static MoveToDisplayItem obtain(int targetDisplayId, Configuration configuration) { + MoveToDisplayItem instance = ObjectPool.obtain(MoveToDisplayItem.class); + if (instance == null) { + instance = new MoveToDisplayItem(); + } + instance.mTargetDisplayId = targetDisplayId; + instance.mConfiguration = configuration; + + return instance; + } + + @Override + public void recycle() { + mTargetDisplayId = 0; + mConfiguration = null; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ @@ -82,7 +103,7 @@ public class MoveToDisplayItem extends ClientTransactionItem { } final MoveToDisplayItem other = (MoveToDisplayItem) o; return mTargetDisplayId == other.mTargetDisplayId - && mConfiguration.equals(other.mConfiguration); + && Objects.equals(mConfiguration, other.mConfiguration); } @Override diff --git a/core/java/android/app/servertransaction/MultiWindowModeChangeItem.java b/core/java/android/app/servertransaction/MultiWindowModeChangeItem.java index 04ddb5e1378c..c3022d6facc7 100644 --- a/core/java/android/app/servertransaction/MultiWindowModeChangeItem.java +++ b/core/java/android/app/servertransaction/MultiWindowModeChangeItem.java @@ -21,6 +21,8 @@ import android.content.res.Configuration; import android.os.IBinder; import android.os.Parcel; +import java.util.Objects; + /** * Multi-window mode change message. * @hide @@ -29,14 +31,8 @@ import android.os.Parcel; // communicate multi-window mode change with WindowConfiguration. public class MultiWindowModeChangeItem extends ClientTransactionItem { - private final boolean mIsInMultiWindowMode; - private final Configuration mOverrideConfig; - - public MultiWindowModeChangeItem(boolean isInMultiWindowMode, - Configuration overrideConfig) { - mIsInMultiWindowMode = isInMultiWindowMode; - mOverrideConfig = overrideConfig; - } + private boolean mIsInMultiWindowMode; + private Configuration mOverrideConfig; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -45,6 +41,31 @@ public class MultiWindowModeChangeItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private MultiWindowModeChangeItem() {} + + /** Obtain an instance initialized with provided params. */ + public static MultiWindowModeChangeItem obtain(boolean isInMultiWindowMode, + Configuration overrideConfig) { + MultiWindowModeChangeItem instance = ObjectPool.obtain(MultiWindowModeChangeItem.class); + if (instance == null) { + instance = new MultiWindowModeChangeItem(); + } + instance.mIsInMultiWindowMode = isInMultiWindowMode; + instance.mOverrideConfig = overrideConfig; + + return instance; + } + + @Override + public void recycle() { + mIsInMultiWindowMode = false; + mOverrideConfig = null; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ @@ -81,7 +102,7 @@ public class MultiWindowModeChangeItem extends ClientTransactionItem { } final MultiWindowModeChangeItem other = (MultiWindowModeChangeItem) o; return mIsInMultiWindowMode == other.mIsInMultiWindowMode - && mOverrideConfig.equals(other.mOverrideConfig); + && Objects.equals(mOverrideConfig, other.mOverrideConfig); } @Override diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java index d01b455e5390..7dfde73c0534 100644 --- a/core/java/android/app/servertransaction/NewIntentItem.java +++ b/core/java/android/app/servertransaction/NewIntentItem.java @@ -25,6 +25,7 @@ import android.os.Trace; import com.android.internal.content.ReferrerIntent; import java.util.List; +import java.util.Objects; /** * New intent message. @@ -32,13 +33,8 @@ import java.util.List; */ public class NewIntentItem extends ClientTransactionItem { - private final List<ReferrerIntent> mIntents; - private final boolean mPause; - - public NewIntentItem(List<ReferrerIntent> intents, boolean pause) { - mIntents = intents; - mPause = pause; - } + private List<ReferrerIntent> mIntents; + private boolean mPause; // TODO(lifecycler): Switch new intent handling to this scheme. /*@Override @@ -60,6 +56,30 @@ public class NewIntentItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private NewIntentItem() {} + + /** Obtain an instance initialized with provided params. */ + public static NewIntentItem obtain(List<ReferrerIntent> intents, boolean pause) { + NewIntentItem instance = ObjectPool.obtain(NewIntentItem.class); + if (instance == null) { + instance = new NewIntentItem(); + } + instance.mIntents = intents; + instance.mPause = pause; + + return instance; + } + + @Override + public void recycle() { + mIntents = null; + mPause = false; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ @@ -95,7 +115,7 @@ public class NewIntentItem extends ClientTransactionItem { return false; } final NewIntentItem other = (NewIntentItem) o; - return mPause == other.mPause && mIntents.equals(other.mIntents); + return mPause == other.mPause && Objects.equals(mIntents, other.mIntents); } @Override diff --git a/core/java/android/app/servertransaction/ObjectPool.java b/core/java/android/app/servertransaction/ObjectPool.java new file mode 100644 index 000000000000..98121253f486 --- /dev/null +++ b/core/java/android/app/servertransaction/ObjectPool.java @@ -0,0 +1,73 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.servertransaction; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; + +/** + * An object pool that can provide reused objects if available. + * @hide + */ +class ObjectPool { + + private static final Object sPoolSync = new Object(); + private static final Map<Class, LinkedList<? 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. + * @return An instance or null if there is none. + */ + public static <T extends ObjectPoolItem> T obtain(Class<T> itemClass) { + synchronized (sPoolSync) { + @SuppressWarnings("unchecked") + LinkedList<T> itemPool = (LinkedList<T>) sPoolMap.get(itemClass); + if (itemPool != null && !itemPool.isEmpty()) { + return itemPool.poll(); + } + return null; + } + } + + /** + * Recycle the object to the pool. The object should be properly cleared before this. + * @param item The object to recycle. + * @see ObjectPoolItem#recycle() + */ + public static <T extends ObjectPoolItem> void recycle(T item) { + synchronized (sPoolSync) { + @SuppressWarnings("unchecked") + LinkedList<T> itemPool = (LinkedList<T>) sPoolMap.get(item.getClass()); + if (itemPool == null) { + itemPool = new LinkedList<>(); + sPoolMap.put(item.getClass(), itemPool); + } + if (itemPool.contains(item)) { + throw new IllegalStateException("Trying to recycle already recycled item"); + } + + if (itemPool.size() < MAX_POOL_SIZE) { + itemPool.add(item); + } + } + } +} diff --git a/core/java/android/app/servertransaction/ObjectPoolItem.java b/core/java/android/app/servertransaction/ObjectPoolItem.java new file mode 100644 index 000000000000..17bd4f30640f --- /dev/null +++ b/core/java/android/app/servertransaction/ObjectPoolItem.java @@ -0,0 +1,29 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.servertransaction; + +/** + * Base interface for all lifecycle items that can be put in object pool. + * @hide + */ +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. + */ + void recycle(); +} diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java index 634da04a09bf..880fef73c6f2 100644 --- a/core/java/android/app/servertransaction/PauseActivityItem.java +++ b/core/java/android/app/servertransaction/PauseActivityItem.java @@ -33,23 +33,10 @@ public class PauseActivityItem extends ActivityLifecycleItem { private static final String TAG = "PauseActivityItem"; - private final boolean mFinished; - private final boolean mUserLeaving; - private final int mConfigChanges; - private final boolean mDontReport; - - public PauseActivityItem() { - this(false /* finished */, false /* userLeaving */, 0 /* configChanges */, - true /* dontReport */); - } - - public PauseActivityItem(boolean finished, boolean userLeaving, int configChanges, - boolean dontReport) { - mFinished = finished; - mUserLeaving = userLeaving; - mConfigChanges = configChanges; - mDontReport = dontReport; - } + private boolean mFinished; + private boolean mUserLeaving; + private int mConfigChanges; + private boolean mDontReport; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -79,6 +66,49 @@ public class PauseActivityItem extends ActivityLifecycleItem { } } + + // ObjectPoolItem implementation + + private PauseActivityItem() {} + + /** Obtain an instance initialized with provided params. */ + public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges, + boolean dontReport) { + PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class); + if (instance == null) { + instance = new PauseActivityItem(); + } + instance.mFinished = finished; + instance.mUserLeaving = userLeaving; + instance.mConfigChanges = configChanges; + instance.mDontReport = dontReport; + + return instance; + } + + /** Obtain an instance initialized with default params. */ + public static PauseActivityItem obtain() { + PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class); + if (instance == null) { + instance = new PauseActivityItem(); + } + instance.mFinished = false; + instance.mUserLeaving = false; + instance.mConfigChanges = 0; + instance.mDontReport = true; + + return instance; + } + + @Override + public void recycle() { + mFinished = false; + mUserLeaving = false; + mConfigChanges = 0; + mDontReport = false; + ObjectPool.recycle(this); + } + // Parcelable implementation /** Write to Parcel. */ diff --git a/core/java/android/app/servertransaction/PipModeChangeItem.java b/core/java/android/app/servertransaction/PipModeChangeItem.java index 7c74e6f76656..b999cd7e295e 100644 --- a/core/java/android/app/servertransaction/PipModeChangeItem.java +++ b/core/java/android/app/servertransaction/PipModeChangeItem.java @@ -21,6 +21,8 @@ import android.content.res.Configuration; import android.os.IBinder; import android.os.Parcel; +import java.util.Objects; + /** * Picture in picture mode change message. * @hide @@ -29,13 +31,8 @@ import android.os.Parcel; // communicate multi-window mode change with WindowConfiguration. public class PipModeChangeItem extends ClientTransactionItem { - private final boolean mIsInPipMode; - private final Configuration mOverrideConfig; - - public PipModeChangeItem(boolean isInPipMode, Configuration overrideConfig) { - mIsInPipMode = isInPipMode; - mOverrideConfig = overrideConfig; - } + private boolean mIsInPipMode; + private Configuration mOverrideConfig; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -44,6 +41,30 @@ public class PipModeChangeItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private PipModeChangeItem() {} + + /** Obtain an instance initialized with provided params. */ + public static PipModeChangeItem obtain(boolean isInPipMode, Configuration overrideConfig) { + PipModeChangeItem instance = ObjectPool.obtain(PipModeChangeItem.class); + if (instance == null) { + instance = new PipModeChangeItem(); + } + instance.mIsInPipMode = isInPipMode; + instance.mOverrideConfig = overrideConfig; + + return instance; + } + + @Override + public void recycle() { + mIsInPipMode = false; + mOverrideConfig = null; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ @@ -78,7 +99,8 @@ public class PipModeChangeItem extends ClientTransactionItem { return false; } final PipModeChangeItem other = (PipModeChangeItem) o; - return mIsInPipMode == other.mIsInPipMode && mOverrideConfig.equals(other.mOverrideConfig); + return mIsInPipMode == other.mIsInPipMode + && Objects.equals(mOverrideConfig, other.mOverrideConfig); } @Override diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java index d659b80bb54f..9249c6e8ed54 100644 --- a/core/java/android/app/servertransaction/ResumeActivityItem.java +++ b/core/java/android/app/servertransaction/ResumeActivityItem.java @@ -33,21 +33,9 @@ public class ResumeActivityItem extends ActivityLifecycleItem { private static final String TAG = "ResumeActivityItem"; - private final int mProcState; - private final boolean mUpdateProcState; - private final boolean mIsForward; - - public ResumeActivityItem(boolean isForward) { - mProcState = ActivityManager.PROCESS_STATE_UNKNOWN; - mUpdateProcState = false; - mIsForward = isForward; - } - - public ResumeActivityItem(int procState, boolean isForward) { - mProcState = procState; - mUpdateProcState = true; - mIsForward = isForward; - } + private int mProcState; + private boolean mUpdateProcState; + private boolean mIsForward; @Override public void preExecute(ClientTransactionHandler client, IBinder token) { @@ -81,6 +69,45 @@ public class ResumeActivityItem extends ActivityLifecycleItem { } + // ObjectPoolItem implementation + + private ResumeActivityItem() {} + + /** Obtain an instance initialized with provided params. */ + public static ResumeActivityItem obtain(int procState, boolean isForward) { + ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class); + if (instance == null) { + instance = new ResumeActivityItem(); + } + instance.mProcState = procState; + instance.mUpdateProcState = true; + instance.mIsForward = isForward; + + return instance; + } + + /** Obtain an instance initialized with provided params. */ + public static ResumeActivityItem obtain(boolean isForward) { + ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class); + if (instance == null) { + instance = new ResumeActivityItem(); + } + instance.mProcState = ActivityManager.PROCESS_STATE_UNKNOWN; + instance.mUpdateProcState = false; + instance.mIsForward = isForward; + + return instance; + } + + @Override + public void recycle() { + mProcState = ActivityManager.PROCESS_STATE_UNKNOWN; + mUpdateProcState = false; + mIsForward = false; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java index 6e49386b9c38..5c5c3041344f 100644 --- a/core/java/android/app/servertransaction/StopActivityItem.java +++ b/core/java/android/app/servertransaction/StopActivityItem.java @@ -31,13 +31,8 @@ public class StopActivityItem extends ActivityLifecycleItem { private static final String TAG = "StopActivityItem"; - private final boolean mShowWindow; - private final int mConfigChanges; - - public StopActivityItem(boolean showWindow, int configChanges) { - mShowWindow = showWindow; - mConfigChanges = configChanges; - } + private boolean mShowWindow; + private int mConfigChanges; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -59,6 +54,30 @@ public class StopActivityItem extends ActivityLifecycleItem { } + // ObjectPoolItem implementation + + private StopActivityItem() {} + + /** Obtain an instance initialized with provided params. */ + public static StopActivityItem obtain(boolean showWindow, int configChanges) { + StopActivityItem instance = ObjectPool.obtain(StopActivityItem.class); + if (instance == null) { + instance = new StopActivityItem(); + } + instance.mShowWindow = showWindow; + instance.mConfigChanges = configChanges; + + return instance; + } + + @Override + public void recycle() { + mShowWindow = false; + mConfigChanges = 0; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java index bd24824f142d..5b0ea6b1f9d4 100644 --- a/core/java/android/app/servertransaction/TransactionExecutor.java +++ b/core/java/android/app/servertransaction/TransactionExecutor.java @@ -243,8 +243,6 @@ public class TransactionExecutor { } private static void log(String message) { - if (DEBUG_RESOLVER) { - Slog.d(TAG, message); - } + if (DEBUG_RESOLVER) Slog.d(TAG, message); } } diff --git a/core/java/android/app/servertransaction/WindowVisibilityItem.java b/core/java/android/app/servertransaction/WindowVisibilityItem.java index 6fcdcfa9efd6..d9956b1348b1 100644 --- a/core/java/android/app/servertransaction/WindowVisibilityItem.java +++ b/core/java/android/app/servertransaction/WindowVisibilityItem.java @@ -29,11 +29,7 @@ import android.os.Trace; */ public class WindowVisibilityItem extends ClientTransactionItem { - private final boolean mShowWindow; - - public WindowVisibilityItem(boolean showWindow) { - mShowWindow = showWindow; - } + private boolean mShowWindow; @Override public void execute(ClientTransactionHandler client, IBinder token, @@ -44,6 +40,28 @@ public class WindowVisibilityItem extends ClientTransactionItem { } + // ObjectPoolItem implementation + + private WindowVisibilityItem() {} + + /** Obtain an instance initialized with provided params. */ + public static WindowVisibilityItem obtain(boolean showWindow) { + WindowVisibilityItem instance = ObjectPool.obtain(WindowVisibilityItem.class); + if (instance == null) { + instance = new WindowVisibilityItem(); + } + instance.mShowWindow = showWindow; + + return instance; + } + + @Override + public void recycle() { + mShowWindow = false; + ObjectPool.recycle(this); + } + + // Parcelable implementation /** Write to Parcel. */ diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java index ea2dd59a4313..b1f855246320 100644 --- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java @@ -42,7 +42,7 @@ public class ClientTransactionTests { ClientTransactionHandler clientTransactionHandler = mock(ClientTransactionHandler.class); IBinder token = mock(IBinder.class); - ClientTransaction transaction = new ClientTransaction(null /* client */, + ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token /* activityToken */); transaction.addCallback(callback1); transaction.addCallback(callback2); diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java new file mode 100644 index 000000000000..aefc47e95512 --- /dev/null +++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java @@ -0,0 +1,287 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.servertransaction; + +import static android.app.servertransaction.TestUtils.config; +import static android.app.servertransaction.TestUtils.referrerIntentList; +import static android.app.servertransaction.TestUtils.resultInfoList; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; + +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.res.CompatibilityInfo; +import android.content.res.Configuration; +import android.os.Binder; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.platform.test.annotations.Presubmit; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +@Presubmit +public class ObjectPoolTests { + + // 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. + + @Test + public void testRecycleActivityConfigurationChangeItem() { + ActivityConfigurationChangeItem emptyItem = ActivityConfigurationChangeItem.obtain(null); + ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain(config()); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + ActivityConfigurationChangeItem item2 = ActivityConfigurationChangeItem.obtain(config()); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleActivityResultItem() { + ActivityResultItem emptyItem = ActivityResultItem.obtain(null); + ActivityResultItem item = ActivityResultItem.obtain(resultInfoList()); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + ActivityResultItem item2 = ActivityResultItem.obtain(resultInfoList()); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleConfigurationChangeItem() { + ConfigurationChangeItem emptyItem = ConfigurationChangeItem.obtain(null); + ConfigurationChangeItem item = ConfigurationChangeItem.obtain(config()); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + ConfigurationChangeItem item2 = ConfigurationChangeItem.obtain(config()); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleDestroyActivityItem() { + DestroyActivityItem emptyItem = DestroyActivityItem.obtain(false, 0); + DestroyActivityItem item = DestroyActivityItem.obtain(true, 117); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + DestroyActivityItem item2 = DestroyActivityItem.obtain(true, 14); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleLaunchActivityItem() { + Intent intent = new Intent("action"); + int ident = 57; + ActivityInfo activityInfo = new ActivityInfo(); + activityInfo.flags = 42; + activityInfo.maxAspectRatio = 2.4f; + activityInfo.launchToken = "token"; + activityInfo.applicationInfo = new ApplicationInfo(); + activityInfo.packageName = "packageName"; + activityInfo.name = "name"; + Configuration overrideConfig = new Configuration(); + overrideConfig.assetsSeq = 5; + CompatibilityInfo compat = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; + String referrer = "referrer"; + int procState = 4; + Bundle bundle = new Bundle(); + bundle.putString("key", "value"); + PersistableBundle persistableBundle = new PersistableBundle(); + persistableBundle.putInt("k", 4); + + LaunchActivityItem emptyItem = LaunchActivityItem.obtain(null, 0, null, null, null, null, + null, null, 0, null, null, null, null, false, null); + LaunchActivityItem item = LaunchActivityItem.obtain(intent, ident, activityInfo, + config(), overrideConfig, compat, referrer, null /* voiceInteractor */, + procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(), + true /* isForward */, null /* profilerInfo */); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + LaunchActivityItem item2 = LaunchActivityItem.obtain(intent, ident, activityInfo, + config(), overrideConfig, compat, referrer, null /* voiceInteractor */, + procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(), + true /* isForward */, null /* profilerInfo */); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleMoveToDisplayItem() { + MoveToDisplayItem emptyItem = MoveToDisplayItem.obtain(0, null); + MoveToDisplayItem item = MoveToDisplayItem.obtain(4, config()); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + MoveToDisplayItem item2 = MoveToDisplayItem.obtain(3, config()); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleMultiWindowModeChangeItem() { + MultiWindowModeChangeItem emptyItem = MultiWindowModeChangeItem.obtain(false, null); + MultiWindowModeChangeItem item = MultiWindowModeChangeItem.obtain(true, config()); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + MultiWindowModeChangeItem item2 = MultiWindowModeChangeItem.obtain(true, config()); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleNewIntentItem() { + NewIntentItem emptyItem = NewIntentItem.obtain(null, false); + NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), true); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + NewIntentItem item2 = NewIntentItem.obtain(referrerIntentList(), true); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecyclePauseActivityItemItem() { + PauseActivityItem emptyItem = PauseActivityItem.obtain(false, false, 0, false); + PauseActivityItem item = PauseActivityItem.obtain(true, true, 5, true); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + PauseActivityItem item2 = PauseActivityItem.obtain(true, false, 5, true); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecyclePipModeChangeItem() { + PipModeChangeItem emptyItem = PipModeChangeItem.obtain(false, null); + PipModeChangeItem item = PipModeChangeItem.obtain(true, config()); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + PipModeChangeItem item2 = PipModeChangeItem.obtain(true, config()); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleResumeActivityItem() { + ResumeActivityItem emptyItem = ResumeActivityItem.obtain(false); + ResumeActivityItem item = ResumeActivityItem.obtain(3, true); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + ResumeActivityItem item2 = ResumeActivityItem.obtain(2, true); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleStopItem() { + StopActivityItem emptyItem = StopActivityItem.obtain(false, 0); + StopActivityItem item = StopActivityItem.obtain(true, 4); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + StopActivityItem item2 = StopActivityItem.obtain(true, 3); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleWindowVisibleItem() { + WindowVisibilityItem emptyItem = WindowVisibilityItem.obtain(false); + WindowVisibilityItem item = WindowVisibilityItem.obtain(true); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + WindowVisibilityItem item2 = WindowVisibilityItem.obtain(true); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } + + @Test + public void testRecycleClientTransaction() { + ClientTransaction emptyItem = ClientTransaction.obtain(null, null); + ClientTransaction item = ClientTransaction.obtain(null, new Binder()); + assertNotSame(item, emptyItem); + assertFalse(item.equals(emptyItem)); + + item.recycle(); + assertEquals(item, emptyItem); + + ClientTransaction item2 = ClientTransaction.obtain(null, new Binder()); + assertSame(item, item2); + assertFalse(item2.equals(emptyItem)); + } +} diff --git a/core/tests/coretests/src/android/app/servertransaction/TestUtils.java b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java new file mode 100644 index 000000000000..e92351609256 --- /dev/null +++ b/core/tests/coretests/src/android/app/servertransaction/TestUtils.java @@ -0,0 +1,74 @@ +/* + * Copyright 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.servertransaction; + +import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; + +import android.app.ResultInfo; +import android.content.Intent; +import android.content.res.Configuration; + +import com.android.internal.content.ReferrerIntent; + +import java.util.ArrayList; +import java.util.List; + +class TestUtils { + + static Configuration config() { + Configuration config = new Configuration(); + config.densityDpi = 10; + config.fontScale = 0.3f; + config.screenHeightDp = 15; + config.orientation = ORIENTATION_LANDSCAPE; + return config; + } + + static List<ResultInfo> resultInfoList() { + String resultWho1 = "resultWho1"; + int requestCode1 = 7; + int resultCode1 = 4; + Intent data1 = new Intent("action1"); + ResultInfo resultInfo1 = new ResultInfo(resultWho1, requestCode1, resultCode1, data1); + + String resultWho2 = "resultWho2"; + int requestCode2 = 8; + int resultCode2 = 6; + Intent data2 = new Intent("action2"); + ResultInfo resultInfo2 = new ResultInfo(resultWho2, requestCode2, resultCode2, data2); + + List<ResultInfo> resultInfoList = new ArrayList<>(); + resultInfoList.add(resultInfo1); + resultInfoList.add(resultInfo2); + + return resultInfoList; + } + + static List<ReferrerIntent> referrerIntentList() { + Intent intent1 = new Intent("action1"); + ReferrerIntent referrerIntent1 = new ReferrerIntent(intent1, "referrer1"); + + Intent intent2 = new Intent("action2"); + ReferrerIntent referrerIntent2 = new ReferrerIntent(intent2, "referrer2"); + + List<ReferrerIntent> referrerIntents = new ArrayList<>(); + referrerIntents.add(referrerIntent1); + referrerIntents.add(referrerIntent2); + + return referrerIntents; + } +} diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java index d2830047505b..e575650393f0 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java @@ -38,6 +38,7 @@ import static org.mockito.Mockito.when; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.os.IBinder; +import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -51,6 +52,7 @@ import java.util.ArrayList; /** Test {@link TransactionExecutor} logic. */ @RunWith(AndroidJUnit4.class) @SmallTest +@Presubmit public class TransactionExecutorTests { private TransactionExecutor mExecutor; @@ -171,7 +173,7 @@ public class TransactionExecutorTests { ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class); IBinder token = mock(IBinder.class); - ClientTransaction transaction = new ClientTransaction(null /* client */, + ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token /* activityToken */); transaction.addCallback(callback1); transaction.addCallback(callback2); @@ -188,10 +190,10 @@ public class TransactionExecutorTests { @Test public void testRequiredStateResolution() { - ActivityResultItem activityResultItem = new ActivityResultItem(new ArrayList<>()); + ActivityResultItem activityResultItem = ActivityResultItem.obtain(new ArrayList<>()); IBinder token = mock(IBinder.class); - ClientTransaction transaction = new ClientTransaction(null /* client */, + ClientTransaction transaction = ClientTransaction.obtain(null /* client */, token /* activityToken */); transaction.addCallback(activityResultItem); diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java index f6c656d5f17c..4b1f2dab61b9 100644 --- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java +++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java @@ -16,7 +16,9 @@ package android.app.servertransaction; -import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static android.app.servertransaction.TestUtils.config; +import static android.app.servertransaction.TestUtils.referrerIntentList; +import static android.app.servertransaction.TestUtils.resultInfoList; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; @@ -57,7 +59,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -77,7 +78,7 @@ public class TransactionParcelTests { @Test public void testConfigurationChange() { // Write to parcel - ConfigurationChangeItem item = new ConfigurationChangeItem(config()); + ConfigurationChangeItem item = ConfigurationChangeItem.obtain(config()); writeAndPrepareForReading(item); // Read from parcel and assert @@ -90,7 +91,7 @@ public class TransactionParcelTests { @Test public void testActivityConfigChange() { // Write to parcel - ActivityConfigurationChangeItem item = new ActivityConfigurationChangeItem(config()); + ActivityConfigurationChangeItem item = ActivityConfigurationChangeItem.obtain(config()); writeAndPrepareForReading(item); // Read from parcel and assert @@ -104,7 +105,7 @@ public class TransactionParcelTests { @Test public void testMoveToDisplay() { // Write to parcel - MoveToDisplayItem item = new MoveToDisplayItem(4 /* targetDisplayId */, config()); + MoveToDisplayItem item = MoveToDisplayItem.obtain(4 /* targetDisplayId */, config()); writeAndPrepareForReading(item); // Read from parcel and assert @@ -117,7 +118,7 @@ public class TransactionParcelTests { @Test public void testNewIntent() { // Write to parcel - NewIntentItem item = new NewIntentItem(referrerIntentList(), true /* pause */); + NewIntentItem item = NewIntentItem.obtain(referrerIntentList(), true /* pause */); writeAndPrepareForReading(item); // Read from parcel and assert @@ -130,7 +131,7 @@ public class TransactionParcelTests { @Test public void testActivityResult() { // Write to parcel - ActivityResultItem item = new ActivityResultItem(resultInfoList()); + ActivityResultItem item = ActivityResultItem.obtain(resultInfoList()); writeAndPrepareForReading(item); // Read from parcel and assert @@ -143,7 +144,7 @@ public class TransactionParcelTests { @Test public void testPipModeChange() { // Write to parcel - PipModeChangeItem item = new PipModeChangeItem(true /* isInPipMode */, config()); + PipModeChangeItem item = PipModeChangeItem.obtain(true /* isInPipMode */, config()); writeAndPrepareForReading(item); // Read from parcel and assert @@ -156,7 +157,7 @@ public class TransactionParcelTests { @Test public void testMultiWindowModeChange() { // Write to parcel - MultiWindowModeChangeItem item = new MultiWindowModeChangeItem( + MultiWindowModeChangeItem item = MultiWindowModeChangeItem.obtain( true /* isInMultiWindowMode */, config()); writeAndPrepareForReading(item); @@ -171,7 +172,7 @@ public class TransactionParcelTests { @Test public void testWindowVisibilityChange() { // Write to parcel - WindowVisibilityItem item = new WindowVisibilityItem(true /* showWindow */); + WindowVisibilityItem item = WindowVisibilityItem.obtain(true /* showWindow */); writeAndPrepareForReading(item); // Read from parcel and assert @@ -181,7 +182,7 @@ public class TransactionParcelTests { assertTrue(item.equals(result)); // Check different value - item = new WindowVisibilityItem(false); + item = WindowVisibilityItem.obtain(false); mParcel = Parcel.obtain(); writeAndPrepareForReading(item); @@ -195,7 +196,7 @@ public class TransactionParcelTests { @Test public void testDestroy() { - DestroyActivityItem item = new DestroyActivityItem(true /* finished */, + DestroyActivityItem item = DestroyActivityItem.obtain(true /* finished */, 135 /* configChanges */); writeAndPrepareForReading(item); @@ -228,7 +229,7 @@ public class TransactionParcelTests { PersistableBundle persistableBundle = new PersistableBundle(); persistableBundle.putInt("k", 4); - LaunchActivityItem item = new LaunchActivityItem(intent, ident, activityInfo, + LaunchActivityItem item = LaunchActivityItem.obtain(intent, ident, activityInfo, config(), overrideConfig, compat, referrer, null /* voiceInteractor */, procState, bundle, persistableBundle, resultInfoList(), referrerIntentList(), true /* isForward */, null /* profilerInfo */); @@ -244,8 +245,8 @@ public class TransactionParcelTests { @Test public void testPause() { // Write to parcel - PauseActivityItem item = new PauseActivityItem(true /* finished */, true /* userLeaving */, - 135 /* configChanges */, true /* dontReport */); + PauseActivityItem item = PauseActivityItem.obtain(true /* finished */, + true /* userLeaving */, 135 /* configChanges */, true /* dontReport */); writeAndPrepareForReading(item); // Read from parcel and assert @@ -258,7 +259,8 @@ public class TransactionParcelTests { @Test public void testResume() { // Write to parcel - ResumeActivityItem item = new ResumeActivityItem(27 /* procState */, true /* isForward */); + ResumeActivityItem item = ResumeActivityItem.obtain(27 /* procState */, + true /* isForward */); writeAndPrepareForReading(item); // Read from parcel and assert @@ -271,7 +273,8 @@ public class TransactionParcelTests { @Test public void testStop() { // Write to parcel - StopActivityItem item = new StopActivityItem(true /* showWindow */, 14 /* configChanges */); + StopActivityItem item = StopActivityItem.obtain(true /* showWindow */, + 14 /* configChanges */); writeAndPrepareForReading(item); // Read from parcel and assert @@ -284,16 +287,17 @@ public class TransactionParcelTests { @Test public void testClientTransaction() { // Write to parcel - WindowVisibilityItem callback1 = new WindowVisibilityItem(true); - ActivityConfigurationChangeItem callback2 = new ActivityConfigurationChangeItem(config()); + WindowVisibilityItem callback1 = WindowVisibilityItem.obtain(true); + ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain( + config()); - StopActivityItem lifecycleRequest = new StopActivityItem(true /* showWindow */, + StopActivityItem lifecycleRequest = StopActivityItem.obtain(true /* showWindow */, 78 /* configChanges */); IApplicationThread appThread = new StubAppThread(); Binder activityToken = new Binder(); - ClientTransaction transaction = new ClientTransaction(appThread, activityToken); + ClientTransaction transaction = ClientTransaction.obtain(appThread, activityToken); transaction.addCallback(callback1); transaction.addCallback(callback2); transaction.setLifecycleStateRequest(lifecycleRequest); @@ -310,13 +314,14 @@ public class TransactionParcelTests { @Test public void testClientTransactionCallbacksOnly() { // Write to parcel - WindowVisibilityItem callback1 = new WindowVisibilityItem(true); - ActivityConfigurationChangeItem callback2 = new ActivityConfigurationChangeItem(config()); + WindowVisibilityItem callback1 = WindowVisibilityItem.obtain(true); + ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain( + config()); IApplicationThread appThread = new StubAppThread(); Binder activityToken = new Binder(); - ClientTransaction transaction = new ClientTransaction(appThread, activityToken); + ClientTransaction transaction = ClientTransaction.obtain(appThread, activityToken); transaction.addCallback(callback1); transaction.addCallback(callback2); @@ -332,13 +337,13 @@ public class TransactionParcelTests { @Test public void testClientTransactionLifecycleOnly() { // Write to parcel - StopActivityItem lifecycleRequest = new StopActivityItem(true /* showWindow */, + StopActivityItem lifecycleRequest = StopActivityItem.obtain(true /* showWindow */, 78 /* configChanges */); IApplicationThread appThread = new StubAppThread(); Binder activityToken = new Binder(); - ClientTransaction transaction = new ClientTransaction(appThread, activityToken); + ClientTransaction transaction = ClientTransaction.obtain(appThread, activityToken); transaction.setLifecycleStateRequest(lifecycleRequest); writeAndPrepareForReading(transaction); @@ -350,49 +355,6 @@ public class TransactionParcelTests { assertTrue(transaction.equals(result)); } - private static List<ResultInfo> resultInfoList() { - String resultWho1 = "resultWho1"; - int requestCode1 = 7; - int resultCode1 = 4; - Intent data1 = new Intent("action1"); - ResultInfo resultInfo1 = new ResultInfo(resultWho1, requestCode1, resultCode1, data1); - - String resultWho2 = "resultWho2"; - int requestCode2 = 8; - int resultCode2 = 6; - Intent data2 = new Intent("action2"); - ResultInfo resultInfo2 = new ResultInfo(resultWho2, requestCode2, resultCode2, data2); - - List<ResultInfo> resultInfoList = new ArrayList<>(); - resultInfoList.add(resultInfo1); - resultInfoList.add(resultInfo2); - - return resultInfoList; - } - - private static List<ReferrerIntent> referrerIntentList() { - Intent intent1 = new Intent("action1"); - ReferrerIntent referrerIntent1 = new ReferrerIntent(intent1, "referrer1"); - - Intent intent2 = new Intent("action2"); - ReferrerIntent referrerIntent2 = new ReferrerIntent(intent2, "referrer2"); - - List<ReferrerIntent> referrerIntents = new ArrayList<>(); - referrerIntents.add(referrerIntent1); - referrerIntents.add(referrerIntent2); - - return referrerIntents; - } - - private static Configuration config() { - Configuration config = new Configuration(); - config.densityDpi = 10; - config.fontScale = 0.3f; - config.screenHeightDp = 15; - config.orientation = ORIENTATION_LANDSCAPE; - return config; - } - /** Write to {@link #mParcel} and reset its position to prepare for reading from the start. */ private void writeAndPrepareForReading(Parcelable parcelable) { parcelable.writeToParcel(mParcel, 0 /* flags */); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2ca2c27d0958..635d68d27a04 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -20676,7 +20676,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc " + app.processName + " new config " + configCopy); mLifecycleManager.scheduleTransaction(app.thread, - new ConfigurationChangeItem(configCopy)); + ConfigurationChangeItem.obtain(configCopy)); } } catch (Exception e) { Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e); diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index a089e6ceef78..60a623677825 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -618,7 +618,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo + ", displayId=" + displayId + ", config=" + config); service.mLifecycleManager.scheduleTransaction(app.thread, appToken, - new MoveToDisplayItem(displayId, config)); + MoveToDisplayItem.obtain(displayId, config)); } catch (RemoteException e) { // If process died, whatever. } @@ -636,7 +636,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo + config); service.mLifecycleManager.scheduleTransaction(app.thread, appToken, - new ActivityConfigurationChangeItem(config)); + ActivityConfigurationChangeItem.obtain(config)); } catch (RemoteException e) { // If process died, whatever. } @@ -663,7 +663,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo private void scheduleMultiWindowModeChanged(Configuration overrideConfig) { try { service.mLifecycleManager.scheduleTransaction(app.thread, appToken, - new MultiWindowModeChangeItem(mLastReportedMultiWindowMode, + MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode, overrideConfig)); } catch (Exception e) { // If process died, I don't care. @@ -691,7 +691,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo private void schedulePictureInPictureModeChanged(Configuration overrideConfig) { try { service.mLifecycleManager.scheduleTransaction(app.thread, appToken, - new PipModeChangeItem(mLastReportedPictureInPictureMode, + PipModeChangeItem.obtain(mLastReportedPictureInPictureMode, overrideConfig)); } catch (Exception e) { // If process died, no one cares. @@ -1380,7 +1380,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo ArrayList<ReferrerIntent> ar = new ArrayList<>(1); ar.add(rintent); service.mLifecycleManager.scheduleTransaction(app.thread, appToken, - new NewIntentItem(ar, state == PAUSED)); + NewIntentItem.obtain(ar, state == PAUSED)); unsent = false; } catch (RemoteException e) { Slog.w(TAG, "Exception thrown sending new intent to " + this, e); @@ -1603,7 +1603,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo sleeping = false; app.pendingUiClean = true; service.mLifecycleManager.scheduleTransaction(app.thread, appToken, - new WindowVisibilityItem(true /* showWindow */)); + WindowVisibilityItem.obtain(true /* showWindow */)); // The activity may be waiting for stop, but that is no longer appropriate for it. mStackSupervisor.mStoppingActivities.remove(this); mStackSupervisor.mGoingToSleepActivities.remove(this); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index edf9813497e0..a30413f20d35 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1430,7 +1430,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai mService.updateUsageStats(prev, false); mService.mLifecycleManager.scheduleTransaction(prev.app.thread, prev.appToken, - new PauseActivityItem(prev.finishing, userLeaving, + PauseActivityItem.obtain(prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately)); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. @@ -2061,7 +2061,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Scheduling invisibility: " + r); mService.mLifecycleManager.scheduleTransaction(r.app.thread, r.appToken, - new WindowVisibilityItem(false /* showWindow */)); + WindowVisibilityItem.obtain(false /* showWindow */)); } // Reset the flag indicating that an app can enter picture-in-picture once the @@ -2589,13 +2589,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_RESULTS) Slog.v(TAG_RESULTS, "Delivering results to " + next + ": " + a); mService.mLifecycleManager.scheduleTransaction(next.app.thread, - next.appToken, new ActivityResultItem(a)); + next.appToken, ActivityResultItem.obtain(a)); } } if (next.newIntents != null) { mService.mLifecycleManager.scheduleTransaction(next.app.thread, - next.appToken, new NewIntentItem(next.newIntents, + next.appToken, NewIntentItem.obtain(next.newIntents, false /* andPause */)); } @@ -2614,7 +2614,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai next.app.forceProcessStateUpTo(mService.mTopProcessState); next.clearOptionsLocked(); mService.mLifecycleManager.scheduleTransaction(next.app.thread, next.appToken, - new ResumeActivityItem(next.app.repProcState, + ResumeActivityItem.obtain(next.app.repProcState, mService.isNextTransitionForward())); if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed " @@ -3266,7 +3266,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai list.add(new ResultInfo(resultWho, requestCode, resultCode, data)); mService.mLifecycleManager.scheduleTransaction(r.app.thread, r.appToken, - new ActivityResultItem(list)); + ActivityResultItem.obtain(list)); return; } catch (Exception e) { Slog.w(TAG, "Exception thrown sending result to " + r, e); @@ -3395,7 +3395,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai EventLogTags.writeAmStopActivity( r.userId, System.identityHashCode(r), r.shortComponentName); mService.mLifecycleManager.scheduleTransaction(r.app.thread, r.appToken, - new StopActivityItem(r.visible, r.configChangeFlags)); + StopActivityItem.obtain(r.visible, r.configChangeFlags)); if (shouldSleepOrShutDownActivities()) { r.setSleeping(true); } @@ -4201,7 +4201,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai try { if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r); mService.mLifecycleManager.scheduleTransaction(r.app.thread, r.appToken, - new DestroyActivityItem(r.finishing, r.configChangeFlags)); + DestroyActivityItem.obtain(r.finishing, r.configChangeFlags)); } catch (Exception e) { // We can just ignore exceptions here... if the process // has crashed, our death notification will clean things diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 7561d0f8ad96..fc902de908a9 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1400,9 +1400,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Create activity launch transaction. - final ClientTransaction clientTransaction = new ClientTransaction(app.thread, + final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread, r.appToken); - clientTransaction.addCallback(new LaunchActivityItem(new Intent(r.intent), + clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global // and override configs. @@ -1415,9 +1415,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { - lifecycleItem = new ResumeActivityItem(mService.isNextTransitionForward()); + lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { - lifecycleItem = new PauseActivityItem(); + lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); diff --git a/services/core/java/com/android/server/am/ClientLifecycleManager.java b/services/core/java/com/android/server/am/ClientLifecycleManager.java index c04d103c7ff5..cc70f18dc747 100644 --- a/services/core/java/com/android/server/am/ClientLifecycleManager.java +++ b/services/core/java/com/android/server/am/ClientLifecycleManager.java @@ -43,6 +43,7 @@ class ClientLifecycleManager { */ void scheduleTransaction(ClientTransaction transaction) throws RemoteException { transaction.schedule(); + transaction.recycle(); } /** @@ -100,7 +101,7 @@ class ClientLifecycleManager { */ private static ClientTransaction transactionWithState(@NonNull IApplicationThread client, @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) { - final ClientTransaction clientTransaction = new ClientTransaction(client, activityToken); + final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken); clientTransaction.setLifecycleStateRequest(stateRequest); return clientTransaction; } @@ -113,7 +114,7 @@ class ClientLifecycleManager { */ private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client, IBinder activityToken, @NonNull ClientTransactionItem callback) { - final ClientTransaction clientTransaction = new ClientTransaction(client, activityToken); + final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken); clientTransaction.addCallback(callback); return clientTransaction; } |