/* * 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_MEMORY_TRIM; import android.app.ActivityClient; import android.app.ActivityThread.ActivityClientRecord; import android.os.Build; import android.os.Bundle; import android.os.PersistableBundle; import android.os.TransactionTooLargeException; import android.util.Log; import android.util.LogWriter; import android.util.Slog; import com.android.internal.util.IndentingPrintWriter; /** * Container that has data pending to be used at later stages of * {@link android.app.servertransaction.ClientTransaction}. * An instance of this class is passed to each individual transaction item, so it can use some * information from previous steps or add some for the following steps. * * @hide */ public class PendingTransactionActions { private boolean mRestoreInstanceState; private boolean mCallOnPostCreate; private Bundle mOldState; private StopInfo mStopInfo; private boolean mReportRelaunchToWM; public PendingTransactionActions() { clear(); } /** Reset the state of the instance to default, non-initialized values. */ public void clear() { mRestoreInstanceState = false; mCallOnPostCreate = false; mOldState = null; mStopInfo = null; } /** Getter */ public boolean shouldRestoreInstanceState() { return mRestoreInstanceState; } public void setRestoreInstanceState(boolean restoreInstanceState) { mRestoreInstanceState = restoreInstanceState; } /** Getter */ public boolean shouldCallOnPostCreate() { return mCallOnPostCreate; } public void setCallOnPostCreate(boolean callOnPostCreate) { mCallOnPostCreate = callOnPostCreate; } public Bundle getOldState() { return mOldState; } public void setOldState(Bundle oldState) { mOldState = oldState; } public StopInfo getStopInfo() { return mStopInfo; } public void setStopInfo(StopInfo stopInfo) { mStopInfo = stopInfo; } /** * Check if we should report an activity relaunch to WindowManager. We report back for every * relaunch request to ActivityManager, but only for those that were actually finished to we * report to WindowManager. */ public boolean shouldReportRelaunchToWindowManager() { return mReportRelaunchToWM; } /** * Set if we should report an activity relaunch to WindowManager. We report back for every * relaunch request to ActivityManager, but only for those that were actually finished we report * to WindowManager. */ public void setReportRelaunchToWindowManager(boolean reportToWm) { mReportRelaunchToWM = reportToWm; } /** Reports to server about activity stop. */ public static class StopInfo implements Runnable { private static final String TAG = "ActivityStopInfo"; private ActivityClientRecord mActivity; private Bundle mState; private PersistableBundle mPersistentState; private CharSequence mDescription; public void setActivity(ActivityClientRecord activity) { mActivity = activity; } public void setState(Bundle state) { mState = state; } public void setPersistentState(PersistableBundle persistentState) { mPersistentState = persistentState; } public void setDescription(CharSequence description) { mDescription = description; } @Override public void run() { // Tell activity manager we have been stopped. try { if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + mActivity); // TODO(lifecycler): Use interface callback instead of AMS. ActivityClient.getInstance().activityStopped( mActivity.token, mState, mPersistentState, mDescription); } catch (RuntimeException ex) { // Dump statistics about bundle to help developers debug final LogWriter writer = new LogWriter(Log.WARN, TAG); final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); pw.println("Bundle stats:"); Bundle.dumpStats(pw, mState); pw.println("PersistableBundle stats:"); Bundle.dumpStats(pw, mPersistentState); if (ex.getCause() instanceof TransactionTooLargeException && mActivity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) { Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex); return; } throw ex; } } } }