Loading config/hiddenapi-light-greylist.txt +0 −1 Original line number Original line Diff line number Diff line Loading @@ -46,7 +46,6 @@ Landroid/app/ActivityThread$H;->BIND_SERVICE:I Landroid/app/ActivityThread$H;->CREATE_SERVICE:I Landroid/app/ActivityThread$H;->CREATE_SERVICE:I Landroid/app/ActivityThread$H;->EXIT_APPLICATION:I Landroid/app/ActivityThread$H;->EXIT_APPLICATION:I Landroid/app/ActivityThread$H;->RECEIVER:I Landroid/app/ActivityThread$H;->RECEIVER:I Landroid/app/ActivityThread$H;->RELAUNCH_ACTIVITY:I Landroid/app/ActivityThread$H;->REMOVE_PROVIDER:I Landroid/app/ActivityThread$H;->REMOVE_PROVIDER:I Landroid/app/ActivityThread$H;->SERVICE_ARGS:I Landroid/app/ActivityThread$H;->SERVICE_ARGS:I Landroid/app/ActivityThread$H;->STOP_SERVICE:I Landroid/app/ActivityThread$H;->STOP_SERVICE:I Loading core/java/android/app/ActivityThread.java +35 −108 Original line number Original line Diff line number Diff line Loading @@ -113,6 +113,7 @@ import android.util.DisplayMetrics; import android.util.EventLog; import android.util.EventLog; import android.util.Log; import android.util.Log; import android.util.LogPrinter; import android.util.LogPrinter; import android.util.MergedConfiguration; import android.util.Pair; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.Slog; Loading Loading @@ -204,7 +205,7 @@ public final class ActivityThread extends ClientTransactionHandler { private static final boolean DEBUG_SERVICE = false; private static final boolean DEBUG_SERVICE = false; public static final boolean DEBUG_MEMORY_TRIM = false; public static final boolean DEBUG_MEMORY_TRIM = false; private static final boolean DEBUG_PROVIDER = false; private static final boolean DEBUG_PROVIDER = false; private static final boolean DEBUG_ORDER = false; public static final boolean DEBUG_ORDER = false; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; private static final int LOG_AM_ON_PAUSE_CALLED = 30021; private static final int LOG_AM_ON_PAUSE_CALLED = 30021; Loading Loading @@ -398,7 +399,6 @@ public final class ActivityThread extends ClientTransactionHandler { boolean startsNotResumed; boolean startsNotResumed; public final boolean isForward; public final boolean isForward; int pendingConfigChanges; int pendingConfigChanges; boolean onlyLocalRequest; Window mPendingRemoveWindow; Window mPendingRemoveWindow; WindowManager mPendingRemoveWindowManager; WindowManager mPendingRemoveWindowManager; Loading Loading @@ -520,7 +520,6 @@ public final class ActivityThread extends ClientTransactionHandler { sb.append(", startsNotResumed=").append(startsNotResumed); sb.append(", startsNotResumed=").append(startsNotResumed); sb.append(", isForward=").append(isForward); sb.append(", isForward=").append(isForward); sb.append(", pendingConfigChanges=").append(pendingConfigChanges); sb.append(", pendingConfigChanges=").append(pendingConfigChanges); sb.append(", onlyLocalRequest=").append(onlyLocalRequest); sb.append(", preserveWindow=").append(mPreserveWindow); sb.append(", preserveWindow=").append(mPreserveWindow); if (activity != null) { if (activity != null) { sb.append(", Activity{"); sb.append(", Activity{"); Loading Loading @@ -765,15 +764,6 @@ public final class ActivityThread extends ClientTransactionHandler { sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); } } @Override public final void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, Configuration overrideConfig, boolean preserveWindow) { requestRelaunchActivity(token, pendingResults, pendingNewIntents, configChanges, notResumed, config, overrideConfig, true, preserveWindow); } public final void scheduleReceiver(Intent intent, ActivityInfo info, public final void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) { boolean sync, int sendingUser, int processState) { Loading Loading @@ -1531,7 +1521,6 @@ public final class ActivityThread extends ClientTransactionHandler { public static final int UNBIND_SERVICE = 122; public static final int UNBIND_SERVICE = 122; public static final int DUMP_SERVICE = 123; public static final int DUMP_SERVICE = 123; public static final int LOW_MEMORY = 124; public static final int LOW_MEMORY = 124; public static final int RELAUNCH_ACTIVITY = 126; public static final int PROFILER_CONTROL = 127; public static final int PROFILER_CONTROL = 127; public static final int CREATE_BACKUP_AGENT = 128; public static final int CREATE_BACKUP_AGENT = 128; public static final int DESTROY_BACKUP_AGENT = 129; public static final int DESTROY_BACKUP_AGENT = 129; Loading Loading @@ -1577,7 +1566,6 @@ public final class ActivityThread extends ClientTransactionHandler { case UNBIND_SERVICE: return "UNBIND_SERVICE"; case UNBIND_SERVICE: return "UNBIND_SERVICE"; case DUMP_SERVICE: return "DUMP_SERVICE"; case DUMP_SERVICE: return "DUMP_SERVICE"; case LOW_MEMORY: return "LOW_MEMORY"; case LOW_MEMORY: return "LOW_MEMORY"; case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; case PROFILER_CONTROL: return "PROFILER_CONTROL"; case PROFILER_CONTROL: return "PROFILER_CONTROL"; case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; Loading Loading @@ -1611,12 +1599,6 @@ public final class ActivityThread extends ClientTransactionHandler { public void handleMessage(Message msg) { public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { switch (msg.what) { case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case BIND_APPLICATION: case BIND_APPLICATION: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); AppBindData data = (AppBindData)msg.obj; AppBindData data = (AppBindData)msg.obj; Loading Loading @@ -3726,20 +3708,6 @@ public final class ActivityThread extends ClientTransactionHandler { } } r.activity.performResume(r.startsNotResumed); r.activity.performResume(r.startsNotResumed); synchronized (mResourcesManager) { // If there is a pending local relaunch that was requested when the activity was // paused, it will put the activity into paused state when it finally happens. // Since the activity resumed before being relaunched, we don't want that to // happen, so we need to clear the request to relaunch paused. for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) { final ActivityClientRecord relaunching = mRelaunchingActivities.get(i); if (relaunching.token == r.token && relaunching.onlyLocalRequest && relaunching.startsNotResumed) { relaunching.startsNotResumed = false; } } } EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(), EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(), r.activity.getComponentName().getClassName(), reason); r.activity.getComponentName().getClassName(), reason); Loading Loading @@ -3888,14 +3856,12 @@ public final class ActivityThread extends ClientTransactionHandler { } } } } if (!r.onlyLocalRequest) { r.nextIdle = mNewActivities; r.nextIdle = mNewActivities; mNewActivities = r; mNewActivities = r; if (localLOGV) Slog.v( if (localLOGV) { TAG, "Scheduling idle handler for " + r); Slog.v(TAG, "Scheduling idle handler for " + r); Looper.myQueue().addIdleHandler(new Idler()); } } r.onlyLocalRequest = false; Looper.myQueue().addIdleHandler(new Idler()); } else { } else { // If an exception was thrown when trying to resume, then // If an exception was thrown when trying to resume, then // just end this activity. // just end this activity. Loading Loading @@ -4586,15 +4552,12 @@ public final class ActivityThread extends ClientTransactionHandler { mSomeActivitiesChanged = true; mSomeActivitiesChanged = true; } } /** @Override * @param preserveWindow Whether the activity should try to reuse the window it created, public ActivityClientRecord prepareRelaunchActivity(IBinder token, * including the decor view after the relaunch. */ public final void requestRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, int configChanges, MergedConfiguration config, boolean preserveWindow) { Configuration overrideConfig, boolean fromServer, boolean preserveWindow) { ActivityClientRecord target = null; ActivityClientRecord target = null; boolean scheduleRelaunch = false; synchronized (mResourcesManager) { synchronized (mResourcesManager) { for (int i=0; i<mRelaunchingActivities.size(); i++) { for (int i=0; i<mRelaunchingActivities.size(); i++) { Loading @@ -4616,57 +4579,31 @@ public final class ActivityThread extends ClientTransactionHandler { r.pendingIntents = pendingNewIntents; r.pendingIntents = pendingNewIntents; } } } } // For each relaunch request, activity manager expects an answer if (!r.onlyLocalRequest && fromServer) { try { ActivityManager.getService().activityRelaunched(token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } break; break; } } } } if (target == null) { if (target == null) { if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:" if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null"); + fromServer); target = new ActivityClientRecord(); target = new ActivityClientRecord(); target.token = token; target.token = token; target.pendingResults = pendingResults; target.pendingResults = pendingResults; target.pendingIntents = pendingNewIntents; target.pendingIntents = pendingNewIntents; target.mPreserveWindow = preserveWindow; target.mPreserveWindow = preserveWindow; if (!fromServer) { final ActivityClientRecord existing = mActivities.get(token); if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing); if (existing != null) { if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= " + existing.paused);; target.startsNotResumed = existing.paused; target.overrideConfig = existing.overrideConfig; } target.onlyLocalRequest = true; } mRelaunchingActivities.add(target); mRelaunchingActivities.add(target); sendMessage(H.RELAUNCH_ACTIVITY, target); scheduleRelaunch = true; } if (fromServer) { target.startsNotResumed = notResumed; target.onlyLocalRequest = false; } if (config != null) { target.createdConfig = config; } if (overrideConfig != null) { target.overrideConfig = overrideConfig; } } target.createdConfig = config.getGlobalConfiguration(); target.overrideConfig = config.getOverrideConfiguration(); target.pendingConfigChanges |= configChanges; target.pendingConfigChanges |= configChanges; } } return scheduleRelaunch ? target : null; } } private void handleRelaunchActivity(ActivityClientRecord tmp) { @Override public void handleRelaunchActivity(ActivityClientRecord tmp, PendingTransactionActions pendingActions) { // If we are getting ready to gc after going to the background, well // If we are getting ready to gc after going to the background, well // we are back active so skip it. // we are back active so skip it. unscheduleGcIdler(); unscheduleGcIdler(); Loading Loading @@ -4735,18 +4672,10 @@ public final class ActivityThread extends ClientTransactionHandler { ActivityClientRecord r = mActivities.get(tmp.token); ActivityClientRecord r = mActivities.get(tmp.token); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); if (r == null) { if (r == null) { if (!tmp.onlyLocalRequest) { try { ActivityManager.getService().activityRelaunched(tmp.token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return; return; } } r.activity.mConfigChangeFlags |= configChanges; r.activity.mConfigChangeFlags |= configChanges; r.onlyLocalRequest = tmp.onlyLocalRequest; r.mPreserveWindow = tmp.mPreserveWindow; r.mPreserveWindow = tmp.mPreserveWindow; r.activity.mChangingConfigurations = true; r.activity.mChangingConfigurations = true; Loading @@ -4763,9 +4692,9 @@ public final class ActivityThread extends ClientTransactionHandler { // preserved by the server, so we want to notify it that we are preparing to replace // preserved by the server, so we want to notify it that we are preparing to replace // everything // everything try { try { if (r.mPreserveWindow || r.onlyLocalRequest) { if (r.mPreserveWindow) { WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( r.token, !r.onlyLocalRequest); r.token, true /* childrenOnly */); } } } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); Loading Loading @@ -4804,26 +4733,24 @@ public final class ActivityThread extends ClientTransactionHandler { r.startsNotResumed = tmp.startsNotResumed; r.startsNotResumed = tmp.startsNotResumed; r.overrideConfig = tmp.overrideConfig; r.overrideConfig = tmp.overrideConfig; // TODO(lifecycler): Move relaunch to lifecycler. PendingTransactionActions pendingActions = new PendingTransactionActions(); handleLaunchActivity(r, pendingActions); handleLaunchActivity(r, pendingActions); handleStartActivity(r, pendingActions); // Only report a successful relaunch to WindowManager. handleResumeActivity(r.token, false /* clearHide */, r.isForward, "relaunch"); pendingActions.setReportRelaunchToWindowManager(true); if (r.startsNotResumed) { performPauseActivity(r, false /* finished */, "relaunch", pendingActions); } } if (!tmp.onlyLocalRequest) { @Override public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) { try { try { ActivityManager.getService().activityRelaunched(r.token); ActivityManager.getService().activityRelaunched(token); if (r.window != null) { final ActivityClientRecord r = mActivities.get(token); if (pendingActions.shouldReportRelaunchToWindowManager() && r != null && r.window != null) { r.window.reportActivityRelaunched(); r.window.reportActivityRelaunched(); } } } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } } } } private void callActivityOnSaveInstanceState(ActivityClientRecord r) { private void callActivityOnSaveInstanceState(ActivityClientRecord r) { r.state = new Bundle(); r.state = new Bundle(); Loading core/java/android/app/ClientTransactionHandler.java +34 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.os.IBinder; import android.os.IBinder; import android.util.MergedConfiguration; import com.android.internal.content.ReferrerIntent; import com.android.internal.content.ReferrerIntent; Loading Loading @@ -123,6 +124,39 @@ public abstract class ClientTransactionHandler { */ */ public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token); public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token); /** * Prepare activity relaunch to update internal bookkeeping. This is used to track multiple * relaunch and config update requests. * @param token Activity token. * @param pendingResults Activity results to be delivered. * @param pendingNewIntents New intent messages to be delivered. * @param configChanges Mask of configuration changes that have occurred. * @param config New configuration applied to the activity. * @param preserveWindow Whether the activity should try to reuse the window it created, * including the decor view after the relaunch. * @return An initialized instance of {@link ActivityThread.ActivityClientRecord} to use during * relaunch, or {@code null} if relaunch cancelled. */ public abstract ActivityThread.ActivityClientRecord prepareRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, MergedConfiguration config, boolean preserveWindow); /** * Perform activity relaunch. * @param r Activity client record prepared for relaunch. * @param pendingActions Pending actions to be used on later stages of activity transaction. * */ public abstract void handleRelaunchActivity(ActivityThread.ActivityClientRecord r, PendingTransactionActions pendingActions); /** * Report that relaunch request was handled. * @param token Target activity token. * @param pendingActions Pending actions initialized on earlier stages of activity transaction. * Used to check if we should report relaunch to WM. * */ public abstract void reportRelaunch(IBinder token, PendingTransactionActions pendingActions); /** /** * Debugging output. * Debugging output. * @param pw {@link PrintWriter} to write logs to. * @param pw {@link PrintWriter} to write logs to. Loading core/java/android/app/IApplicationThread.aidl +0 −3 Original line number Original line Diff line number Diff line Loading @@ -83,9 +83,6 @@ oneway interface IApplicationThread { int resultCode, in String data, in Bundle extras, boolean ordered, int resultCode, in String data, in Bundle extras, boolean ordered, boolean sticky, int sendingUser, int processState); boolean sticky, int sendingUser, int processState); void scheduleLowMemory(); void scheduleLowMemory(); void scheduleRelaunchActivity(IBinder token, in List<ResultInfo> pendingResults, in List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, in Configuration config, in Configuration overrideConfig, boolean preserveWindow); void scheduleSleeping(IBinder token, boolean sleeping); void scheduleSleeping(IBinder token, boolean sleeping); void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType); void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType); void setSchedulingGroup(int group); void setSchedulingGroup(int group); Loading core/java/android/app/servertransaction/ActivityRelaunchItem.java 0 → 100644 +176 −0 Original line number Original line Diff line number Diff line /* * 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.ActivityThread.DEBUG_ORDER; import android.app.ActivityThread; import android.app.ClientTransactionHandler; import android.app.ResultInfo; import android.os.IBinder; import android.os.Parcel; import android.os.Trace; import android.util.MergedConfiguration; import android.util.Slog; import com.android.internal.content.ReferrerIntent; import java.util.List; import java.util.Objects; /** * Activity relaunch callback. * @hide */ public class ActivityRelaunchItem extends ClientTransactionItem { private static final String TAG = "ActivityRelaunchItem"; private List<ResultInfo> mPendingResults; private List<ReferrerIntent> mPendingNewIntents; private int mConfigChanges; private MergedConfiguration mConfig; private boolean mPreserveWindow; /** * A record that was properly configured for relaunch. Execution will be cancelled if not * initialized after {@link #preExecute(ClientTransactionHandler, IBinder)}. */ private ActivityThread.ActivityClientRecord mActivityClientRecord; @Override public void preExecute(ClientTransactionHandler client, IBinder token) { mActivityClientRecord = client.prepareRelaunchActivity(token, mPendingResults, mPendingNewIntents, mConfigChanges, mConfig, mPreserveWindow); } @Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { if (mActivityClientRecord == null) { if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled"); return; } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); client.handleRelaunchActivity(mActivityClientRecord, pendingActions); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } @Override public void postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { client.reportRelaunch(token, pendingActions); } // ObjectPoolItem implementation private ActivityRelaunchItem() {} /** Obtain an instance initialized with provided params. */ public static ActivityRelaunchItem obtain(List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, MergedConfiguration config, boolean preserveWindow) { ActivityRelaunchItem instance = ObjectPool.obtain(ActivityRelaunchItem.class); if (instance == null) { instance = new ActivityRelaunchItem(); } instance.mPendingResults = pendingResults; instance.mPendingNewIntents = pendingNewIntents; instance.mConfigChanges = configChanges; instance.mConfig = config; instance.mPreserveWindow = preserveWindow; return instance; } @Override public void recycle() { mPendingResults = null; mPendingNewIntents = null; mConfigChanges = 0; mConfig = null; mPreserveWindow = false; mActivityClientRecord = null; ObjectPool.recycle(this); } // Parcelable implementation /** Write to Parcel. */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeTypedList(mPendingResults, flags); dest.writeTypedList(mPendingNewIntents, flags); dest.writeInt(mConfigChanges); dest.writeTypedObject(mConfig, flags); dest.writeBoolean(mPreserveWindow); } /** Read from Parcel. */ private ActivityRelaunchItem(Parcel in) { mPendingResults = in.createTypedArrayList(ResultInfo.CREATOR); mPendingNewIntents = in.createTypedArrayList(ReferrerIntent.CREATOR); mConfigChanges = in.readInt(); mConfig = in.readTypedObject(MergedConfiguration.CREATOR); mPreserveWindow = in.readBoolean(); } public static final Creator<ActivityRelaunchItem> CREATOR = new Creator<ActivityRelaunchItem>() { public ActivityRelaunchItem createFromParcel(Parcel in) { return new ActivityRelaunchItem(in); } public ActivityRelaunchItem[] newArray(int size) { return new ActivityRelaunchItem[size]; } }; @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final ActivityRelaunchItem other = (ActivityRelaunchItem) o; return Objects.equals(mPendingResults, other.mPendingResults) && Objects.equals(mPendingNewIntents, other.mPendingNewIntents) && mConfigChanges == other.mConfigChanges && Objects.equals(mConfig, other.mConfig) && mPreserveWindow == other.mPreserveWindow; } @Override public int hashCode() { int result = 17; result = 31 * result + Objects.hashCode(mPendingResults); result = 31 * result + Objects.hashCode(mPendingNewIntents); result = 31 * result + mConfigChanges; result = 31 * result + Objects.hashCode(mConfig); result = 31 * result + (mPreserveWindow ? 1 : 0); return result; } @Override public String toString() { return "ActivityRelaunchItem{pendingResults=" + mPendingResults + ",pendingNewIntents=" + mPendingNewIntents + ",configChanges=" + mConfigChanges + ",config=" + mConfig + ",preserveWindow" + mPreserveWindow + "}"; } } Loading
config/hiddenapi-light-greylist.txt +0 −1 Original line number Original line Diff line number Diff line Loading @@ -46,7 +46,6 @@ Landroid/app/ActivityThread$H;->BIND_SERVICE:I Landroid/app/ActivityThread$H;->CREATE_SERVICE:I Landroid/app/ActivityThread$H;->CREATE_SERVICE:I Landroid/app/ActivityThread$H;->EXIT_APPLICATION:I Landroid/app/ActivityThread$H;->EXIT_APPLICATION:I Landroid/app/ActivityThread$H;->RECEIVER:I Landroid/app/ActivityThread$H;->RECEIVER:I Landroid/app/ActivityThread$H;->RELAUNCH_ACTIVITY:I Landroid/app/ActivityThread$H;->REMOVE_PROVIDER:I Landroid/app/ActivityThread$H;->REMOVE_PROVIDER:I Landroid/app/ActivityThread$H;->SERVICE_ARGS:I Landroid/app/ActivityThread$H;->SERVICE_ARGS:I Landroid/app/ActivityThread$H;->STOP_SERVICE:I Landroid/app/ActivityThread$H;->STOP_SERVICE:I Loading
core/java/android/app/ActivityThread.java +35 −108 Original line number Original line Diff line number Diff line Loading @@ -113,6 +113,7 @@ import android.util.DisplayMetrics; import android.util.EventLog; import android.util.EventLog; import android.util.Log; import android.util.Log; import android.util.LogPrinter; import android.util.LogPrinter; import android.util.MergedConfiguration; import android.util.Pair; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.Slog; Loading Loading @@ -204,7 +205,7 @@ public final class ActivityThread extends ClientTransactionHandler { private static final boolean DEBUG_SERVICE = false; private static final boolean DEBUG_SERVICE = false; public static final boolean DEBUG_MEMORY_TRIM = false; public static final boolean DEBUG_MEMORY_TRIM = false; private static final boolean DEBUG_PROVIDER = false; private static final boolean DEBUG_PROVIDER = false; private static final boolean DEBUG_ORDER = false; public static final boolean DEBUG_ORDER = false; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; private static final long MIN_TIME_BETWEEN_GCS = 5*1000; private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; private static final int LOG_AM_ON_PAUSE_CALLED = 30021; private static final int LOG_AM_ON_PAUSE_CALLED = 30021; Loading Loading @@ -398,7 +399,6 @@ public final class ActivityThread extends ClientTransactionHandler { boolean startsNotResumed; boolean startsNotResumed; public final boolean isForward; public final boolean isForward; int pendingConfigChanges; int pendingConfigChanges; boolean onlyLocalRequest; Window mPendingRemoveWindow; Window mPendingRemoveWindow; WindowManager mPendingRemoveWindowManager; WindowManager mPendingRemoveWindowManager; Loading Loading @@ -520,7 +520,6 @@ public final class ActivityThread extends ClientTransactionHandler { sb.append(", startsNotResumed=").append(startsNotResumed); sb.append(", startsNotResumed=").append(startsNotResumed); sb.append(", isForward=").append(isForward); sb.append(", isForward=").append(isForward); sb.append(", pendingConfigChanges=").append(pendingConfigChanges); sb.append(", pendingConfigChanges=").append(pendingConfigChanges); sb.append(", onlyLocalRequest=").append(onlyLocalRequest); sb.append(", preserveWindow=").append(mPreserveWindow); sb.append(", preserveWindow=").append(mPreserveWindow); if (activity != null) { if (activity != null) { sb.append(", Activity{"); sb.append(", Activity{"); Loading Loading @@ -765,15 +764,6 @@ public final class ActivityThread extends ClientTransactionHandler { sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); sendMessage(H.SLEEPING, token, sleeping ? 1 : 0); } } @Override public final void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, Configuration overrideConfig, boolean preserveWindow) { requestRelaunchActivity(token, pendingResults, pendingNewIntents, configChanges, notResumed, config, overrideConfig, true, preserveWindow); } public final void scheduleReceiver(Intent intent, ActivityInfo info, public final void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) { boolean sync, int sendingUser, int processState) { Loading Loading @@ -1531,7 +1521,6 @@ public final class ActivityThread extends ClientTransactionHandler { public static final int UNBIND_SERVICE = 122; public static final int UNBIND_SERVICE = 122; public static final int DUMP_SERVICE = 123; public static final int DUMP_SERVICE = 123; public static final int LOW_MEMORY = 124; public static final int LOW_MEMORY = 124; public static final int RELAUNCH_ACTIVITY = 126; public static final int PROFILER_CONTROL = 127; public static final int PROFILER_CONTROL = 127; public static final int CREATE_BACKUP_AGENT = 128; public static final int CREATE_BACKUP_AGENT = 128; public static final int DESTROY_BACKUP_AGENT = 129; public static final int DESTROY_BACKUP_AGENT = 129; Loading Loading @@ -1577,7 +1566,6 @@ public final class ActivityThread extends ClientTransactionHandler { case UNBIND_SERVICE: return "UNBIND_SERVICE"; case UNBIND_SERVICE: return "UNBIND_SERVICE"; case DUMP_SERVICE: return "DUMP_SERVICE"; case DUMP_SERVICE: return "DUMP_SERVICE"; case LOW_MEMORY: return "LOW_MEMORY"; case LOW_MEMORY: return "LOW_MEMORY"; case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; case PROFILER_CONTROL: return "PROFILER_CONTROL"; case PROFILER_CONTROL: return "PROFILER_CONTROL"; case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; Loading Loading @@ -1611,12 +1599,6 @@ public final class ActivityThread extends ClientTransactionHandler { public void handleMessage(Message msg) { public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { switch (msg.what) { case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case BIND_APPLICATION: case BIND_APPLICATION: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); AppBindData data = (AppBindData)msg.obj; AppBindData data = (AppBindData)msg.obj; Loading Loading @@ -3726,20 +3708,6 @@ public final class ActivityThread extends ClientTransactionHandler { } } r.activity.performResume(r.startsNotResumed); r.activity.performResume(r.startsNotResumed); synchronized (mResourcesManager) { // If there is a pending local relaunch that was requested when the activity was // paused, it will put the activity into paused state when it finally happens. // Since the activity resumed before being relaunched, we don't want that to // happen, so we need to clear the request to relaunch paused. for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) { final ActivityClientRecord relaunching = mRelaunchingActivities.get(i); if (relaunching.token == r.token && relaunching.onlyLocalRequest && relaunching.startsNotResumed) { relaunching.startsNotResumed = false; } } } EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(), EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(), r.activity.getComponentName().getClassName(), reason); r.activity.getComponentName().getClassName(), reason); Loading Loading @@ -3888,14 +3856,12 @@ public final class ActivityThread extends ClientTransactionHandler { } } } } if (!r.onlyLocalRequest) { r.nextIdle = mNewActivities; r.nextIdle = mNewActivities; mNewActivities = r; mNewActivities = r; if (localLOGV) Slog.v( if (localLOGV) { TAG, "Scheduling idle handler for " + r); Slog.v(TAG, "Scheduling idle handler for " + r); Looper.myQueue().addIdleHandler(new Idler()); } } r.onlyLocalRequest = false; Looper.myQueue().addIdleHandler(new Idler()); } else { } else { // If an exception was thrown when trying to resume, then // If an exception was thrown when trying to resume, then // just end this activity. // just end this activity. Loading Loading @@ -4586,15 +4552,12 @@ public final class ActivityThread extends ClientTransactionHandler { mSomeActivitiesChanged = true; mSomeActivitiesChanged = true; } } /** @Override * @param preserveWindow Whether the activity should try to reuse the window it created, public ActivityClientRecord prepareRelaunchActivity(IBinder token, * including the decor view after the relaunch. */ public final void requestRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, int configChanges, MergedConfiguration config, boolean preserveWindow) { Configuration overrideConfig, boolean fromServer, boolean preserveWindow) { ActivityClientRecord target = null; ActivityClientRecord target = null; boolean scheduleRelaunch = false; synchronized (mResourcesManager) { synchronized (mResourcesManager) { for (int i=0; i<mRelaunchingActivities.size(); i++) { for (int i=0; i<mRelaunchingActivities.size(); i++) { Loading @@ -4616,57 +4579,31 @@ public final class ActivityThread extends ClientTransactionHandler { r.pendingIntents = pendingNewIntents; r.pendingIntents = pendingNewIntents; } } } } // For each relaunch request, activity manager expects an answer if (!r.onlyLocalRequest && fromServer) { try { ActivityManager.getService().activityRelaunched(token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } break; break; } } } } if (target == null) { if (target == null) { if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:" if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null"); + fromServer); target = new ActivityClientRecord(); target = new ActivityClientRecord(); target.token = token; target.token = token; target.pendingResults = pendingResults; target.pendingResults = pendingResults; target.pendingIntents = pendingNewIntents; target.pendingIntents = pendingNewIntents; target.mPreserveWindow = preserveWindow; target.mPreserveWindow = preserveWindow; if (!fromServer) { final ActivityClientRecord existing = mActivities.get(token); if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing); if (existing != null) { if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= " + existing.paused);; target.startsNotResumed = existing.paused; target.overrideConfig = existing.overrideConfig; } target.onlyLocalRequest = true; } mRelaunchingActivities.add(target); mRelaunchingActivities.add(target); sendMessage(H.RELAUNCH_ACTIVITY, target); scheduleRelaunch = true; } if (fromServer) { target.startsNotResumed = notResumed; target.onlyLocalRequest = false; } if (config != null) { target.createdConfig = config; } if (overrideConfig != null) { target.overrideConfig = overrideConfig; } } target.createdConfig = config.getGlobalConfiguration(); target.overrideConfig = config.getOverrideConfiguration(); target.pendingConfigChanges |= configChanges; target.pendingConfigChanges |= configChanges; } } return scheduleRelaunch ? target : null; } } private void handleRelaunchActivity(ActivityClientRecord tmp) { @Override public void handleRelaunchActivity(ActivityClientRecord tmp, PendingTransactionActions pendingActions) { // If we are getting ready to gc after going to the background, well // If we are getting ready to gc after going to the background, well // we are back active so skip it. // we are back active so skip it. unscheduleGcIdler(); unscheduleGcIdler(); Loading Loading @@ -4735,18 +4672,10 @@ public final class ActivityThread extends ClientTransactionHandler { ActivityClientRecord r = mActivities.get(tmp.token); ActivityClientRecord r = mActivities.get(tmp.token); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); if (r == null) { if (r == null) { if (!tmp.onlyLocalRequest) { try { ActivityManager.getService().activityRelaunched(tmp.token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return; return; } } r.activity.mConfigChangeFlags |= configChanges; r.activity.mConfigChangeFlags |= configChanges; r.onlyLocalRequest = tmp.onlyLocalRequest; r.mPreserveWindow = tmp.mPreserveWindow; r.mPreserveWindow = tmp.mPreserveWindow; r.activity.mChangingConfigurations = true; r.activity.mChangingConfigurations = true; Loading @@ -4763,9 +4692,9 @@ public final class ActivityThread extends ClientTransactionHandler { // preserved by the server, so we want to notify it that we are preparing to replace // preserved by the server, so we want to notify it that we are preparing to replace // everything // everything try { try { if (r.mPreserveWindow || r.onlyLocalRequest) { if (r.mPreserveWindow) { WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( WindowManagerGlobal.getWindowSession().prepareToReplaceWindows( r.token, !r.onlyLocalRequest); r.token, true /* childrenOnly */); } } } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); Loading Loading @@ -4804,26 +4733,24 @@ public final class ActivityThread extends ClientTransactionHandler { r.startsNotResumed = tmp.startsNotResumed; r.startsNotResumed = tmp.startsNotResumed; r.overrideConfig = tmp.overrideConfig; r.overrideConfig = tmp.overrideConfig; // TODO(lifecycler): Move relaunch to lifecycler. PendingTransactionActions pendingActions = new PendingTransactionActions(); handleLaunchActivity(r, pendingActions); handleLaunchActivity(r, pendingActions); handleStartActivity(r, pendingActions); // Only report a successful relaunch to WindowManager. handleResumeActivity(r.token, false /* clearHide */, r.isForward, "relaunch"); pendingActions.setReportRelaunchToWindowManager(true); if (r.startsNotResumed) { performPauseActivity(r, false /* finished */, "relaunch", pendingActions); } } if (!tmp.onlyLocalRequest) { @Override public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) { try { try { ActivityManager.getService().activityRelaunched(r.token); ActivityManager.getService().activityRelaunched(token); if (r.window != null) { final ActivityClientRecord r = mActivities.get(token); if (pendingActions.shouldReportRelaunchToWindowManager() && r != null && r.window != null) { r.window.reportActivityRelaunched(); r.window.reportActivityRelaunched(); } } } catch (RemoteException e) { } catch (RemoteException e) { throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer(); } } } } } private void callActivityOnSaveInstanceState(ActivityClientRecord r) { private void callActivityOnSaveInstanceState(ActivityClientRecord r) { r.state = new Bundle(); r.state = new Bundle(); Loading
core/java/android/app/ClientTransactionHandler.java +34 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.os.IBinder; import android.os.IBinder; import android.util.MergedConfiguration; import com.android.internal.content.ReferrerIntent; import com.android.internal.content.ReferrerIntent; Loading Loading @@ -123,6 +124,39 @@ public abstract class ClientTransactionHandler { */ */ public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token); public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token); /** * Prepare activity relaunch to update internal bookkeeping. This is used to track multiple * relaunch and config update requests. * @param token Activity token. * @param pendingResults Activity results to be delivered. * @param pendingNewIntents New intent messages to be delivered. * @param configChanges Mask of configuration changes that have occurred. * @param config New configuration applied to the activity. * @param preserveWindow Whether the activity should try to reuse the window it created, * including the decor view after the relaunch. * @return An initialized instance of {@link ActivityThread.ActivityClientRecord} to use during * relaunch, or {@code null} if relaunch cancelled. */ public abstract ActivityThread.ActivityClientRecord prepareRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, MergedConfiguration config, boolean preserveWindow); /** * Perform activity relaunch. * @param r Activity client record prepared for relaunch. * @param pendingActions Pending actions to be used on later stages of activity transaction. * */ public abstract void handleRelaunchActivity(ActivityThread.ActivityClientRecord r, PendingTransactionActions pendingActions); /** * Report that relaunch request was handled. * @param token Target activity token. * @param pendingActions Pending actions initialized on earlier stages of activity transaction. * Used to check if we should report relaunch to WM. * */ public abstract void reportRelaunch(IBinder token, PendingTransactionActions pendingActions); /** /** * Debugging output. * Debugging output. * @param pw {@link PrintWriter} to write logs to. * @param pw {@link PrintWriter} to write logs to. Loading
core/java/android/app/IApplicationThread.aidl +0 −3 Original line number Original line Diff line number Diff line Loading @@ -83,9 +83,6 @@ oneway interface IApplicationThread { int resultCode, in String data, in Bundle extras, boolean ordered, int resultCode, in String data, in Bundle extras, boolean ordered, boolean sticky, int sendingUser, int processState); boolean sticky, int sendingUser, int processState); void scheduleLowMemory(); void scheduleLowMemory(); void scheduleRelaunchActivity(IBinder token, in List<ResultInfo> pendingResults, in List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, in Configuration config, in Configuration overrideConfig, boolean preserveWindow); void scheduleSleeping(IBinder token, boolean sleeping); void scheduleSleeping(IBinder token, boolean sleeping); void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType); void profilerControl(boolean start, in ProfilerInfo profilerInfo, int profileType); void setSchedulingGroup(int group); void setSchedulingGroup(int group); Loading
core/java/android/app/servertransaction/ActivityRelaunchItem.java 0 → 100644 +176 −0 Original line number Original line Diff line number Diff line /* * 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.ActivityThread.DEBUG_ORDER; import android.app.ActivityThread; import android.app.ClientTransactionHandler; import android.app.ResultInfo; import android.os.IBinder; import android.os.Parcel; import android.os.Trace; import android.util.MergedConfiguration; import android.util.Slog; import com.android.internal.content.ReferrerIntent; import java.util.List; import java.util.Objects; /** * Activity relaunch callback. * @hide */ public class ActivityRelaunchItem extends ClientTransactionItem { private static final String TAG = "ActivityRelaunchItem"; private List<ResultInfo> mPendingResults; private List<ReferrerIntent> mPendingNewIntents; private int mConfigChanges; private MergedConfiguration mConfig; private boolean mPreserveWindow; /** * A record that was properly configured for relaunch. Execution will be cancelled if not * initialized after {@link #preExecute(ClientTransactionHandler, IBinder)}. */ private ActivityThread.ActivityClientRecord mActivityClientRecord; @Override public void preExecute(ClientTransactionHandler client, IBinder token) { mActivityClientRecord = client.prepareRelaunchActivity(token, mPendingResults, mPendingNewIntents, mConfigChanges, mConfig, mPreserveWindow); } @Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { if (mActivityClientRecord == null) { if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled"); return; } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); client.handleRelaunchActivity(mActivityClientRecord, pendingActions); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } @Override public void postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { client.reportRelaunch(token, pendingActions); } // ObjectPoolItem implementation private ActivityRelaunchItem() {} /** Obtain an instance initialized with provided params. */ public static ActivityRelaunchItem obtain(List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, MergedConfiguration config, boolean preserveWindow) { ActivityRelaunchItem instance = ObjectPool.obtain(ActivityRelaunchItem.class); if (instance == null) { instance = new ActivityRelaunchItem(); } instance.mPendingResults = pendingResults; instance.mPendingNewIntents = pendingNewIntents; instance.mConfigChanges = configChanges; instance.mConfig = config; instance.mPreserveWindow = preserveWindow; return instance; } @Override public void recycle() { mPendingResults = null; mPendingNewIntents = null; mConfigChanges = 0; mConfig = null; mPreserveWindow = false; mActivityClientRecord = null; ObjectPool.recycle(this); } // Parcelable implementation /** Write to Parcel. */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeTypedList(mPendingResults, flags); dest.writeTypedList(mPendingNewIntents, flags); dest.writeInt(mConfigChanges); dest.writeTypedObject(mConfig, flags); dest.writeBoolean(mPreserveWindow); } /** Read from Parcel. */ private ActivityRelaunchItem(Parcel in) { mPendingResults = in.createTypedArrayList(ResultInfo.CREATOR); mPendingNewIntents = in.createTypedArrayList(ReferrerIntent.CREATOR); mConfigChanges = in.readInt(); mConfig = in.readTypedObject(MergedConfiguration.CREATOR); mPreserveWindow = in.readBoolean(); } public static final Creator<ActivityRelaunchItem> CREATOR = new Creator<ActivityRelaunchItem>() { public ActivityRelaunchItem createFromParcel(Parcel in) { return new ActivityRelaunchItem(in); } public ActivityRelaunchItem[] newArray(int size) { return new ActivityRelaunchItem[size]; } }; @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final ActivityRelaunchItem other = (ActivityRelaunchItem) o; return Objects.equals(mPendingResults, other.mPendingResults) && Objects.equals(mPendingNewIntents, other.mPendingNewIntents) && mConfigChanges == other.mConfigChanges && Objects.equals(mConfig, other.mConfig) && mPreserveWindow == other.mPreserveWindow; } @Override public int hashCode() { int result = 17; result = 31 * result + Objects.hashCode(mPendingResults); result = 31 * result + Objects.hashCode(mPendingNewIntents); result = 31 * result + mConfigChanges; result = 31 * result + Objects.hashCode(mConfig); result = 31 * result + (mPreserveWindow ? 1 : 0); return result; } @Override public String toString() { return "ActivityRelaunchItem{pendingResults=" + mPendingResults + ",pendingNewIntents=" + mPendingNewIntents + ",configChanges=" + mConfigChanges + ",config=" + mConfig + ",preserveWindow" + mPreserveWindow + "}"; } }