Home | History | Annotate | Download | only in servertransaction
      1 /*
      2  * Copyright 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app.servertransaction;
     18 
     19 import static android.app.ActivityThread.DEBUG_MEMORY_TRIM;
     20 
     21 import android.app.ActivityManager;
     22 import android.app.ActivityThread.ActivityClientRecord;
     23 import android.os.Build;
     24 import android.os.Bundle;
     25 import android.os.PersistableBundle;
     26 import android.os.RemoteException;
     27 import android.os.TransactionTooLargeException;
     28 import android.util.Log;
     29 import android.util.LogWriter;
     30 import android.util.Slog;
     31 
     32 import com.android.internal.util.IndentingPrintWriter;
     33 
     34 /**
     35  * Container that has data pending to be used at later stages of
     36  * {@link android.app.servertransaction.ClientTransaction}.
     37  * An instance of this class is passed to each individual transaction item, so it can use some
     38  * information from previous steps or add some for the following steps.
     39  *
     40  * @hide
     41  */
     42 public class PendingTransactionActions {
     43     private boolean mRestoreInstanceState;
     44     private boolean mCallOnPostCreate;
     45     private Bundle mOldState;
     46     private StopInfo mStopInfo;
     47     private boolean mReportRelaunchToWM;
     48 
     49     public PendingTransactionActions() {
     50         clear();
     51     }
     52 
     53     /** Reset the state of the instance to default, non-initialized values. */
     54     public void clear() {
     55         mRestoreInstanceState = false;
     56         mCallOnPostCreate = false;
     57         mOldState = null;
     58         mStopInfo = null;
     59     }
     60 
     61     /** Getter */
     62     public boolean shouldRestoreInstanceState() {
     63         return mRestoreInstanceState;
     64     }
     65 
     66     public void setRestoreInstanceState(boolean restoreInstanceState) {
     67         mRestoreInstanceState = restoreInstanceState;
     68     }
     69 
     70     /** Getter */
     71     public boolean shouldCallOnPostCreate() {
     72         return mCallOnPostCreate;
     73     }
     74 
     75     public void setCallOnPostCreate(boolean callOnPostCreate) {
     76         mCallOnPostCreate = callOnPostCreate;
     77     }
     78 
     79     public Bundle getOldState() {
     80         return mOldState;
     81     }
     82 
     83     public void setOldState(Bundle oldState) {
     84         mOldState = oldState;
     85     }
     86 
     87     public StopInfo getStopInfo() {
     88         return mStopInfo;
     89     }
     90 
     91     public void setStopInfo(StopInfo stopInfo) {
     92         mStopInfo = stopInfo;
     93     }
     94 
     95     /**
     96      * Check if we should report an activity relaunch to WindowManager. We report back for every
     97      * relaunch request to ActivityManager, but only for those that were actually finished to we
     98      * report to WindowManager.
     99      */
    100     public boolean shouldReportRelaunchToWindowManager() {
    101         return mReportRelaunchToWM;
    102     }
    103 
    104     /**
    105      * Set if we should report an activity relaunch to WindowManager. We report back for every
    106      * relaunch request to ActivityManager, but only for those that were actually finished we report
    107      * to WindowManager.
    108      */
    109     public void setReportRelaunchToWindowManager(boolean reportToWm) {
    110         mReportRelaunchToWM = reportToWm;
    111     }
    112 
    113     /** Reports to server about activity stop. */
    114     public static class StopInfo implements Runnable {
    115         private static final String TAG = "ActivityStopInfo";
    116 
    117         private ActivityClientRecord mActivity;
    118         private Bundle mState;
    119         private PersistableBundle mPersistentState;
    120         private CharSequence mDescription;
    121 
    122         public void setActivity(ActivityClientRecord activity) {
    123             mActivity = activity;
    124         }
    125 
    126         public void setState(Bundle state) {
    127             mState = state;
    128         }
    129 
    130         public void setPersistentState(PersistableBundle persistentState) {
    131             mPersistentState = persistentState;
    132         }
    133 
    134         public void setDescription(CharSequence description) {
    135             mDescription = description;
    136         }
    137 
    138         @Override
    139         public void run() {
    140             // Tell activity manager we have been stopped.
    141             try {
    142                 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + mActivity);
    143                 // TODO(lifecycler): Use interface callback instead of AMS.
    144                 ActivityManager.getService().activityStopped(
    145                         mActivity.token, mState, mPersistentState, mDescription);
    146             } catch (RemoteException ex) {
    147                 // Dump statistics about bundle to help developers debug
    148                 final LogWriter writer = new LogWriter(Log.WARN, TAG);
    149                 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
    150                 pw.println("Bundle stats:");
    151                 Bundle.dumpStats(pw, mState);
    152                 pw.println("PersistableBundle stats:");
    153                 Bundle.dumpStats(pw, mPersistentState);
    154 
    155                 if (ex instanceof TransactionTooLargeException
    156                         && mActivity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
    157                     Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
    158                     return;
    159                 }
    160                 throw ex.rethrowFromSystemServer();
    161             }
    162         }
    163     }
    164 }
    165