Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2006 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;
     18 
     19 import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
     20 import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
     21 import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY;
     22 import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
     23 import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
     24 import static android.app.servertransaction.ActivityLifecycleItem.ON_START;
     25 import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
     26 import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
     27 import static android.content.ContentResolver.DEPRECATE_DATA_COLUMNS;
     28 import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX;
     29 import static android.view.Display.INVALID_DISPLAY;
     30 
     31 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
     32 
     33 import android.annotation.NonNull;
     34 import android.annotation.Nullable;
     35 import android.annotation.UnsupportedAppUsage;
     36 import android.app.assist.AssistContent;
     37 import android.app.assist.AssistStructure;
     38 import android.app.backup.BackupAgent;
     39 import android.app.servertransaction.ActivityLifecycleItem;
     40 import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
     41 import android.app.servertransaction.ActivityRelaunchItem;
     42 import android.app.servertransaction.ActivityResultItem;
     43 import android.app.servertransaction.ClientTransaction;
     44 import android.app.servertransaction.ClientTransactionItem;
     45 import android.app.servertransaction.PendingTransactionActions;
     46 import android.app.servertransaction.PendingTransactionActions.StopInfo;
     47 import android.app.servertransaction.TransactionExecutor;
     48 import android.app.servertransaction.TransactionExecutorHelper;
     49 import android.content.AutofillOptions;
     50 import android.content.BroadcastReceiver;
     51 import android.content.ComponentCallbacks2;
     52 import android.content.ComponentName;
     53 import android.content.ContentCaptureOptions;
     54 import android.content.ContentProvider;
     55 import android.content.ContentResolver;
     56 import android.content.Context;
     57 import android.content.IContentProvider;
     58 import android.content.IIntentReceiver;
     59 import android.content.Intent;
     60 import android.content.pm.ActivityInfo;
     61 import android.content.pm.ApplicationInfo;
     62 import android.content.pm.IPackageManager;
     63 import android.content.pm.InstrumentationInfo;
     64 import android.content.pm.PackageInfo;
     65 import android.content.pm.PackageManager;
     66 import android.content.pm.PackageManager.NameNotFoundException;
     67 import android.content.pm.ParceledListSlice;
     68 import android.content.pm.ProviderInfo;
     69 import android.content.pm.ServiceInfo;
     70 import android.content.res.AssetManager;
     71 import android.content.res.CompatibilityInfo;
     72 import android.content.res.Configuration;
     73 import android.content.res.Resources;
     74 import android.content.res.Resources.Theme;
     75 import android.database.sqlite.SQLiteDatabase;
     76 import android.database.sqlite.SQLiteDebug;
     77 import android.database.sqlite.SQLiteDebug.DbStats;
     78 import android.graphics.Bitmap;
     79 import android.graphics.Canvas;
     80 import android.graphics.HardwareRenderer;
     81 import android.graphics.ImageDecoder;
     82 import android.hardware.display.DisplayManagerGlobal;
     83 import android.net.ConnectivityManager;
     84 import android.net.IConnectivityManager;
     85 import android.net.Proxy;
     86 import android.net.Uri;
     87 import android.os.AsyncTask;
     88 import android.os.Binder;
     89 import android.os.Build;
     90 import android.os.Bundle;
     91 import android.os.CancellationSignal;
     92 import android.os.Debug;
     93 import android.os.Environment;
     94 import android.os.FileUtils;
     95 import android.os.GraphicsEnvironment;
     96 import android.os.Handler;
     97 import android.os.HandlerExecutor;
     98 import android.os.IBinder;
     99 import android.os.ICancellationSignal;
    100 import android.os.LocaleList;
    101 import android.os.Looper;
    102 import android.os.Message;
    103 import android.os.MessageQueue;
    104 import android.os.Parcel;
    105 import android.os.ParcelFileDescriptor;
    106 import android.os.PersistableBundle;
    107 import android.os.Process;
    108 import android.os.RemoteCallback;
    109 import android.os.RemoteException;
    110 import android.os.ServiceManager;
    111 import android.os.StrictMode;
    112 import android.os.SystemClock;
    113 import android.os.SystemProperties;
    114 import android.os.Trace;
    115 import android.os.UserHandle;
    116 import android.provider.BlockedNumberContract;
    117 import android.provider.CalendarContract;
    118 import android.provider.CallLog;
    119 import android.provider.ContactsContract;
    120 import android.provider.Downloads;
    121 import android.provider.FontsContract;
    122 import android.provider.Settings;
    123 import android.renderscript.RenderScriptCacheDir;
    124 import android.security.NetworkSecurityPolicy;
    125 import android.security.net.config.NetworkSecurityConfigProvider;
    126 import android.system.ErrnoException;
    127 import android.system.OsConstants;
    128 import android.system.StructStat;
    129 import android.util.AndroidRuntimeException;
    130 import android.util.ArrayMap;
    131 import android.util.DisplayMetrics;
    132 import android.util.EventLog;
    133 import android.util.Log;
    134 import android.util.LogPrinter;
    135 import android.util.MergedConfiguration;
    136 import android.util.Pair;
    137 import android.util.PrintWriterPrinter;
    138 import android.util.Slog;
    139 import android.util.SparseArray;
    140 import android.util.SparseIntArray;
    141 import android.util.SuperNotCalledException;
    142 import android.util.UtilConfig;
    143 import android.util.proto.ProtoOutputStream;
    144 import android.view.Choreographer;
    145 import android.view.ContextThemeWrapper;
    146 import android.view.Display;
    147 import android.view.ThreadedRenderer;
    148 import android.view.View;
    149 import android.view.ViewDebug;
    150 import android.view.ViewManager;
    151 import android.view.ViewRootImpl;
    152 import android.view.Window;
    153 import android.view.WindowManager;
    154 import android.view.WindowManagerGlobal;
    155 import android.webkit.WebView;
    156 
    157 import com.android.internal.annotations.GuardedBy;
    158 import com.android.internal.annotations.VisibleForTesting;
    159 import com.android.internal.app.IVoiceInteractor;
    160 import com.android.internal.content.ReferrerIntent;
    161 import com.android.internal.os.BinderInternal;
    162 import com.android.internal.os.RuntimeInit;
    163 import com.android.internal.os.SomeArgs;
    164 import com.android.internal.util.ArrayUtils;
    165 import com.android.internal.util.FastPrintWriter;
    166 import com.android.internal.util.Preconditions;
    167 import com.android.internal.util.function.pooled.PooledLambda;
    168 import com.android.org.conscrypt.OpenSSLSocketImpl;
    169 import com.android.org.conscrypt.TrustedCertificateStore;
    170 import com.android.server.am.MemInfoDumpProto;
    171 
    172 import dalvik.system.CloseGuard;
    173 import dalvik.system.VMDebug;
    174 import dalvik.system.VMRuntime;
    175 
    176 import libcore.io.ForwardingOs;
    177 import libcore.io.IoUtils;
    178 import libcore.io.Os;
    179 import libcore.net.event.NetworkEventDispatcher;
    180 
    181 import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
    182 
    183 import java.io.File;
    184 import java.io.FileDescriptor;
    185 import java.io.FileNotFoundException;
    186 import java.io.FileOutputStream;
    187 import java.io.IOException;
    188 import java.io.PrintWriter;
    189 import java.lang.ref.WeakReference;
    190 import java.lang.reflect.Method;
    191 import java.net.InetAddress;
    192 import java.nio.file.Files;
    193 import java.text.DateFormat;
    194 import java.util.ArrayList;
    195 import java.util.Arrays;
    196 import java.util.Collections;
    197 import java.util.List;
    198 import java.util.Locale;
    199 import java.util.Map;
    200 import java.util.Objects;
    201 import java.util.TimeZone;
    202 import java.util.concurrent.Executor;
    203 import java.util.concurrent.atomic.AtomicInteger;
    204 
    205 final class RemoteServiceException extends AndroidRuntimeException {
    206     public RemoteServiceException(String msg) {
    207         super(msg);
    208     }
    209 }
    210 
    211 /**
    212  * This manages the execution of the main thread in an
    213  * application process, scheduling and executing activities,
    214  * broadcasts, and other operations on it as the activity
    215  * manager requests.
    216  *
    217  * {@hide}
    218  */
    219 public final class ActivityThread extends ClientTransactionHandler {
    220     /** @hide */
    221     public static final String TAG = "ActivityThread";
    222     private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
    223     static final boolean localLOGV = false;
    224     static final boolean DEBUG_MESSAGES = false;
    225     /** @hide */
    226     public static final boolean DEBUG_BROADCAST = false;
    227     private static final boolean DEBUG_RESULTS = false;
    228     private static final boolean DEBUG_BACKUP = false;
    229     public static final boolean DEBUG_CONFIGURATION = false;
    230     private static final boolean DEBUG_SERVICE = false;
    231     public static final boolean DEBUG_MEMORY_TRIM = false;
    232     private static final boolean DEBUG_PROVIDER = false;
    233     public static final boolean DEBUG_ORDER = false;
    234     private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
    235     /**
    236      * If the activity doesn't become idle in time, the timeout will ensure to apply the pending top
    237      * process state.
    238      */
    239     private static final long PENDING_TOP_PROCESS_STATE_TIMEOUT = 1000;
    240     /**
    241      * The delay to release the provider when it has no more references. It reduces the number of
    242      * transactions for acquiring and releasing provider if the client accesses the provider
    243      * frequently in a short time.
    244      */
    245     private static final long CONTENT_PROVIDER_RETAIN_TIME = 1000;
    246     private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
    247 
    248     /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
    249     public static final int SERVICE_DONE_EXECUTING_ANON = 0;
    250     /** Type for IActivityManager.serviceDoneExecuting: done with an onStart call */
    251     public static final int SERVICE_DONE_EXECUTING_START = 1;
    252     /** Type for IActivityManager.serviceDoneExecuting: done stopping (destroying) service */
    253     public static final int SERVICE_DONE_EXECUTING_STOP = 2;
    254 
    255     // Whether to invoke an activity callback after delivering new configuration.
    256     private static final boolean REPORT_TO_ACTIVITY = true;
    257 
    258     /** Use foreground GC policy (less pause time) and higher JIT weight. */
    259     private static final int VM_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
    260     /** Use background GC policy and default JIT threshold. */
    261     private static final int VM_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
    262 
    263     /**
    264      * Denotes an invalid sequence number corresponding to a process state change.
    265      */
    266     public static final long INVALID_PROC_STATE_SEQ = -1;
    267 
    268     /**
    269      * Identifier for the sequence no. associated with this process start. It will be provided
    270      * as one of the arguments when the process starts.
    271      */
    272     public static final String PROC_START_SEQ_IDENT = "seq=";
    273 
    274     private final Object mNetworkPolicyLock = new Object();
    275 
    276     /**
    277      * Denotes the sequence number of the process state change for which the main thread needs
    278      * to block until the network rules are updated for it.
    279      *
    280      * Value of {@link #INVALID_PROC_STATE_SEQ} indicates there is no need for blocking.
    281      */
    282     @GuardedBy("mNetworkPolicyLock")
    283     private long mNetworkBlockSeq = INVALID_PROC_STATE_SEQ;
    284 
    285     @UnsupportedAppUsage
    286     private ContextImpl mSystemContext;
    287     private ContextImpl mSystemUiContext;
    288 
    289     @UnsupportedAppUsage
    290     static volatile IPackageManager sPackageManager;
    291 
    292     @UnsupportedAppUsage
    293     final ApplicationThread mAppThread = new ApplicationThread();
    294     @UnsupportedAppUsage
    295     final Looper mLooper = Looper.myLooper();
    296     @UnsupportedAppUsage
    297     final H mH = new H();
    298     final Executor mExecutor = new HandlerExecutor(mH);
    299     /**
    300      * Maps from activity token to local record of running activities in this process.
    301      *
    302      * This variable is readable if the code is running in activity thread or holding {@link
    303      * #mResourcesManager}. It's only writable if the code is running in activity thread and holding
    304      * {@link #mResourcesManager}.
    305      */
    306     @UnsupportedAppUsage
    307     final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
    308     /** The activities to be truly destroyed (not include relaunch). */
    309     final Map<IBinder, ClientTransactionItem> mActivitiesToBeDestroyed =
    310             Collections.synchronizedMap(new ArrayMap<IBinder, ClientTransactionItem>());
    311     // List of new activities (via ActivityRecord.nextIdle) that should
    312     // be reported when next we idle.
    313     ActivityClientRecord mNewActivities = null;
    314     // Number of activities that are currently visible on-screen.
    315     @UnsupportedAppUsage
    316     int mNumVisibleActivities = 0;
    317     private final AtomicInteger mNumLaunchingActivities = new AtomicInteger();
    318     @GuardedBy("mAppThread")
    319     private int mLastProcessState = PROCESS_STATE_UNKNOWN;
    320     @GuardedBy("mAppThread")
    321     private int mPendingProcessState = PROCESS_STATE_UNKNOWN;
    322     ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>();
    323     private int mLastSessionId;
    324     @UnsupportedAppUsage
    325     final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
    326     @UnsupportedAppUsage
    327     AppBindData mBoundApplication;
    328     Profiler mProfiler;
    329     @UnsupportedAppUsage
    330     int mCurDefaultDisplayDpi;
    331     @UnsupportedAppUsage
    332     boolean mDensityCompatMode;
    333     @UnsupportedAppUsage
    334     Configuration mConfiguration;
    335     Configuration mCompatConfiguration;
    336     @UnsupportedAppUsage
    337     Application mInitialApplication;
    338     @UnsupportedAppUsage
    339     final ArrayList<Application> mAllApplications
    340             = new ArrayList<Application>();
    341     /**
    342      * Bookkeeping of instantiated backup agents indexed first by user id, then by package name.
    343      * Indexing by user id supports parallel backups across users on system packages as they run in
    344      * the same process with the same package name. Indexing by package name supports multiple
    345      * distinct applications running in the same process.
    346      */
    347     private final SparseArray<ArrayMap<String, BackupAgent>> mBackupAgentsByUser =
    348             new SparseArray<>();
    349     /** Reference to singleton {@link ActivityThread} */
    350     @UnsupportedAppUsage
    351     private static volatile ActivityThread sCurrentActivityThread;
    352     @UnsupportedAppUsage
    353     Instrumentation mInstrumentation;
    354     String mInstrumentationPackageName = null;
    355     @UnsupportedAppUsage
    356     String mInstrumentationAppDir = null;
    357     String[] mInstrumentationSplitAppDirs = null;
    358     String mInstrumentationLibDir = null;
    359     @UnsupportedAppUsage
    360     String mInstrumentedAppDir = null;
    361     String[] mInstrumentedSplitAppDirs = null;
    362     String mInstrumentedLibDir = null;
    363     boolean mSystemThread = false;
    364     boolean mSomeActivitiesChanged = false;
    365     boolean mUpdatingSystemConfig = false;
    366     /* package */ boolean mHiddenApiWarningShown = false;
    367 
    368     // These can be accessed by multiple threads; mResourcesManager is the lock.
    369     // XXX For now we keep around information about all packages we have
    370     // seen, not removing entries from this map.
    371     // NOTE: The activity and window managers need to call in to
    372     // ActivityThread to do things like update resource configurations,
    373     // which means this lock gets held while the activity and window managers
    374     // holds their own lock.  Thus you MUST NEVER call back into the activity manager
    375     // or window manager or anything that depends on them while holding this lock.
    376     // These LoadedApk are only valid for the userId that we're running as.
    377     @GuardedBy("mResourcesManager")
    378     @UnsupportedAppUsage
    379     final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>();
    380     @GuardedBy("mResourcesManager")
    381     @UnsupportedAppUsage
    382     final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>();
    383     @GuardedBy("mResourcesManager")
    384     final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<>();
    385     @GuardedBy("mResourcesManager")
    386     @UnsupportedAppUsage
    387     Configuration mPendingConfiguration = null;
    388     // An executor that performs multi-step transactions.
    389     private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    390 
    391     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    392     private final ResourcesManager mResourcesManager;
    393 
    394     // Registry of remote cancellation transports pending a reply with reply handles.
    395     @GuardedBy("this")
    396     private @Nullable Map<SafeCancellationTransport, CancellationSignal> mRemoteCancellations;
    397 
    398     private static final class ProviderKey {
    399         final String authority;
    400         final int userId;
    401 
    402         public ProviderKey(String authority, int userId) {
    403             this.authority = authority;
    404             this.userId = userId;
    405         }
    406 
    407         @Override
    408         public boolean equals(Object o) {
    409             if (o instanceof ProviderKey) {
    410                 final ProviderKey other = (ProviderKey) o;
    411                 return Objects.equals(authority, other.authority) && userId == other.userId;
    412             }
    413             return false;
    414         }
    415 
    416         @Override
    417         public int hashCode() {
    418             return ((authority != null) ? authority.hashCode() : 0) ^ userId;
    419         }
    420     }
    421 
    422     // The lock of mProviderMap protects the following variables.
    423     @UnsupportedAppUsage
    424     final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
    425         = new ArrayMap<ProviderKey, ProviderClientRecord>();
    426     @UnsupportedAppUsage
    427     final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
    428         = new ArrayMap<IBinder, ProviderRefCount>();
    429     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    430     final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
    431         = new ArrayMap<IBinder, ProviderClientRecord>();
    432     @UnsupportedAppUsage
    433     final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
    434             = new ArrayMap<ComponentName, ProviderClientRecord>();
    435 
    436     // Mitigation for b/74523247: Used to serialize calls to AM.getContentProvider().
    437     // Note we never removes items from this map but that's okay because there are only so many
    438     // users and so many authorities.
    439     // TODO Remove it once we move CPR.wait() from AMS to the client side.
    440     @GuardedBy("mGetProviderLocks")
    441     final ArrayMap<ProviderKey, Object> mGetProviderLocks = new ArrayMap<>();
    442 
    443     final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
    444         = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
    445 
    446     final GcIdler mGcIdler = new GcIdler();
    447     final PurgeIdler mPurgeIdler = new PurgeIdler();
    448 
    449     boolean mPurgeIdlerScheduled = false;
    450     boolean mGcIdlerScheduled = false;
    451 
    452     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    453     static volatile Handler sMainThreadHandler;  // set once in main()
    454 
    455     Bundle mCoreSettings = null;
    456 
    457     /** Activity client record, used for bookkeeping for the real {@link Activity} instance. */
    458     public static final class ActivityClientRecord {
    459         @UnsupportedAppUsage
    460         public IBinder token;
    461         public IBinder assistToken;
    462         int ident;
    463         @UnsupportedAppUsage
    464         Intent intent;
    465         String referrer;
    466         IVoiceInteractor voiceInteractor;
    467         Bundle state;
    468         PersistableBundle persistentState;
    469         @UnsupportedAppUsage
    470         Activity activity;
    471         Window window;
    472         Activity parent;
    473         String embeddedID;
    474         Activity.NonConfigurationInstances lastNonConfigurationInstances;
    475         // TODO(lifecycler): Use mLifecycleState instead.
    476         @UnsupportedAppUsage
    477         boolean paused;
    478         @UnsupportedAppUsage
    479         boolean stopped;
    480         boolean hideForNow;
    481         Configuration newConfig;
    482         Configuration createdConfig;
    483         Configuration overrideConfig;
    484         // Used to save the last reported configuration from server side so that activity
    485         // configuration transactions can always use the latest configuration.
    486         @GuardedBy("this")
    487         private Configuration mPendingOverrideConfig;
    488         // Used for consolidating configs before sending on to Activity.
    489         private Configuration tmpConfig = new Configuration();
    490         // Callback used for updating activity override config.
    491         ViewRootImpl.ActivityConfigCallback configCallback;
    492         ActivityClientRecord nextIdle;
    493 
    494         // Indicates whether this activity is currently the topmost resumed one in the system.
    495         // This holds the last reported value from server.
    496         boolean isTopResumedActivity;
    497         // This holds the value last sent to the activity. This is needed, because an update from
    498         // server may come at random time, but we always need to report changes between ON_RESUME
    499         // and ON_PAUSE to the app.
    500         boolean lastReportedTopResumedState;
    501 
    502         ProfilerInfo profilerInfo;
    503 
    504         @UnsupportedAppUsage
    505         ActivityInfo activityInfo;
    506         @UnsupportedAppUsage
    507         CompatibilityInfo compatInfo;
    508         @UnsupportedAppUsage
    509         public LoadedApk packageInfo;
    510 
    511         List<ResultInfo> pendingResults;
    512         List<ReferrerIntent> pendingIntents;
    513 
    514         boolean startsNotResumed;
    515         public final boolean isForward;
    516         int pendingConfigChanges;
    517 
    518         Window mPendingRemoveWindow;
    519         WindowManager mPendingRemoveWindowManager;
    520         @UnsupportedAppUsage
    521         boolean mPreserveWindow;
    522 
    523         @LifecycleState
    524         private int mLifecycleState = PRE_ON_CREATE;
    525 
    526         @VisibleForTesting
    527         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    528         public ActivityClientRecord() {
    529             this.isForward = false;
    530             init();
    531         }
    532 
    533         public ActivityClientRecord(IBinder token, Intent intent, int ident,
    534                 ActivityInfo info, Configuration overrideConfig, CompatibilityInfo compatInfo,
    535                 String referrer, IVoiceInteractor voiceInteractor, Bundle state,
    536                 PersistableBundle persistentState, List<ResultInfo> pendingResults,
    537                 List<ReferrerIntent> pendingNewIntents, boolean isForward,
    538                 ProfilerInfo profilerInfo, ClientTransactionHandler client,
    539                 IBinder assistToken) {
    540             this.token = token;
    541             this.assistToken = assistToken;
    542             this.ident = ident;
    543             this.intent = intent;
    544             this.referrer = referrer;
    545             this.voiceInteractor = voiceInteractor;
    546             this.activityInfo = info;
    547             this.compatInfo = compatInfo;
    548             this.state = state;
    549             this.persistentState = persistentState;
    550             this.pendingResults = pendingResults;
    551             this.pendingIntents = pendingNewIntents;
    552             this.isForward = isForward;
    553             this.profilerInfo = profilerInfo;
    554             this.overrideConfig = overrideConfig;
    555             this.packageInfo = client.getPackageInfoNoCheck(activityInfo.applicationInfo,
    556                     compatInfo);
    557             init();
    558         }
    559 
    560         /** Common initializer for all constructors. */
    561         private void init() {
    562             parent = null;
    563             embeddedID = null;
    564             paused = false;
    565             stopped = false;
    566             hideForNow = false;
    567             nextIdle = null;
    568             configCallback = (Configuration overrideConfig, int newDisplayId) -> {
    569                 if (activity == null) {
    570                     throw new IllegalStateException(
    571                             "Received config update for non-existing activity");
    572                 }
    573                 activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig,
    574                         newDisplayId);
    575             };
    576         }
    577 
    578         /** Get the current lifecycle state. */
    579         public int getLifecycleState() {
    580             return mLifecycleState;
    581         }
    582 
    583         /** Update the current lifecycle state for internal bookkeeping. */
    584         public void setState(@LifecycleState int newLifecycleState) {
    585             mLifecycleState = newLifecycleState;
    586             switch (mLifecycleState) {
    587                 case ON_CREATE:
    588                     paused = true;
    589                     stopped = true;
    590                     break;
    591                 case ON_START:
    592                     paused = true;
    593                     stopped = false;
    594                     break;
    595                 case ON_RESUME:
    596                     paused = false;
    597                     stopped = false;
    598                     break;
    599                 case ON_PAUSE:
    600                     paused = true;
    601                     stopped = false;
    602                     break;
    603                 case ON_STOP:
    604                     paused = true;
    605                     stopped = true;
    606                     break;
    607             }
    608         }
    609 
    610         private boolean isPreHoneycomb() {
    611             return activity != null && activity.getApplicationInfo().targetSdkVersion
    612                     < android.os.Build.VERSION_CODES.HONEYCOMB;
    613         }
    614 
    615         private boolean isPreP() {
    616             return activity != null && activity.getApplicationInfo().targetSdkVersion
    617                     < android.os.Build.VERSION_CODES.P;
    618         }
    619 
    620         public boolean isPersistable() {
    621             return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
    622         }
    623 
    624         public boolean isVisibleFromServer() {
    625             return activity != null && activity.mVisibleFromServer;
    626         }
    627 
    628         public String toString() {
    629             ComponentName componentName = intent != null ? intent.getComponent() : null;
    630             return "ActivityRecord{"
    631                 + Integer.toHexString(System.identityHashCode(this))
    632                 + " token=" + token + " " + (componentName == null
    633                         ? "no component name" : componentName.toShortString())
    634                 + "}";
    635         }
    636 
    637         public String getStateString() {
    638             StringBuilder sb = new StringBuilder();
    639             sb.append("ActivityClientRecord{");
    640             sb.append("paused=").append(paused);
    641             sb.append(", stopped=").append(stopped);
    642             sb.append(", hideForNow=").append(hideForNow);
    643             sb.append(", startsNotResumed=").append(startsNotResumed);
    644             sb.append(", isForward=").append(isForward);
    645             sb.append(", pendingConfigChanges=").append(pendingConfigChanges);
    646             sb.append(", preserveWindow=").append(mPreserveWindow);
    647             if (activity != null) {
    648                 sb.append(", Activity{");
    649                 sb.append("resumed=").append(activity.mResumed);
    650                 sb.append(", stopped=").append(activity.mStopped);
    651                 sb.append(", finished=").append(activity.isFinishing());
    652                 sb.append(", destroyed=").append(activity.isDestroyed());
    653                 sb.append(", startedActivity=").append(activity.mStartedActivity);
    654                 sb.append(", changingConfigurations=").append(activity.mChangingConfigurations);
    655                 sb.append("}");
    656             }
    657             sb.append("}");
    658             return sb.toString();
    659         }
    660     }
    661 
    662     final class ProviderClientRecord {
    663         final String[] mNames;
    664         @UnsupportedAppUsage
    665         final IContentProvider mProvider;
    666         @UnsupportedAppUsage
    667         final ContentProvider mLocalProvider;
    668         @UnsupportedAppUsage
    669         final ContentProviderHolder mHolder;
    670 
    671         ProviderClientRecord(String[] names, IContentProvider provider,
    672                 ContentProvider localProvider, ContentProviderHolder holder) {
    673             mNames = names;
    674             mProvider = provider;
    675             mLocalProvider = localProvider;
    676             mHolder = holder;
    677         }
    678     }
    679 
    680     static final class ReceiverData extends BroadcastReceiver.PendingResult {
    681         public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
    682                 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
    683             super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
    684                     token, sendingUser, intent.getFlags());
    685             this.intent = intent;
    686         }
    687 
    688         @UnsupportedAppUsage
    689         Intent intent;
    690         @UnsupportedAppUsage
    691         ActivityInfo info;
    692         @UnsupportedAppUsage
    693         CompatibilityInfo compatInfo;
    694         public String toString() {
    695             return "ReceiverData{intent=" + intent + " packageName=" +
    696                     info.packageName + " resultCode=" + getResultCode()
    697                     + " resultData=" + getResultData() + " resultExtras="
    698                     + getResultExtras(false) + "}";
    699         }
    700     }
    701 
    702     static final class CreateBackupAgentData {
    703         ApplicationInfo appInfo;
    704         CompatibilityInfo compatInfo;
    705         int backupMode;
    706         int userId;
    707         public String toString() {
    708             return "CreateBackupAgentData{appInfo=" + appInfo
    709                     + " backupAgent=" + appInfo.backupAgentName
    710                     + " mode=" + backupMode + " userId=" + userId + "}";
    711         }
    712     }
    713 
    714     static final class CreateServiceData {
    715         @UnsupportedAppUsage
    716         IBinder token;
    717         @UnsupportedAppUsage
    718         ServiceInfo info;
    719         @UnsupportedAppUsage
    720         CompatibilityInfo compatInfo;
    721         @UnsupportedAppUsage
    722         Intent intent;
    723         public String toString() {
    724             return "CreateServiceData{token=" + token + " className="
    725             + info.name + " packageName=" + info.packageName
    726             + " intent=" + intent + "}";
    727         }
    728     }
    729 
    730     static final class BindServiceData {
    731         @UnsupportedAppUsage
    732         IBinder token;
    733         @UnsupportedAppUsage
    734         Intent intent;
    735         boolean rebind;
    736         public String toString() {
    737             return "BindServiceData{token=" + token + " intent=" + intent + "}";
    738         }
    739     }
    740 
    741     static final class ServiceArgsData {
    742         @UnsupportedAppUsage
    743         IBinder token;
    744         boolean taskRemoved;
    745         int startId;
    746         int flags;
    747         @UnsupportedAppUsage
    748         Intent args;
    749         public String toString() {
    750             return "ServiceArgsData{token=" + token + " startId=" + startId
    751             + " args=" + args + "}";
    752         }
    753     }
    754 
    755     static final class AppBindData {
    756         @UnsupportedAppUsage
    757         LoadedApk info;
    758         @UnsupportedAppUsage
    759         String processName;
    760         @UnsupportedAppUsage
    761         ApplicationInfo appInfo;
    762         @UnsupportedAppUsage
    763         List<ProviderInfo> providers;
    764         ComponentName instrumentationName;
    765         @UnsupportedAppUsage
    766         Bundle instrumentationArgs;
    767         IInstrumentationWatcher instrumentationWatcher;
    768         IUiAutomationConnection instrumentationUiAutomationConnection;
    769         int debugMode;
    770         boolean enableBinderTracking;
    771         boolean trackAllocation;
    772         @UnsupportedAppUsage
    773         boolean restrictedBackupMode;
    774         @UnsupportedAppUsage
    775         boolean persistent;
    776         Configuration config;
    777         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    778         CompatibilityInfo compatInfo;
    779         String buildSerial;
    780 
    781         /** Initial values for {@link Profiler}. */
    782         ProfilerInfo initProfilerInfo;
    783 
    784         AutofillOptions autofillOptions;
    785 
    786         /**
    787          * Content capture options for the application - when null, it means ContentCapture is not
    788          * enabled for the package.
    789          */
    790         @Nullable
    791         ContentCaptureOptions contentCaptureOptions;
    792 
    793         @Override
    794         public String toString() {
    795             return "AppBindData{appInfo=" + appInfo + "}";
    796         }
    797     }
    798 
    799     static final class Profiler {
    800         String profileFile;
    801         ParcelFileDescriptor profileFd;
    802         int samplingInterval;
    803         boolean autoStopProfiler;
    804         boolean streamingOutput;
    805         boolean profiling;
    806         boolean handlingProfiling;
    807         public void setProfiler(ProfilerInfo profilerInfo) {
    808             ParcelFileDescriptor fd = profilerInfo.profileFd;
    809             if (profiling) {
    810                 if (fd != null) {
    811                     try {
    812                         fd.close();
    813                     } catch (IOException e) {
    814                         // Ignore
    815                     }
    816                 }
    817                 return;
    818             }
    819             if (profileFd != null) {
    820                 try {
    821                     profileFd.close();
    822                 } catch (IOException e) {
    823                     // Ignore
    824                 }
    825             }
    826             profileFile = profilerInfo.profileFile;
    827             profileFd = fd;
    828             samplingInterval = profilerInfo.samplingInterval;
    829             autoStopProfiler = profilerInfo.autoStopProfiler;
    830             streamingOutput = profilerInfo.streamingOutput;
    831         }
    832         public void startProfiling() {
    833             if (profileFd == null || profiling) {
    834                 return;
    835             }
    836             try {
    837                 int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8);
    838                 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
    839                         bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval,
    840                         streamingOutput);
    841                 profiling = true;
    842             } catch (RuntimeException e) {
    843                 Slog.w(TAG, "Profiling failed on path " + profileFile, e);
    844                 try {
    845                     profileFd.close();
    846                     profileFd = null;
    847                 } catch (IOException e2) {
    848                     Slog.w(TAG, "Failure closing profile fd", e2);
    849                 }
    850             }
    851         }
    852         public void stopProfiling() {
    853             if (profiling) {
    854                 profiling = false;
    855                 Debug.stopMethodTracing();
    856                 if (profileFd != null) {
    857                     try {
    858                         profileFd.close();
    859                     } catch (IOException e) {
    860                     }
    861                 }
    862                 profileFd = null;
    863                 profileFile = null;
    864             }
    865         }
    866     }
    867 
    868     static final class DumpComponentInfo {
    869         ParcelFileDescriptor fd;
    870         IBinder token;
    871         String prefix;
    872         String[] args;
    873     }
    874 
    875     static final class ContextCleanupInfo {
    876         ContextImpl context;
    877         String what;
    878         String who;
    879     }
    880 
    881     static final class DumpHeapData {
    882         // Whether to dump the native or managed heap.
    883         public boolean managed;
    884         public boolean mallocInfo;
    885         public boolean runGc;
    886         String path;
    887         ParcelFileDescriptor fd;
    888         RemoteCallback finishCallback;
    889     }
    890 
    891     static final class UpdateCompatibilityData {
    892         String pkg;
    893         CompatibilityInfo info;
    894     }
    895 
    896     static final class RequestAssistContextExtras {
    897         IBinder activityToken;
    898         IBinder requestToken;
    899         int requestType;
    900         int sessionId;
    901         int flags;
    902     }
    903 
    904     private class ApplicationThread extends IApplicationThread.Stub {
    905         private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
    906 
    907         public final void scheduleSleeping(IBinder token, boolean sleeping) {
    908             sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
    909         }
    910 
    911         public final void scheduleReceiver(Intent intent, ActivityInfo info,
    912                 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
    913                 boolean sync, int sendingUser, int processState) {
    914             updateProcessState(processState, false);
    915             ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
    916                     sync, false, mAppThread.asBinder(), sendingUser);
    917             r.info = info;
    918             r.compatInfo = compatInfo;
    919             sendMessage(H.RECEIVER, r);
    920         }
    921 
    922         public final void scheduleCreateBackupAgent(ApplicationInfo app,
    923                 CompatibilityInfo compatInfo, int backupMode, int userId) {
    924             CreateBackupAgentData d = new CreateBackupAgentData();
    925             d.appInfo = app;
    926             d.compatInfo = compatInfo;
    927             d.backupMode = backupMode;
    928             d.userId = userId;
    929 
    930             sendMessage(H.CREATE_BACKUP_AGENT, d);
    931         }
    932 
    933         public final void scheduleDestroyBackupAgent(ApplicationInfo app,
    934                 CompatibilityInfo compatInfo, int userId) {
    935             CreateBackupAgentData d = new CreateBackupAgentData();
    936             d.appInfo = app;
    937             d.compatInfo = compatInfo;
    938             d.userId = userId;
    939 
    940             sendMessage(H.DESTROY_BACKUP_AGENT, d);
    941         }
    942 
    943         public final void scheduleCreateService(IBinder token,
    944                 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
    945             updateProcessState(processState, false);
    946             CreateServiceData s = new CreateServiceData();
    947             s.token = token;
    948             s.info = info;
    949             s.compatInfo = compatInfo;
    950 
    951             sendMessage(H.CREATE_SERVICE, s);
    952         }
    953 
    954         public final void scheduleBindService(IBinder token, Intent intent,
    955                 boolean rebind, int processState) {
    956             updateProcessState(processState, false);
    957             BindServiceData s = new BindServiceData();
    958             s.token = token;
    959             s.intent = intent;
    960             s.rebind = rebind;
    961 
    962             if (DEBUG_SERVICE)
    963                 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
    964                         + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
    965             sendMessage(H.BIND_SERVICE, s);
    966         }
    967 
    968         public final void scheduleUnbindService(IBinder token, Intent intent) {
    969             BindServiceData s = new BindServiceData();
    970             s.token = token;
    971             s.intent = intent;
    972 
    973             sendMessage(H.UNBIND_SERVICE, s);
    974         }
    975 
    976         public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
    977             List<ServiceStartArgs> list = args.getList();
    978 
    979             for (int i = 0; i < list.size(); i++) {
    980                 ServiceStartArgs ssa = list.get(i);
    981                 ServiceArgsData s = new ServiceArgsData();
    982                 s.token = token;
    983                 s.taskRemoved = ssa.taskRemoved;
    984                 s.startId = ssa.startId;
    985                 s.flags = ssa.flags;
    986                 s.args = ssa.args;
    987 
    988                 sendMessage(H.SERVICE_ARGS, s);
    989             }
    990         }
    991 
    992         public final void scheduleStopService(IBinder token) {
    993             sendMessage(H.STOP_SERVICE, token);
    994         }
    995 
    996         public final void bindApplication(String processName, ApplicationInfo appInfo,
    997                 List<ProviderInfo> providers, ComponentName instrumentationName,
    998                 ProfilerInfo profilerInfo, Bundle instrumentationArgs,
    999                 IInstrumentationWatcher instrumentationWatcher,
   1000                 IUiAutomationConnection instrumentationUiConnection, int debugMode,
   1001                 boolean enableBinderTracking, boolean trackAllocation,
   1002                 boolean isRestrictedBackupMode, boolean persistent, Configuration config,
   1003                 CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
   1004                 String buildSerial, AutofillOptions autofillOptions,
   1005                 ContentCaptureOptions contentCaptureOptions) {
   1006             if (services != null) {
   1007                 if (false) {
   1008                     // Test code to make sure the app could see the passed-in services.
   1009                     for (Object oname : services.keySet()) {
   1010                         if (services.get(oname) == null) {
   1011                             continue; // AM just passed in a null service.
   1012                         }
   1013                         String name = (String) oname;
   1014 
   1015                         // See b/79378449 about the following exemption.
   1016                         switch (name) {
   1017                             case "package":
   1018                             case Context.WINDOW_SERVICE:
   1019                                 continue;
   1020                         }
   1021 
   1022                         if (ServiceManager.getService(name) == null) {
   1023                             Log.wtf(TAG, "Service " + name + " should be accessible by this app");
   1024                         }
   1025                     }
   1026                 }
   1027 
   1028                 // Setup the service cache in the ServiceManager
   1029                 ServiceManager.initServiceCache(services);
   1030             }
   1031 
   1032             setCoreSettings(coreSettings);
   1033 
   1034             AppBindData data = new AppBindData();
   1035             data.processName = processName;
   1036             data.appInfo = appInfo;
   1037             data.providers = providers;
   1038             data.instrumentationName = instrumentationName;
   1039             data.instrumentationArgs = instrumentationArgs;
   1040             data.instrumentationWatcher = instrumentationWatcher;
   1041             data.instrumentationUiAutomationConnection = instrumentationUiConnection;
   1042             data.debugMode = debugMode;
   1043             data.enableBinderTracking = enableBinderTracking;
   1044             data.trackAllocation = trackAllocation;
   1045             data.restrictedBackupMode = isRestrictedBackupMode;
   1046             data.persistent = persistent;
   1047             data.config = config;
   1048             data.compatInfo = compatInfo;
   1049             data.initProfilerInfo = profilerInfo;
   1050             data.buildSerial = buildSerial;
   1051             data.autofillOptions = autofillOptions;
   1052             data.contentCaptureOptions = contentCaptureOptions;
   1053             sendMessage(H.BIND_APPLICATION, data);
   1054         }
   1055 
   1056         public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) {
   1057             SomeArgs args = SomeArgs.obtain();
   1058             args.arg1 = entryPoint;
   1059             args.arg2 = entryPointArgs;
   1060             sendMessage(H.RUN_ISOLATED_ENTRY_POINT, args);
   1061         }
   1062 
   1063         public final void scheduleExit() {
   1064             sendMessage(H.EXIT_APPLICATION, null);
   1065         }
   1066 
   1067         public final void scheduleSuicide() {
   1068             sendMessage(H.SUICIDE, null);
   1069         }
   1070 
   1071         public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
   1072             mH.removeMessages(H.APPLICATION_INFO_CHANGED, ai);
   1073             sendMessage(H.APPLICATION_INFO_CHANGED, ai);
   1074         }
   1075 
   1076         public void updateTimeZone() {
   1077             TimeZone.setDefault(null);
   1078         }
   1079 
   1080         public void clearDnsCache() {
   1081             // a non-standard API to get this to libcore
   1082             InetAddress.clearDnsCache();
   1083             // Allow libcore to perform the necessary actions as it sees fit upon a network
   1084             // configuration change.
   1085             NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
   1086         }
   1087 
   1088         public void updateHttpProxy() {
   1089             ActivityThread.updateHttpProxy(
   1090                     getApplication() != null ? getApplication() : getSystemContext());
   1091         }
   1092 
   1093         public void processInBackground() {
   1094             mH.removeMessages(H.GC_WHEN_IDLE);
   1095             mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
   1096         }
   1097 
   1098         public void dumpService(ParcelFileDescriptor pfd, IBinder servicetoken, String[] args) {
   1099             DumpComponentInfo data = new DumpComponentInfo();
   1100             try {
   1101                 data.fd = pfd.dup();
   1102                 data.token = servicetoken;
   1103                 data.args = args;
   1104                 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
   1105             } catch (IOException e) {
   1106                 Slog.w(TAG, "dumpService failed", e);
   1107             } finally {
   1108                 IoUtils.closeQuietly(pfd);
   1109             }
   1110         }
   1111 
   1112         // This function exists to make sure all receiver dispatching is
   1113         // correctly ordered, since these are one-way calls and the binder driver
   1114         // applies transaction ordering per object for such calls.
   1115         public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
   1116                 int resultCode, String dataStr, Bundle extras, boolean ordered,
   1117                 boolean sticky, int sendingUser, int processState) throws RemoteException {
   1118             updateProcessState(processState, false);
   1119             receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
   1120                     sticky, sendingUser);
   1121         }
   1122 
   1123         @Override
   1124         public void scheduleLowMemory() {
   1125             sendMessage(H.LOW_MEMORY, null);
   1126         }
   1127 
   1128         @Override
   1129         public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
   1130             sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
   1131         }
   1132 
   1133         @Override
   1134         public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String path,
   1135                 ParcelFileDescriptor fd, RemoteCallback finishCallback) {
   1136             DumpHeapData dhd = new DumpHeapData();
   1137             dhd.managed = managed;
   1138             dhd.mallocInfo = mallocInfo;
   1139             dhd.runGc = runGc;
   1140             dhd.path = path;
   1141             try {
   1142                 // Since we're going to dump the heap asynchronously, dup the file descriptor before
   1143                 // it's closed on returning from the IPC call.
   1144                 dhd.fd = fd.dup();
   1145             } catch (IOException e) {
   1146                 Slog.e(TAG, "Failed to duplicate heap dump file descriptor", e);
   1147                 return;
   1148             }
   1149             dhd.finishCallback = finishCallback;
   1150             sendMessage(H.DUMP_HEAP, dhd, 0, 0, true /*async*/);
   1151         }
   1152 
   1153         public void attachAgent(String agent) {
   1154             sendMessage(H.ATTACH_AGENT, agent);
   1155         }
   1156 
   1157         public void setSchedulingGroup(int group) {
   1158             // Note: do this immediately, since going into the foreground
   1159             // should happen regardless of what pending work we have to do
   1160             // and the activity manager will wait for us to report back that
   1161             // we are done before sending us to the background.
   1162             try {
   1163                 Process.setProcessGroup(Process.myPid(), group);
   1164             } catch (Exception e) {
   1165                 Slog.w(TAG, "Failed setting process group to " + group, e);
   1166             }
   1167         }
   1168 
   1169         public void dispatchPackageBroadcast(int cmd, String[] packages) {
   1170             sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
   1171         }
   1172 
   1173         public void scheduleCrash(String msg) {
   1174             sendMessage(H.SCHEDULE_CRASH, msg);
   1175         }
   1176 
   1177         public void dumpActivity(ParcelFileDescriptor pfd, IBinder activitytoken,
   1178                 String prefix, String[] args) {
   1179             DumpComponentInfo data = new DumpComponentInfo();
   1180             try {
   1181                 data.fd = pfd.dup();
   1182                 data.token = activitytoken;
   1183                 data.prefix = prefix;
   1184                 data.args = args;
   1185                 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
   1186             } catch (IOException e) {
   1187                 Slog.w(TAG, "dumpActivity failed", e);
   1188             } finally {
   1189                 IoUtils.closeQuietly(pfd);
   1190             }
   1191         }
   1192 
   1193         public void dumpProvider(ParcelFileDescriptor pfd, IBinder providertoken,
   1194                 String[] args) {
   1195             DumpComponentInfo data = new DumpComponentInfo();
   1196             try {
   1197                 data.fd = pfd.dup();
   1198                 data.token = providertoken;
   1199                 data.args = args;
   1200                 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
   1201             } catch (IOException e) {
   1202                 Slog.w(TAG, "dumpProvider failed", e);
   1203             } finally {
   1204                 IoUtils.closeQuietly(pfd);
   1205             }
   1206         }
   1207 
   1208         @Override
   1209         public void dumpMemInfo(ParcelFileDescriptor pfd, Debug.MemoryInfo mem, boolean checkin,
   1210                 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
   1211                 boolean dumpUnreachable, String[] args) {
   1212             FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor());
   1213             PrintWriter pw = new FastPrintWriter(fout);
   1214             try {
   1215                 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
   1216             } finally {
   1217                 pw.flush();
   1218                 IoUtils.closeQuietly(pfd);
   1219             }
   1220         }
   1221 
   1222         private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
   1223                 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable) {
   1224             long nativeMax = Debug.getNativeHeapSize() / 1024;
   1225             long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
   1226             long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
   1227 
   1228             Runtime runtime = Runtime.getRuntime();
   1229             runtime.gc();  // Do GC since countInstancesOfClass counts unreachable objects.
   1230             long dalvikMax = runtime.totalMemory() / 1024;
   1231             long dalvikFree = runtime.freeMemory() / 1024;
   1232             long dalvikAllocated = dalvikMax - dalvikFree;
   1233 
   1234             Class[] classesToCount = new Class[] {
   1235                     ContextImpl.class,
   1236                     Activity.class,
   1237                     WebView.class,
   1238                     OpenSSLSocketImpl.class
   1239             };
   1240             long[] instanceCounts = VMDebug.countInstancesOfClasses(classesToCount, true);
   1241             long appContextInstanceCount = instanceCounts[0];
   1242             long activityInstanceCount = instanceCounts[1];
   1243             long webviewInstanceCount = instanceCounts[2];
   1244             long openSslSocketCount = instanceCounts[3];
   1245 
   1246             long viewInstanceCount = ViewDebug.getViewInstanceCount();
   1247             long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
   1248             int globalAssetCount = AssetManager.getGlobalAssetCount();
   1249             int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
   1250             int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
   1251             int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
   1252             int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
   1253             long parcelSize = Parcel.getGlobalAllocSize();
   1254             long parcelCount = Parcel.getGlobalAllocCount();
   1255             SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
   1256 
   1257             dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly,
   1258                     Process.myPid(),
   1259                     (mBoundApplication != null) ? mBoundApplication.processName : "unknown",
   1260                     nativeMax, nativeAllocated, nativeFree,
   1261                     dalvikMax, dalvikAllocated, dalvikFree);
   1262 
   1263             if (checkin) {
   1264                 // NOTE: if you change anything significant below, also consider changing
   1265                 // ACTIVITY_THREAD_CHECKIN_VERSION.
   1266 
   1267                 // Object counts
   1268                 pw.print(viewInstanceCount); pw.print(',');
   1269                 pw.print(viewRootInstanceCount); pw.print(',');
   1270                 pw.print(appContextInstanceCount); pw.print(',');
   1271                 pw.print(activityInstanceCount); pw.print(',');
   1272 
   1273                 pw.print(globalAssetCount); pw.print(',');
   1274                 pw.print(globalAssetManagerCount); pw.print(',');
   1275                 pw.print(binderLocalObjectCount); pw.print(',');
   1276                 pw.print(binderProxyObjectCount); pw.print(',');
   1277 
   1278                 pw.print(binderDeathObjectCount); pw.print(',');
   1279                 pw.print(openSslSocketCount); pw.print(',');
   1280 
   1281                 // SQL
   1282                 pw.print(stats.memoryUsed / 1024); pw.print(',');
   1283                 pw.print(stats.memoryUsed / 1024); pw.print(',');
   1284                 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
   1285                 pw.print(stats.largestMemAlloc / 1024);
   1286                 for (int i = 0; i < stats.dbStats.size(); i++) {
   1287                     DbStats dbStats = stats.dbStats.get(i);
   1288                     pw.print(','); pw.print(dbStats.dbName);
   1289                     pw.print(','); pw.print(dbStats.pageSize);
   1290                     pw.print(','); pw.print(dbStats.dbSize);
   1291                     pw.print(','); pw.print(dbStats.lookaside);
   1292                     pw.print(','); pw.print(dbStats.cache);
   1293                     pw.print(','); pw.print(dbStats.cache);
   1294                 }
   1295                 pw.println();
   1296 
   1297                 return;
   1298             }
   1299 
   1300             pw.println(" ");
   1301             pw.println(" Objects");
   1302             printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
   1303                     viewRootInstanceCount);
   1304 
   1305             printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
   1306                     "Activities:", activityInstanceCount);
   1307 
   1308             printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
   1309                     "AssetManagers:", globalAssetManagerCount);
   1310 
   1311             printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
   1312                     "Proxy Binders:", binderProxyObjectCount);
   1313             printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024,
   1314                     "Parcel count:", parcelCount);
   1315             printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount,
   1316                     "OpenSSL Sockets:", openSslSocketCount);
   1317             printRow(pw, ONE_COUNT_COLUMN, "WebViews:", webviewInstanceCount);
   1318 
   1319             // SQLite mem info
   1320             pw.println(" ");
   1321             pw.println(" SQL");
   1322             printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
   1323             printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
   1324                     stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
   1325             pw.println(" ");
   1326             int N = stats.dbStats.size();
   1327             if (N > 0) {
   1328                 pw.println(" DATABASES");
   1329                 printRow(pw, DB_INFO_FORMAT, "pgsz", "dbsz", "Lookaside(b)", "cache",
   1330                         "Dbname");
   1331                 for (int i = 0; i < N; i++) {
   1332                     DbStats dbStats = stats.dbStats.get(i);
   1333                     printRow(pw, DB_INFO_FORMAT,
   1334                             (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
   1335                             (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
   1336                             (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
   1337                             dbStats.cache, dbStats.dbName);
   1338                 }
   1339             }
   1340 
   1341             // Asset details.
   1342             String assetAlloc = AssetManager.getAssetAllocations();
   1343             if (assetAlloc != null) {
   1344                 pw.println(" ");
   1345                 pw.println(" Asset Allocations");
   1346                 pw.print(assetAlloc);
   1347             }
   1348 
   1349             // Unreachable native memory
   1350             if (dumpUnreachable) {
   1351                 boolean showContents = ((mBoundApplication != null)
   1352                     && ((mBoundApplication.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0))
   1353                     || android.os.Build.IS_DEBUGGABLE;
   1354                 pw.println(" ");
   1355                 pw.println(" Unreachable memory");
   1356                 pw.print(Debug.getUnreachableMemory(100, showContents));
   1357             }
   1358         }
   1359 
   1360         @Override
   1361         public void dumpMemInfoProto(ParcelFileDescriptor pfd, Debug.MemoryInfo mem,
   1362                 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
   1363                 boolean dumpUnreachable, String[] args) {
   1364             ProtoOutputStream proto = new ProtoOutputStream(pfd.getFileDescriptor());
   1365             try {
   1366                 dumpMemInfo(proto, mem, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
   1367             } finally {
   1368                 proto.flush();
   1369                 IoUtils.closeQuietly(pfd);
   1370             }
   1371         }
   1372 
   1373         private void dumpMemInfo(ProtoOutputStream proto, Debug.MemoryInfo memInfo,
   1374                 boolean dumpFullInfo, boolean dumpDalvik,
   1375                 boolean dumpSummaryOnly, boolean dumpUnreachable) {
   1376             long nativeMax = Debug.getNativeHeapSize() / 1024;
   1377             long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
   1378             long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
   1379 
   1380             Runtime runtime = Runtime.getRuntime();
   1381             runtime.gc();  // Do GC since countInstancesOfClass counts unreachable objects.
   1382             long dalvikMax = runtime.totalMemory() / 1024;
   1383             long dalvikFree = runtime.freeMemory() / 1024;
   1384             long dalvikAllocated = dalvikMax - dalvikFree;
   1385 
   1386             Class[] classesToCount = new Class[] {
   1387                     ContextImpl.class,
   1388                     Activity.class,
   1389                     WebView.class,
   1390                     OpenSSLSocketImpl.class
   1391             };
   1392             long[] instanceCounts = VMDebug.countInstancesOfClasses(classesToCount, true);
   1393             long appContextInstanceCount = instanceCounts[0];
   1394             long activityInstanceCount = instanceCounts[1];
   1395             long webviewInstanceCount = instanceCounts[2];
   1396             long openSslSocketCount = instanceCounts[3];
   1397 
   1398             long viewInstanceCount = ViewDebug.getViewInstanceCount();
   1399             long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
   1400             int globalAssetCount = AssetManager.getGlobalAssetCount();
   1401             int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
   1402             int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
   1403             int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
   1404             int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
   1405             long parcelSize = Parcel.getGlobalAllocSize();
   1406             long parcelCount = Parcel.getGlobalAllocCount();
   1407             SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
   1408 
   1409             final long mToken = proto.start(MemInfoDumpProto.AppData.PROCESS_MEMORY);
   1410             proto.write(MemInfoDumpProto.ProcessMemory.PID, Process.myPid());
   1411             proto.write(MemInfoDumpProto.ProcessMemory.PROCESS_NAME,
   1412                     (mBoundApplication != null) ? mBoundApplication.processName : "unknown");
   1413             dumpMemInfoTable(proto, memInfo, dumpDalvik, dumpSummaryOnly,
   1414                     nativeMax, nativeAllocated, nativeFree,
   1415                     dalvikMax, dalvikAllocated, dalvikFree);
   1416             proto.end(mToken);
   1417 
   1418             final long oToken = proto.start(MemInfoDumpProto.AppData.OBJECTS);
   1419             proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_INSTANCE_COUNT,
   1420                     viewInstanceCount);
   1421             proto.write(MemInfoDumpProto.AppData.ObjectStats.VIEW_ROOT_INSTANCE_COUNT,
   1422                     viewRootInstanceCount);
   1423             proto.write(MemInfoDumpProto.AppData.ObjectStats.APP_CONTEXT_INSTANCE_COUNT,
   1424                     appContextInstanceCount);
   1425             proto.write(MemInfoDumpProto.AppData.ObjectStats.ACTIVITY_INSTANCE_COUNT,
   1426                     activityInstanceCount);
   1427             proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_COUNT,
   1428                     globalAssetCount);
   1429             proto.write(MemInfoDumpProto.AppData.ObjectStats.GLOBAL_ASSET_MANAGER_COUNT,
   1430                     globalAssetManagerCount);
   1431             proto.write(MemInfoDumpProto.AppData.ObjectStats.LOCAL_BINDER_OBJECT_COUNT,
   1432                     binderLocalObjectCount);
   1433             proto.write(MemInfoDumpProto.AppData.ObjectStats.PROXY_BINDER_OBJECT_COUNT,
   1434                     binderProxyObjectCount);
   1435             proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_MEMORY_KB,
   1436                     parcelSize / 1024);
   1437             proto.write(MemInfoDumpProto.AppData.ObjectStats.PARCEL_COUNT, parcelCount);
   1438             proto.write(MemInfoDumpProto.AppData.ObjectStats.BINDER_OBJECT_DEATH_COUNT,
   1439                     binderDeathObjectCount);
   1440             proto.write(MemInfoDumpProto.AppData.ObjectStats.OPEN_SSL_SOCKET_COUNT,
   1441                     openSslSocketCount);
   1442             proto.write(MemInfoDumpProto.AppData.ObjectStats.WEBVIEW_INSTANCE_COUNT,
   1443                     webviewInstanceCount);
   1444             proto.end(oToken);
   1445 
   1446             // SQLite mem info
   1447             final long sToken = proto.start(MemInfoDumpProto.AppData.SQL);
   1448             proto.write(MemInfoDumpProto.AppData.SqlStats.MEMORY_USED_KB,
   1449                     stats.memoryUsed / 1024);
   1450             proto.write(MemInfoDumpProto.AppData.SqlStats.PAGECACHE_OVERFLOW_KB,
   1451                     stats.pageCacheOverflow / 1024);
   1452             proto.write(MemInfoDumpProto.AppData.SqlStats.MALLOC_SIZE_KB,
   1453                     stats.largestMemAlloc / 1024);
   1454             int n = stats.dbStats.size();
   1455             for (int i = 0; i < n; i++) {
   1456                 DbStats dbStats = stats.dbStats.get(i);
   1457 
   1458                 final long dToken = proto.start(MemInfoDumpProto.AppData.SqlStats.DATABASES);
   1459                 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.NAME, dbStats.dbName);
   1460                 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.PAGE_SIZE, dbStats.pageSize);
   1461                 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.DB_SIZE, dbStats.dbSize);
   1462                 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.LOOKASIDE_B,
   1463                         dbStats.lookaside);
   1464                 proto.write(MemInfoDumpProto.AppData.SqlStats.Database.CACHE, dbStats.cache);
   1465                 proto.end(dToken);
   1466             }
   1467             proto.end(sToken);
   1468 
   1469             // Asset details.
   1470             String assetAlloc = AssetManager.getAssetAllocations();
   1471             if (assetAlloc != null) {
   1472                 proto.write(MemInfoDumpProto.AppData.ASSET_ALLOCATIONS, assetAlloc);
   1473             }
   1474 
   1475             // Unreachable native memory
   1476             if (dumpUnreachable) {
   1477                 int flags = mBoundApplication == null ? 0 : mBoundApplication.appInfo.flags;
   1478                 boolean showContents = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0
   1479                         || android.os.Build.IS_DEBUGGABLE;
   1480                 proto.write(MemInfoDumpProto.AppData.UNREACHABLE_MEMORY,
   1481                         Debug.getUnreachableMemory(100, showContents));
   1482             }
   1483         }
   1484 
   1485         @Override
   1486         public void dumpGfxInfo(ParcelFileDescriptor pfd, String[] args) {
   1487             nDumpGraphicsInfo(pfd.getFileDescriptor());
   1488             WindowManagerGlobal.getInstance().dumpGfxInfo(pfd.getFileDescriptor(), args);
   1489             IoUtils.closeQuietly(pfd);
   1490         }
   1491 
   1492         private File getDatabasesDir(Context context) {
   1493             // There's no simple way to get the databases/ path, so do it this way.
   1494             return context.getDatabasePath("a").getParentFile();
   1495         }
   1496 
   1497         private void dumpDatabaseInfo(ParcelFileDescriptor pfd, String[] args, boolean isSystem) {
   1498             PrintWriter pw = new FastPrintWriter(
   1499                     new FileOutputStream(pfd.getFileDescriptor()));
   1500             PrintWriterPrinter printer = new PrintWriterPrinter(pw);
   1501             SQLiteDebug.dump(printer, args, isSystem);
   1502             pw.flush();
   1503         }
   1504 
   1505         @Override
   1506         public void dumpDbInfo(final ParcelFileDescriptor pfd, final String[] args) {
   1507             if (mSystemThread) {
   1508                 // Ensure this invocation is asynchronous to prevent writer waiting if buffer cannot
   1509                 // be consumed. But it must duplicate the file descriptor first, since caller might
   1510                 // be closing it.
   1511                 final ParcelFileDescriptor dup;
   1512                 try {
   1513                     dup = pfd.dup();
   1514                 } catch (IOException e) {
   1515                     Log.w(TAG, "Could not dup FD " + pfd.getFileDescriptor().getInt$());
   1516                     return;
   1517                 } finally {
   1518                     IoUtils.closeQuietly(pfd);
   1519                 }
   1520 
   1521                 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
   1522                     @Override
   1523                     public void run() {
   1524                         try {
   1525                             dumpDatabaseInfo(dup, args, true);
   1526                         } finally {
   1527                             IoUtils.closeQuietly(dup);
   1528                         }
   1529                     }
   1530                 });
   1531             } else {
   1532                 dumpDatabaseInfo(pfd, args, false);
   1533                 IoUtils.closeQuietly(pfd);
   1534             }
   1535         }
   1536 
   1537         @Override
   1538         public void unstableProviderDied(IBinder provider) {
   1539             sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
   1540         }
   1541 
   1542         @Override
   1543         public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
   1544                 int requestType, int sessionId, int flags) {
   1545             RequestAssistContextExtras cmd = new RequestAssistContextExtras();
   1546             cmd.activityToken = activityToken;
   1547             cmd.requestToken = requestToken;
   1548             cmd.requestType = requestType;
   1549             cmd.sessionId = sessionId;
   1550             cmd.flags = flags;
   1551             sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
   1552         }
   1553 
   1554         public void setCoreSettings(Bundle coreSettings) {
   1555             sendMessage(H.SET_CORE_SETTINGS, coreSettings);
   1556         }
   1557 
   1558         public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
   1559             UpdateCompatibilityData ucd = new UpdateCompatibilityData();
   1560             ucd.pkg = pkg;
   1561             ucd.info = info;
   1562             sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
   1563         }
   1564 
   1565         public void scheduleTrimMemory(int level) {
   1566             final Runnable r = PooledLambda.obtainRunnable(ActivityThread::handleTrimMemory,
   1567                     ActivityThread.this, level).recycleOnUse();
   1568             // Schedule trimming memory after drawing the frame to minimize jank-risk.
   1569             Choreographer choreographer = Choreographer.getMainThreadInstance();
   1570             if (choreographer != null) {
   1571                 choreographer.postCallback(Choreographer.CALLBACK_COMMIT, r, null);
   1572             } else {
   1573                 mH.post(r);
   1574             }
   1575         }
   1576 
   1577         public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
   1578             sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
   1579         }
   1580 
   1581         public void scheduleOnNewActivityOptions(IBinder token, Bundle options) {
   1582             sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
   1583                     new Pair<IBinder, ActivityOptions>(token, ActivityOptions.fromBundle(options)));
   1584         }
   1585 
   1586         public void setProcessState(int state) {
   1587             updateProcessState(state, true);
   1588         }
   1589 
   1590         /**
   1591          * Updates {@link #mNetworkBlockSeq}. This is used by ActivityManagerService to inform
   1592          * the main thread that it needs to wait for the network rules to get updated before
   1593          * launching an activity.
   1594          */
   1595         @Override
   1596         public void setNetworkBlockSeq(long procStateSeq) {
   1597             synchronized (mNetworkPolicyLock) {
   1598                 mNetworkBlockSeq = procStateSeq;
   1599             }
   1600         }
   1601 
   1602         @Override
   1603         public void scheduleInstallProvider(ProviderInfo provider) {
   1604             sendMessage(H.INSTALL_PROVIDER, provider);
   1605         }
   1606 
   1607         @Override
   1608         public final void updateTimePrefs(int timeFormatPreference) {
   1609             final Boolean timeFormatPreferenceBool;
   1610             // For convenience we are using the Intent extra values.
   1611             if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR) {
   1612                 timeFormatPreferenceBool = Boolean.FALSE;
   1613             } else if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR) {
   1614                 timeFormatPreferenceBool = Boolean.TRUE;
   1615             } else {
   1616                 // timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT
   1617                 // (or unknown).
   1618                 timeFormatPreferenceBool = null;
   1619             }
   1620             DateFormat.set24HourTimePref(timeFormatPreferenceBool);
   1621         }
   1622 
   1623         @Override
   1624         public void scheduleEnterAnimationComplete(IBinder token) {
   1625             sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
   1626         }
   1627 
   1628         @Override
   1629         public void notifyCleartextNetwork(byte[] firstPacket) {
   1630             if (StrictMode.vmCleartextNetworkEnabled()) {
   1631                 StrictMode.onCleartextNetworkDetected(firstPacket);
   1632             }
   1633         }
   1634 
   1635         @Override
   1636         public void startBinderTracking() {
   1637             sendMessage(H.START_BINDER_TRACKING, null);
   1638         }
   1639 
   1640         @Override
   1641         public void stopBinderTrackingAndDump(ParcelFileDescriptor pfd) {
   1642             try {
   1643                 sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, pfd.dup());
   1644             } catch (IOException e) {
   1645             } finally {
   1646                 IoUtils.closeQuietly(pfd);
   1647             }
   1648         }
   1649 
   1650         @Override
   1651         public void scheduleLocalVoiceInteractionStarted(IBinder token,
   1652                 IVoiceInteractor voiceInteractor) throws RemoteException {
   1653             SomeArgs args = SomeArgs.obtain();
   1654             args.arg1 = token;
   1655             args.arg2 = voiceInteractor;
   1656             sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args);
   1657         }
   1658 
   1659         @Override
   1660         public void handleTrustStorageUpdate() {
   1661             NetworkSecurityPolicy.getInstance().handleTrustStorageUpdate();
   1662         }
   1663 
   1664         @Override
   1665         public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
   1666             ActivityThread.this.scheduleTransaction(transaction);
   1667         }
   1668 
   1669         @Override
   1670         public void requestDirectActions(@NonNull IBinder activityToken,
   1671                 @NonNull IVoiceInteractor interactor, @Nullable RemoteCallback cancellationCallback,
   1672                 @NonNull RemoteCallback callback) {
   1673             final CancellationSignal cancellationSignal = new CancellationSignal();
   1674             if (cancellationCallback != null) {
   1675                 final ICancellationSignal transport = createSafeCancellationTransport(
   1676                         cancellationSignal);
   1677                 final Bundle cancellationResult = new Bundle();
   1678                 cancellationResult.putBinder(VoiceInteractor.KEY_CANCELLATION_SIGNAL,
   1679                         transport.asBinder());
   1680                 cancellationCallback.sendResult(cancellationResult);
   1681             }
   1682             mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handleRequestDirectActions,
   1683                     ActivityThread.this, activityToken, interactor, cancellationSignal, callback));
   1684         }
   1685 
   1686         @Override
   1687         public void performDirectAction(@NonNull IBinder activityToken, @NonNull String actionId,
   1688                 @Nullable Bundle arguments, @Nullable RemoteCallback cancellationCallback,
   1689                 @NonNull RemoteCallback resultCallback) {
   1690             final CancellationSignal cancellationSignal = new CancellationSignal();
   1691             if (cancellationCallback != null) {
   1692                 final ICancellationSignal transport = createSafeCancellationTransport(
   1693                         cancellationSignal);
   1694                 final Bundle cancellationResult = new Bundle();
   1695                 cancellationResult.putBinder(VoiceInteractor.KEY_CANCELLATION_SIGNAL,
   1696                         transport.asBinder());
   1697                 cancellationCallback.sendResult(cancellationResult);
   1698             }
   1699             mH.sendMessage(PooledLambda.obtainMessage(ActivityThread::handlePerformDirectAction,
   1700                     ActivityThread.this, activityToken, actionId, arguments,
   1701                     cancellationSignal, resultCallback));
   1702         }
   1703     }
   1704 
   1705     private @NonNull SafeCancellationTransport createSafeCancellationTransport(
   1706             @NonNull CancellationSignal cancellationSignal) {
   1707         synchronized (ActivityThread.this) {
   1708             if (mRemoteCancellations == null) {
   1709                 mRemoteCancellations = new ArrayMap<>();
   1710             }
   1711             final SafeCancellationTransport transport = new SafeCancellationTransport(
   1712                     this, cancellationSignal);
   1713             mRemoteCancellations.put(transport, cancellationSignal);
   1714             return transport;
   1715         }
   1716     }
   1717 
   1718     private @NonNull CancellationSignal removeSafeCancellationTransport(
   1719             @NonNull SafeCancellationTransport transport) {
   1720         synchronized (ActivityThread.this) {
   1721             final CancellationSignal cancellation = mRemoteCancellations.remove(transport);
   1722             if (mRemoteCancellations.isEmpty()) {
   1723                 mRemoteCancellations = null;
   1724             }
   1725             return cancellation;
   1726         }
   1727     }
   1728 
   1729     private static final class SafeCancellationTransport extends ICancellationSignal.Stub {
   1730         private final @NonNull WeakReference<ActivityThread> mWeakActivityThread;
   1731 
   1732         SafeCancellationTransport(@NonNull ActivityThread activityThread,
   1733                 @NonNull CancellationSignal cancellation) {
   1734             mWeakActivityThread = new WeakReference<>(activityThread);
   1735         }
   1736 
   1737         @Override
   1738         public void cancel() {
   1739             final ActivityThread activityThread = mWeakActivityThread.get();
   1740             if (activityThread != null) {
   1741                 final CancellationSignal cancellation = activityThread
   1742                         .removeSafeCancellationTransport(this);
   1743                 if (cancellation != null) {
   1744                     cancellation.cancel();
   1745                 }
   1746             }
   1747         }
   1748     }
   1749 
   1750     class H extends Handler {
   1751         public static final int BIND_APPLICATION        = 110;
   1752         @UnsupportedAppUsage
   1753         public static final int EXIT_APPLICATION        = 111;
   1754         @UnsupportedAppUsage
   1755         public static final int RECEIVER                = 113;
   1756         @UnsupportedAppUsage
   1757         public static final int CREATE_SERVICE          = 114;
   1758         @UnsupportedAppUsage
   1759         public static final int SERVICE_ARGS            = 115;
   1760         @UnsupportedAppUsage
   1761         public static final int STOP_SERVICE            = 116;
   1762 
   1763         public static final int CONFIGURATION_CHANGED   = 118;
   1764         public static final int CLEAN_UP_CONTEXT        = 119;
   1765         @UnsupportedAppUsage
   1766         public static final int GC_WHEN_IDLE            = 120;
   1767         @UnsupportedAppUsage
   1768         public static final int BIND_SERVICE            = 121;
   1769         @UnsupportedAppUsage
   1770         public static final int UNBIND_SERVICE          = 122;
   1771         public static final int DUMP_SERVICE            = 123;
   1772         public static final int LOW_MEMORY              = 124;
   1773         public static final int PROFILER_CONTROL        = 127;
   1774         public static final int CREATE_BACKUP_AGENT     = 128;
   1775         public static final int DESTROY_BACKUP_AGENT    = 129;
   1776         public static final int SUICIDE                 = 130;
   1777         @UnsupportedAppUsage
   1778         public static final int REMOVE_PROVIDER         = 131;
   1779         public static final int DISPATCH_PACKAGE_BROADCAST = 133;
   1780         @UnsupportedAppUsage
   1781         public static final int SCHEDULE_CRASH          = 134;
   1782         public static final int DUMP_HEAP               = 135;
   1783         public static final int DUMP_ACTIVITY           = 136;
   1784         public static final int SLEEPING                = 137;
   1785         public static final int SET_CORE_SETTINGS       = 138;
   1786         public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
   1787         @UnsupportedAppUsage
   1788         public static final int DUMP_PROVIDER           = 141;
   1789         public static final int UNSTABLE_PROVIDER_DIED  = 142;
   1790         public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
   1791         public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
   1792         @UnsupportedAppUsage
   1793         public static final int INSTALL_PROVIDER        = 145;
   1794         public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
   1795         @UnsupportedAppUsage
   1796         public static final int ENTER_ANIMATION_COMPLETE = 149;
   1797         public static final int START_BINDER_TRACKING = 150;
   1798         public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
   1799         public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
   1800         public static final int ATTACH_AGENT = 155;
   1801         public static final int APPLICATION_INFO_CHANGED = 156;
   1802         public static final int RUN_ISOLATED_ENTRY_POINT = 158;
   1803         public static final int EXECUTE_TRANSACTION = 159;
   1804         public static final int RELAUNCH_ACTIVITY = 160;
   1805         public static final int PURGE_RESOURCES = 161;
   1806 
   1807         String codeToString(int code) {
   1808             if (DEBUG_MESSAGES) {
   1809                 switch (code) {
   1810                     case BIND_APPLICATION: return "BIND_APPLICATION";
   1811                     case EXIT_APPLICATION: return "EXIT_APPLICATION";
   1812                     case RECEIVER: return "RECEIVER";
   1813                     case CREATE_SERVICE: return "CREATE_SERVICE";
   1814                     case SERVICE_ARGS: return "SERVICE_ARGS";
   1815                     case STOP_SERVICE: return "STOP_SERVICE";
   1816                     case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
   1817                     case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
   1818                     case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
   1819                     case BIND_SERVICE: return "BIND_SERVICE";
   1820                     case UNBIND_SERVICE: return "UNBIND_SERVICE";
   1821                     case DUMP_SERVICE: return "DUMP_SERVICE";
   1822                     case LOW_MEMORY: return "LOW_MEMORY";
   1823                     case PROFILER_CONTROL: return "PROFILER_CONTROL";
   1824                     case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
   1825                     case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
   1826                     case SUICIDE: return "SUICIDE";
   1827                     case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
   1828                     case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
   1829                     case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
   1830                     case DUMP_HEAP: return "DUMP_HEAP";
   1831                     case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
   1832                     case SLEEPING: return "SLEEPING";
   1833                     case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
   1834                     case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
   1835                     case DUMP_PROVIDER: return "DUMP_PROVIDER";
   1836                     case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
   1837                     case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
   1838                     case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
   1839                     case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
   1840                     case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
   1841                     case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
   1842                     case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
   1843                     case ATTACH_AGENT: return "ATTACH_AGENT";
   1844                     case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED";
   1845                     case RUN_ISOLATED_ENTRY_POINT: return "RUN_ISOLATED_ENTRY_POINT";
   1846                     case EXECUTE_TRANSACTION: return "EXECUTE_TRANSACTION";
   1847                     case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
   1848                     case PURGE_RESOURCES: return "PURGE_RESOURCES";
   1849                 }
   1850             }
   1851             return Integer.toString(code);
   1852         }
   1853         public void handleMessage(Message msg) {
   1854             if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
   1855             switch (msg.what) {
   1856                 case BIND_APPLICATION:
   1857                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
   1858                     AppBindData data = (AppBindData)msg.obj;
   1859                     handleBindApplication(data);
   1860                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1861                     break;
   1862                 case EXIT_APPLICATION:
   1863                     if (mInitialApplication != null) {
   1864                         mInitialApplication.onTerminate();
   1865                     }
   1866                     Looper.myLooper().quit();
   1867                     break;
   1868                 case RECEIVER:
   1869                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
   1870                     handleReceiver((ReceiverData)msg.obj);
   1871                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1872                     break;
   1873                 case CREATE_SERVICE:
   1874                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
   1875                     handleCreateService((CreateServiceData)msg.obj);
   1876                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1877                     break;
   1878                 case BIND_SERVICE:
   1879                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
   1880                     handleBindService((BindServiceData)msg.obj);
   1881                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1882                     break;
   1883                 case UNBIND_SERVICE:
   1884                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
   1885                     handleUnbindService((BindServiceData)msg.obj);
   1886                     schedulePurgeIdler();
   1887                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1888                     break;
   1889                 case SERVICE_ARGS:
   1890                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
   1891                     handleServiceArgs((ServiceArgsData)msg.obj);
   1892                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1893                     break;
   1894                 case STOP_SERVICE:
   1895                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
   1896                     handleStopService((IBinder)msg.obj);
   1897                     schedulePurgeIdler();
   1898                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1899                     break;
   1900                 case CONFIGURATION_CHANGED:
   1901                     handleConfigurationChanged((Configuration) msg.obj);
   1902                     break;
   1903                 case CLEAN_UP_CONTEXT:
   1904                     ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
   1905                     cci.context.performFinalCleanup(cci.who, cci.what);
   1906                     break;
   1907                 case GC_WHEN_IDLE:
   1908                     scheduleGcIdler();
   1909                     break;
   1910                 case DUMP_SERVICE:
   1911                     handleDumpService((DumpComponentInfo)msg.obj);
   1912                     break;
   1913                 case LOW_MEMORY:
   1914                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
   1915                     handleLowMemory();
   1916                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1917                     break;
   1918                 case PROFILER_CONTROL:
   1919                     handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
   1920                     break;
   1921                 case CREATE_BACKUP_AGENT:
   1922                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
   1923                     handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
   1924                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1925                     break;
   1926                 case DESTROY_BACKUP_AGENT:
   1927                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
   1928                     handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
   1929                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1930                     break;
   1931                 case SUICIDE:
   1932                     Process.killProcess(Process.myPid());
   1933                     break;
   1934                 case REMOVE_PROVIDER:
   1935                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
   1936                     completeRemoveProvider((ProviderRefCount)msg.obj);
   1937                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1938                     break;
   1939                 case DISPATCH_PACKAGE_BROADCAST:
   1940                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
   1941                     handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
   1942                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1943                     break;
   1944                 case SCHEDULE_CRASH:
   1945                     throw new RemoteServiceException((String)msg.obj);
   1946                 case DUMP_HEAP:
   1947                     handleDumpHeap((DumpHeapData) msg.obj);
   1948                     break;
   1949                 case DUMP_ACTIVITY:
   1950                     handleDumpActivity((DumpComponentInfo)msg.obj);
   1951                     break;
   1952                 case DUMP_PROVIDER:
   1953                     handleDumpProvider((DumpComponentInfo)msg.obj);
   1954                     break;
   1955                 case SLEEPING:
   1956                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
   1957                     handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
   1958                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1959                     break;
   1960                 case SET_CORE_SETTINGS:
   1961                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
   1962                     handleSetCoreSettings((Bundle) msg.obj);
   1963                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   1964                     break;
   1965                 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
   1966                     handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
   1967                     break;
   1968                 case UNSTABLE_PROVIDER_DIED:
   1969                     handleUnstableProviderDied((IBinder)msg.obj, false);
   1970                     break;
   1971                 case REQUEST_ASSIST_CONTEXT_EXTRAS:
   1972                     handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
   1973                     break;
   1974                 case TRANSLUCENT_CONVERSION_COMPLETE:
   1975                     handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
   1976                     break;
   1977                 case INSTALL_PROVIDER:
   1978                     handleInstallProvider((ProviderInfo) msg.obj);
   1979                     break;
   1980                 case ON_NEW_ACTIVITY_OPTIONS:
   1981                     Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
   1982                     onNewActivityOptions(pair.first, pair.second);
   1983                     break;
   1984                 case ENTER_ANIMATION_COMPLETE:
   1985                     handleEnterAnimationComplete((IBinder) msg.obj);
   1986                     break;
   1987                 case START_BINDER_TRACKING:
   1988                     handleStartBinderTracking();
   1989                     break;
   1990                 case STOP_BINDER_TRACKING_AND_DUMP:
   1991                     handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
   1992                     break;
   1993                 case LOCAL_VOICE_INTERACTION_STARTED:
   1994                     handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
   1995                             (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
   1996                     break;
   1997                 case ATTACH_AGENT: {
   1998                     Application app = getApplication();
   1999                     handleAttachAgent((String) msg.obj, app != null ? app.mLoadedApk : null);
   2000                     break;
   2001                 }
   2002                 case APPLICATION_INFO_CHANGED:
   2003                     mUpdatingSystemConfig = true;
   2004                     try {
   2005                         handleApplicationInfoChanged((ApplicationInfo) msg.obj);
   2006                     } finally {
   2007                         mUpdatingSystemConfig = false;
   2008                     }
   2009                     break;
   2010                 case RUN_ISOLATED_ENTRY_POINT:
   2011                     handleRunIsolatedEntryPoint((String) ((SomeArgs) msg.obj).arg1,
   2012                             (String[]) ((SomeArgs) msg.obj).arg2);
   2013                     break;
   2014                 case EXECUTE_TRANSACTION:
   2015                     final ClientTransaction transaction = (ClientTransaction) msg.obj;
   2016                     mTransactionExecutor.execute(transaction);
   2017                     if (isSystem()) {
   2018                         // Client transactions inside system process are recycled on the client side
   2019                         // instead of ClientLifecycleManager to avoid being cleared before this
   2020                         // message is handled.
   2021                         transaction.recycle();
   2022                     }
   2023                     // TODO(lifecycler): Recycle locally scheduled transactions.
   2024                     break;
   2025                 case RELAUNCH_ACTIVITY:
   2026                     handleRelaunchActivityLocally((IBinder) msg.obj);
   2027                     break;
   2028                 case PURGE_RESOURCES:
   2029                     schedulePurgeIdler();
   2030                     break;
   2031             }
   2032             Object obj = msg.obj;
   2033             if (obj instanceof SomeArgs) {
   2034                 ((SomeArgs) obj).recycle();
   2035             }
   2036             if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
   2037         }
   2038     }
   2039 
   2040     private class Idler implements MessageQueue.IdleHandler {
   2041         @Override
   2042         public final boolean queueIdle() {
   2043             ActivityClientRecord a = mNewActivities;
   2044             boolean stopProfiling = false;
   2045             if (mBoundApplication != null && mProfiler.profileFd != null
   2046                     && mProfiler.autoStopProfiler) {
   2047                 stopProfiling = true;
   2048             }
   2049             if (a != null) {
   2050                 mNewActivities = null;
   2051                 IActivityTaskManager am = ActivityTaskManager.getService();
   2052                 ActivityClientRecord prev;
   2053                 do {
   2054                     if (localLOGV) Slog.v(
   2055                         TAG, "Reporting idle of " + a +
   2056                         " finished=" +
   2057                         (a.activity != null && a.activity.mFinished));
   2058                     if (a.activity != null && !a.activity.mFinished) {
   2059                         try {
   2060                             am.activityIdle(a.token, a.createdConfig, stopProfiling);
   2061                             a.createdConfig = null;
   2062                         } catch (RemoteException ex) {
   2063                             throw ex.rethrowFromSystemServer();
   2064                         }
   2065                     }
   2066                     prev = a;
   2067                     a = a.nextIdle;
   2068                     prev.nextIdle = null;
   2069                 } while (a != null);
   2070             }
   2071             if (stopProfiling) {
   2072                 mProfiler.stopProfiling();
   2073             }
   2074             applyPendingProcessState();
   2075             return false;
   2076         }
   2077     }
   2078 
   2079     final class GcIdler implements MessageQueue.IdleHandler {
   2080         @Override
   2081         public final boolean queueIdle() {
   2082             doGcIfNeeded();
   2083             purgePendingResources();
   2084             return false;
   2085         }
   2086     }
   2087 
   2088     final class PurgeIdler implements MessageQueue.IdleHandler {
   2089         @Override
   2090         public boolean queueIdle() {
   2091             purgePendingResources();
   2092             return false;
   2093         }
   2094     }
   2095 
   2096     @UnsupportedAppUsage
   2097     public static ActivityThread currentActivityThread() {
   2098         return sCurrentActivityThread;
   2099     }
   2100 
   2101     public static boolean isSystem() {
   2102         return (sCurrentActivityThread != null) ? sCurrentActivityThread.mSystemThread : false;
   2103     }
   2104 
   2105     public static String currentOpPackageName() {
   2106         ActivityThread am = currentActivityThread();
   2107         return (am != null && am.getApplication() != null)
   2108                 ? am.getApplication().getOpPackageName() : null;
   2109     }
   2110 
   2111     @UnsupportedAppUsage
   2112     public static String currentPackageName() {
   2113         ActivityThread am = currentActivityThread();
   2114         return (am != null && am.mBoundApplication != null)
   2115             ? am.mBoundApplication.appInfo.packageName : null;
   2116     }
   2117 
   2118     @UnsupportedAppUsage
   2119     public static String currentProcessName() {
   2120         ActivityThread am = currentActivityThread();
   2121         return (am != null && am.mBoundApplication != null)
   2122             ? am.mBoundApplication.processName : null;
   2123     }
   2124 
   2125     @UnsupportedAppUsage
   2126     public static Application currentApplication() {
   2127         ActivityThread am = currentActivityThread();
   2128         return am != null ? am.mInitialApplication : null;
   2129     }
   2130 
   2131     @UnsupportedAppUsage
   2132     public static IPackageManager getPackageManager() {
   2133         if (sPackageManager != null) {
   2134             //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
   2135             return sPackageManager;
   2136         }
   2137         IBinder b = ServiceManager.getService("package");
   2138         //Slog.v("PackageManager", "default service binder = " + b);
   2139         sPackageManager = IPackageManager.Stub.asInterface(b);
   2140         //Slog.v("PackageManager", "default service = " + sPackageManager);
   2141         return sPackageManager;
   2142     }
   2143 
   2144     private Configuration mMainThreadConfig = new Configuration();
   2145 
   2146     Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
   2147             CompatibilityInfo compat) {
   2148         if (config == null) {
   2149             return null;
   2150         }
   2151         if (!compat.supportsScreen()) {
   2152             mMainThreadConfig.setTo(config);
   2153             config = mMainThreadConfig;
   2154             compat.applyToConfiguration(displayDensity, config);
   2155         }
   2156         return config;
   2157     }
   2158 
   2159     /**
   2160      * Creates the top level resources for the given package. Will return an existing
   2161      * Resources if one has already been created.
   2162      */
   2163     Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
   2164             String[] libDirs, int displayId, LoadedApk pkgInfo) {
   2165         return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
   2166                 displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader());
   2167     }
   2168 
   2169     @UnsupportedAppUsage
   2170     final Handler getHandler() {
   2171         return mH;
   2172     }
   2173 
   2174     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
   2175     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
   2176             int flags) {
   2177         return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
   2178     }
   2179 
   2180     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
   2181             int flags, int userId) {
   2182         final boolean differentUser = (UserHandle.myUserId() != userId);
   2183         ApplicationInfo ai;
   2184         try {
   2185             ai = getPackageManager().getApplicationInfo(packageName,
   2186                     PackageManager.GET_SHARED_LIBRARY_FILES
   2187                             | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
   2188                     (userId < 0) ? UserHandle.myUserId() : userId);
   2189         } catch (RemoteException e) {
   2190             throw e.rethrowFromSystemServer();
   2191         }
   2192 
   2193         synchronized (mResourcesManager) {
   2194             WeakReference<LoadedApk> ref;
   2195             if (differentUser) {
   2196                 // Caching not supported across users
   2197                 ref = null;
   2198             } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) {
   2199                 ref = mPackages.get(packageName);
   2200             } else {
   2201                 ref = mResourcePackages.get(packageName);
   2202             }
   2203 
   2204             LoadedApk packageInfo = ref != null ? ref.get() : null;
   2205             if (ai != null && packageInfo != null) {
   2206                 if (!isLoadedApkResourceDirsUpToDate(packageInfo, ai)) {
   2207                     packageInfo.updateApplicationInfo(ai, null);
   2208                 }
   2209 
   2210                 if (packageInfo.isSecurityViolation()
   2211                         && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
   2212                     throw new SecurityException(
   2213                             "Requesting code from " + packageName
   2214                             + " to be run in process "
   2215                             + mBoundApplication.processName
   2216                             + "/" + mBoundApplication.appInfo.uid);
   2217                 }
   2218                 return packageInfo;
   2219             }
   2220         }
   2221 
   2222         if (ai != null) {
   2223             return getPackageInfo(ai, compatInfo, flags);
   2224         }
   2225 
   2226         return null;
   2227     }
   2228 
   2229     @UnsupportedAppUsage
   2230     public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
   2231             int flags) {
   2232         boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
   2233         boolean securityViolation = includeCode && ai.uid != 0
   2234                 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
   2235                         ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
   2236                         : true);
   2237         boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0;
   2238         if ((flags&(Context.CONTEXT_INCLUDE_CODE
   2239                 |Context.CONTEXT_IGNORE_SECURITY))
   2240                 == Context.CONTEXT_INCLUDE_CODE) {
   2241             if (securityViolation) {
   2242                 String msg = "Requesting code from " + ai.packageName
   2243                         + " (with uid " + ai.uid + ")";
   2244                 if (mBoundApplication != null) {
   2245                     msg = msg + " to be run in process "
   2246                         + mBoundApplication.processName + " (with uid "
   2247                         + mBoundApplication.appInfo.uid + ")";
   2248                 }
   2249                 throw new SecurityException(msg);
   2250             }
   2251         }
   2252         return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
   2253                 registerPackage);
   2254     }
   2255 
   2256     @Override
   2257     @UnsupportedAppUsage
   2258     public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
   2259             CompatibilityInfo compatInfo) {
   2260         return getPackageInfo(ai, compatInfo, null, false, true, false);
   2261     }
   2262 
   2263     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
   2264     public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
   2265         synchronized (mResourcesManager) {
   2266             WeakReference<LoadedApk> ref;
   2267             if (includeCode) {
   2268                 ref = mPackages.get(packageName);
   2269             } else {
   2270                 ref = mResourcePackages.get(packageName);
   2271             }
   2272             return ref != null ? ref.get() : null;
   2273         }
   2274     }
   2275 
   2276     private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
   2277             ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
   2278             boolean registerPackage) {
   2279         final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
   2280         synchronized (mResourcesManager) {
   2281             WeakReference<LoadedApk> ref;
   2282             if (differentUser) {
   2283                 // Caching not supported across users
   2284                 ref = null;
   2285             } else if (includeCode) {
   2286                 ref = mPackages.get(aInfo.packageName);
   2287             } else {
   2288                 ref = mResourcePackages.get(aInfo.packageName);
   2289             }
   2290 
   2291             LoadedApk packageInfo = ref != null ? ref.get() : null;
   2292 
   2293             if (packageInfo != null) {
   2294                 if (!isLoadedApkResourceDirsUpToDate(packageInfo, aInfo)) {
   2295                     packageInfo.updateApplicationInfo(aInfo, null);
   2296                 }
   2297 
   2298                 return packageInfo;
   2299             }
   2300 
   2301             if (localLOGV) {
   2302                 Slog.v(TAG, (includeCode ? "Loading code package "
   2303                         : "Loading resource-only package ") + aInfo.packageName
   2304                         + " (in " + (mBoundApplication != null
   2305                         ? mBoundApplication.processName : null)
   2306                         + ")");
   2307             }
   2308 
   2309             packageInfo =
   2310                     new LoadedApk(this, aInfo, compatInfo, baseLoader,
   2311                             securityViolation, includeCode
   2312                             && (aInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
   2313 
   2314             if (mSystemThread && "android".equals(aInfo.packageName)) {
   2315                 packageInfo.installSystemApplicationInfo(aInfo,
   2316                         getSystemContext().mPackageInfo.getClassLoader());
   2317             }
   2318 
   2319             if (differentUser) {
   2320                 // Caching not supported across users
   2321             } else if (includeCode) {
   2322                 mPackages.put(aInfo.packageName,
   2323                         new WeakReference<LoadedApk>(packageInfo));
   2324             } else {
   2325                 mResourcePackages.put(aInfo.packageName,
   2326                         new WeakReference<LoadedApk>(packageInfo));
   2327             }
   2328 
   2329             return packageInfo;
   2330         }
   2331     }
   2332 
   2333     private static boolean isLoadedApkResourceDirsUpToDate(LoadedApk loadedApk,
   2334             ApplicationInfo appInfo) {
   2335         Resources packageResources = loadedApk.mResources;
   2336         String[] overlayDirs = ArrayUtils.defeatNullable(loadedApk.getOverlayDirs());
   2337         String[] resourceDirs = ArrayUtils.defeatNullable(appInfo.resourceDirs);
   2338 
   2339         return (packageResources == null || packageResources.getAssets().isUpToDate())
   2340                 && overlayDirs.length == resourceDirs.length
   2341                 && ArrayUtils.containsAll(overlayDirs, resourceDirs);
   2342     }
   2343 
   2344     @UnsupportedAppUsage
   2345     ActivityThread() {
   2346         mResourcesManager = ResourcesManager.getInstance();
   2347     }
   2348 
   2349     @UnsupportedAppUsage
   2350     public ApplicationThread getApplicationThread()
   2351     {
   2352         return mAppThread;
   2353     }
   2354 
   2355     @UnsupportedAppUsage
   2356     public Instrumentation getInstrumentation()
   2357     {
   2358         return mInstrumentation;
   2359     }
   2360 
   2361     public boolean isProfiling() {
   2362         return mProfiler != null && mProfiler.profileFile != null
   2363                 && mProfiler.profileFd == null;
   2364     }
   2365 
   2366     public String getProfileFilePath() {
   2367         return mProfiler.profileFile;
   2368     }
   2369 
   2370     @UnsupportedAppUsage
   2371     public Looper getLooper() {
   2372         return mLooper;
   2373     }
   2374 
   2375     public Executor getExecutor() {
   2376         return mExecutor;
   2377     }
   2378 
   2379     @UnsupportedAppUsage
   2380     public Application getApplication() {
   2381         return mInitialApplication;
   2382     }
   2383 
   2384     @UnsupportedAppUsage
   2385     public String getProcessName() {
   2386         return mBoundApplication.processName;
   2387     }
   2388 
   2389     @UnsupportedAppUsage
   2390     public ContextImpl getSystemContext() {
   2391         synchronized (this) {
   2392             if (mSystemContext == null) {
   2393                 mSystemContext = ContextImpl.createSystemContext(this);
   2394             }
   2395             return mSystemContext;
   2396         }
   2397     }
   2398 
   2399     public ContextImpl getSystemUiContext() {
   2400         synchronized (this) {
   2401             if (mSystemUiContext == null) {
   2402                 mSystemUiContext = ContextImpl.createSystemUiContext(getSystemContext());
   2403             }
   2404             return mSystemUiContext;
   2405         }
   2406     }
   2407 
   2408     /**
   2409      * Create the context instance base on system resources & display information which used for UI.
   2410      * @param displayId The ID of the display where the UI is shown.
   2411      * @see ContextImpl#createSystemUiContext(ContextImpl, int)
   2412      */
   2413     public ContextImpl createSystemUiContext(int displayId) {
   2414         return ContextImpl.createSystemUiContext(getSystemUiContext(), displayId);
   2415     }
   2416 
   2417     public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
   2418         synchronized (this) {
   2419             getSystemContext().installSystemApplicationInfo(info, classLoader);
   2420             getSystemUiContext().installSystemApplicationInfo(info, classLoader);
   2421 
   2422             // give ourselves a default profiler
   2423             mProfiler = new Profiler();
   2424         }
   2425     }
   2426 
   2427     @UnsupportedAppUsage
   2428     void scheduleGcIdler() {
   2429         if (!mGcIdlerScheduled) {
   2430             mGcIdlerScheduled = true;
   2431             Looper.myQueue().addIdleHandler(mGcIdler);
   2432         }
   2433         mH.removeMessages(H.GC_WHEN_IDLE);
   2434     }
   2435 
   2436     void unscheduleGcIdler() {
   2437         if (mGcIdlerScheduled) {
   2438             mGcIdlerScheduled = false;
   2439             Looper.myQueue().removeIdleHandler(mGcIdler);
   2440         }
   2441         mH.removeMessages(H.GC_WHEN_IDLE);
   2442     }
   2443 
   2444     void schedulePurgeIdler() {
   2445         if (!mPurgeIdlerScheduled) {
   2446             mPurgeIdlerScheduled = true;
   2447             Looper.myQueue().addIdleHandler(mPurgeIdler);
   2448         }
   2449         mH.removeMessages(H.PURGE_RESOURCES);
   2450     }
   2451 
   2452     void unschedulePurgeIdler() {
   2453         if (mPurgeIdlerScheduled) {
   2454             mPurgeIdlerScheduled = false;
   2455             Looper.myQueue().removeIdleHandler(mPurgeIdler);
   2456         }
   2457         mH.removeMessages(H.PURGE_RESOURCES);
   2458     }
   2459 
   2460     void doGcIfNeeded() {
   2461         doGcIfNeeded("bg");
   2462     }
   2463 
   2464     void doGcIfNeeded(String reason) {
   2465         mGcIdlerScheduled = false;
   2466         final long now = SystemClock.uptimeMillis();
   2467         //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
   2468         //        + "m now=" + now);
   2469         if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
   2470             //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
   2471             BinderInternal.forceGc(reason);
   2472         }
   2473     }
   2474 
   2475     private static final String HEAP_FULL_COLUMN
   2476             = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
   2477     private static final String HEAP_COLUMN
   2478             = "%13s %8s %8s %8s %8s %8s %8s %8s";
   2479     private static final String ONE_COUNT_COLUMN = "%21s %8d";
   2480     private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
   2481     private static final String ONE_COUNT_COLUMN_HEADER = "%21s %8s";
   2482 
   2483     // Formatting for checkin service - update version if row format changes
   2484     private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 4;
   2485 
   2486     static void printRow(PrintWriter pw, String format, Object...objs) {
   2487         pw.println(String.format(format, objs));
   2488     }
   2489 
   2490     public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
   2491             boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
   2492             int pid, String processName,
   2493             long nativeMax, long nativeAllocated, long nativeFree,
   2494             long dalvikMax, long dalvikAllocated, long dalvikFree) {
   2495 
   2496         // For checkin, we print one long comma-separated list of values
   2497         if (checkin) {
   2498             // NOTE: if you change anything significant below, also consider changing
   2499             // ACTIVITY_THREAD_CHECKIN_VERSION.
   2500 
   2501             // Header
   2502             pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
   2503             pw.print(pid); pw.print(',');
   2504             pw.print(processName); pw.print(',');
   2505 
   2506             // Heap info - max
   2507             pw.print(nativeMax); pw.print(',');
   2508             pw.print(dalvikMax); pw.print(',');
   2509             pw.print("N/A,");
   2510             pw.print(nativeMax + dalvikMax); pw.print(',');
   2511 
   2512             // Heap info - allocated
   2513             pw.print(nativeAllocated); pw.print(',');
   2514             pw.print(dalvikAllocated); pw.print(',');
   2515             pw.print("N/A,");
   2516             pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
   2517 
   2518             // Heap info - free
   2519             pw.print(nativeFree); pw.print(',');
   2520             pw.print(dalvikFree); pw.print(',');
   2521             pw.print("N/A,");
   2522             pw.print(nativeFree + dalvikFree); pw.print(',');
   2523 
   2524             // Heap info - proportional set size
   2525             pw.print(memInfo.nativePss); pw.print(',');
   2526             pw.print(memInfo.dalvikPss); pw.print(',');
   2527             pw.print(memInfo.otherPss); pw.print(',');
   2528             pw.print(memInfo.getTotalPss()); pw.print(',');
   2529 
   2530             // Heap info - swappable set size
   2531             pw.print(memInfo.nativeSwappablePss); pw.print(',');
   2532             pw.print(memInfo.dalvikSwappablePss); pw.print(',');
   2533             pw.print(memInfo.otherSwappablePss); pw.print(',');
   2534             pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
   2535 
   2536             // Heap info - shared dirty
   2537             pw.print(memInfo.nativeSharedDirty); pw.print(',');
   2538             pw.print(memInfo.dalvikSharedDirty); pw.print(',');
   2539             pw.print(memInfo.otherSharedDirty); pw.print(',');
   2540             pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
   2541 
   2542             // Heap info - shared clean
   2543             pw.print(memInfo.nativeSharedClean); pw.print(',');
   2544             pw.print(memInfo.dalvikSharedClean); pw.print(',');
   2545             pw.print(memInfo.otherSharedClean); pw.print(',');
   2546             pw.print(memInfo.getTotalSharedClean()); pw.print(',');
   2547 
   2548             // Heap info - private Dirty
   2549             pw.print(memInfo.nativePrivateDirty); pw.print(',');
   2550             pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
   2551             pw.print(memInfo.otherPrivateDirty); pw.print(',');
   2552             pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
   2553 
   2554             // Heap info - private Clean
   2555             pw.print(memInfo.nativePrivateClean); pw.print(',');
   2556             pw.print(memInfo.dalvikPrivateClean); pw.print(',');
   2557             pw.print(memInfo.otherPrivateClean); pw.print(',');
   2558             pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
   2559 
   2560             // Heap info - swapped out
   2561             pw.print(memInfo.nativeSwappedOut); pw.print(',');
   2562             pw.print(memInfo.dalvikSwappedOut); pw.print(',');
   2563             pw.print(memInfo.otherSwappedOut); pw.print(',');
   2564             pw.print(memInfo.getTotalSwappedOut()); pw.print(',');
   2565 
   2566             // Heap info - swapped out pss
   2567             if (memInfo.hasSwappedOutPss) {
   2568                 pw.print(memInfo.nativeSwappedOutPss); pw.print(',');
   2569                 pw.print(memInfo.dalvikSwappedOutPss); pw.print(',');
   2570                 pw.print(memInfo.otherSwappedOutPss); pw.print(',');
   2571                 pw.print(memInfo.getTotalSwappedOutPss()); pw.print(',');
   2572             } else {
   2573                 pw.print("N/A,");
   2574                 pw.print("N/A,");
   2575                 pw.print("N/A,");
   2576                 pw.print("N/A,");
   2577             }
   2578 
   2579             // Heap info - other areas
   2580             for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
   2581                 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
   2582                 pw.print(memInfo.getOtherPss(i)); pw.print(',');
   2583                 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
   2584                 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
   2585                 pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
   2586                 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
   2587                 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
   2588                 pw.print(memInfo.getOtherSwappedOut(i)); pw.print(',');
   2589                 if (memInfo.hasSwappedOutPss) {
   2590                     pw.print(memInfo.getOtherSwappedOutPss(i)); pw.print(',');
   2591                 } else {
   2592                     pw.print("N/A,");
   2593                 }
   2594             }
   2595             return;
   2596         }
   2597 
   2598         if (!dumpSummaryOnly) {
   2599             if (dumpFullInfo) {
   2600                 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
   2601                         "Shared", "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap",
   2602                         "Heap", "Heap", "Heap");
   2603                 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
   2604                         "Clean", "Clean", "Dirty",
   2605                         "Size", "Alloc", "Free");
   2606                 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
   2607                         "------", "------", "------", "------", "------", "------");
   2608                 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
   2609                         memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
   2610                         memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
   2611                         memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ?
   2612                         memInfo.nativeSwappedOutPss : memInfo.nativeSwappedOut,
   2613                         nativeMax, nativeAllocated, nativeFree);
   2614                 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
   2615                         memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
   2616                         memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
   2617                         memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ?
   2618                         memInfo.dalvikSwappedOutPss : memInfo.dalvikSwappedOut,
   2619                         dalvikMax, dalvikAllocated, dalvikFree);
   2620             } else {
   2621                 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
   2622                         "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap",
   2623                         "Heap", "Heap", "Heap");
   2624                 printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
   2625                         "Clean", "Dirty", "Size", "Alloc", "Free");
   2626                 printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
   2627                         "------", "------", "------", "------", "------");
   2628                 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
   2629                         memInfo.nativePrivateDirty,
   2630                         memInfo.nativePrivateClean,
   2631                         memInfo.hasSwappedOutPss ? memInfo.nativeSwappedOutPss :
   2632                         memInfo.nativeSwappedOut,
   2633                         nativeMax, nativeAllocated, nativeFree);
   2634                 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
   2635                         memInfo.dalvikPrivateDirty,
   2636                         memInfo.dalvikPrivateClean,
   2637                         memInfo.hasSwappedOutPss ? memInfo.dalvikSwappedOutPss :
   2638                         memInfo.dalvikSwappedOut,
   2639                         dalvikMax, dalvikAllocated, dalvikFree);
   2640             }
   2641 
   2642             int otherPss = memInfo.otherPss;
   2643             int otherSwappablePss = memInfo.otherSwappablePss;
   2644             int otherSharedDirty = memInfo.otherSharedDirty;
   2645             int otherPrivateDirty = memInfo.otherPrivateDirty;
   2646             int otherSharedClean = memInfo.otherSharedClean;
   2647             int otherPrivateClean = memInfo.otherPrivateClean;
   2648             int otherSwappedOut = memInfo.otherSwappedOut;
   2649             int otherSwappedOutPss = memInfo.otherSwappedOutPss;
   2650 
   2651             for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
   2652                 final int myPss = memInfo.getOtherPss(i);
   2653                 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
   2654                 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
   2655                 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
   2656                 final int mySharedClean = memInfo.getOtherSharedClean(i);
   2657                 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
   2658                 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
   2659                 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
   2660                 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
   2661                         || mySharedClean != 0 || myPrivateClean != 0
   2662                         || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
   2663                     if (dumpFullInfo) {
   2664                         printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   2665                                 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
   2666                                 mySharedClean, myPrivateClean,
   2667                                 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
   2668                                 "", "", "");
   2669                     } else {
   2670                         printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   2671                                 myPss, myPrivateDirty,
   2672                                 myPrivateClean,
   2673                                 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
   2674                                 "", "", "");
   2675                     }
   2676                     otherPss -= myPss;
   2677                     otherSwappablePss -= mySwappablePss;
   2678                     otherSharedDirty -= mySharedDirty;
   2679                     otherPrivateDirty -= myPrivateDirty;
   2680                     otherSharedClean -= mySharedClean;
   2681                     otherPrivateClean -= myPrivateClean;
   2682                     otherSwappedOut -= mySwappedOut;
   2683                     otherSwappedOutPss -= mySwappedOutPss;
   2684                 }
   2685             }
   2686 
   2687             if (dumpFullInfo) {
   2688                 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
   2689                         otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
   2690                         memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
   2691                         "", "", "");
   2692                 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
   2693                         memInfo.getTotalSwappablePss(),
   2694                         memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
   2695                         memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
   2696                         memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
   2697                         memInfo.getTotalSwappedOut(),
   2698                         nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
   2699                         nativeFree+dalvikFree);
   2700             } else {
   2701                 printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
   2702                         otherPrivateDirty, otherPrivateClean,
   2703                         memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
   2704                         "", "", "");
   2705                 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
   2706                         memInfo.getTotalPrivateDirty(),
   2707                         memInfo.getTotalPrivateClean(),
   2708                         memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
   2709                         memInfo.getTotalSwappedOut(),
   2710                         nativeMax+dalvikMax,
   2711                         nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
   2712             }
   2713 
   2714             if (dumpDalvik) {
   2715                 pw.println(" ");
   2716                 pw.println(" Dalvik Details");
   2717 
   2718                 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
   2719                      i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
   2720                     final int myPss = memInfo.getOtherPss(i);
   2721                     final int mySwappablePss = memInfo.getOtherSwappablePss(i);
   2722                     final int mySharedDirty = memInfo.getOtherSharedDirty(i);
   2723                     final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
   2724                     final int mySharedClean = memInfo.getOtherSharedClean(i);
   2725                     final int myPrivateClean = memInfo.getOtherPrivateClean(i);
   2726                     final int mySwappedOut = memInfo.getOtherSwappedOut(i);
   2727                     final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
   2728                     if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
   2729                             || mySharedClean != 0 || myPrivateClean != 0
   2730                             || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
   2731                         if (dumpFullInfo) {
   2732                             printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   2733                                     myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
   2734                                     mySharedClean, myPrivateClean,
   2735                                     memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
   2736                                     "", "", "");
   2737                         } else {
   2738                             printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
   2739                                     myPss, myPrivateDirty,
   2740                                     myPrivateClean,
   2741                                     memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
   2742                                     "", "", "");
   2743                         }
   2744                     }
   2745                 }
   2746             }
   2747         }
   2748 
   2749         pw.println(" ");
   2750         pw.println(" App Summary");
   2751         printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "Pss(KB)");
   2752         printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "------");
   2753         printRow(pw, ONE_COUNT_COLUMN,
   2754             "Java Heap:", memInfo.getSummaryJavaHeap());
   2755         printRow(pw, ONE_COUNT_COLUMN,
   2756             "Native Heap:", memInfo.getSummaryNativeHeap());
   2757         printRow(pw, ONE_COUNT_COLUMN,
   2758             "Code:", memInfo.getSummaryCode());
   2759         printRow(pw, ONE_COUNT_COLUMN,
   2760             "Stack:", memInfo.getSummaryStack());
   2761         printRow(pw, ONE_COUNT_COLUMN,
   2762             "Graphics:", memInfo.getSummaryGraphics());
   2763         printRow(pw, ONE_COUNT_COLUMN,
   2764             "Private Other:", memInfo.getSummaryPrivateOther());
   2765         printRow(pw, ONE_COUNT_COLUMN,
   2766             "System:", memInfo.getSummarySystem());
   2767         pw.println(" ");
   2768         if (memInfo.hasSwappedOutPss) {
   2769             printRow(pw, TWO_COUNT_COLUMNS,
   2770                 "TOTAL:", memInfo.getSummaryTotalPss(),
   2771                 "TOTAL SWAP PSS:", memInfo.getSummaryTotalSwapPss());
   2772         } else {
   2773             printRow(pw, TWO_COUNT_COLUMNS,
   2774                 "TOTAL:", memInfo.getSummaryTotalPss(),
   2775                 "TOTAL SWAP (KB):", memInfo.getSummaryTotalSwap());
   2776         }
   2777     }
   2778 
   2779     /**
   2780      * Dump heap info to proto.
   2781      *
   2782      * @param hasSwappedOutPss determines whether to use dirtySwap or dirtySwapPss
   2783      */
   2784     private static void dumpMemoryInfo(ProtoOutputStream proto, long fieldId, String name,
   2785             int pss, int cleanPss, int sharedDirty, int privateDirty,
   2786             int sharedClean, int privateClean,
   2787             boolean hasSwappedOutPss, int dirtySwap, int dirtySwapPss) {
   2788         final long token = proto.start(fieldId);
   2789 
   2790         proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.NAME, name);
   2791         proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.TOTAL_PSS_KB, pss);
   2792         proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.CLEAN_PSS_KB, cleanPss);
   2793         proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_DIRTY_KB, sharedDirty);
   2794         proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty);
   2795         proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.SHARED_CLEAN_KB, sharedClean);
   2796         proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.PRIVATE_CLEAN_KB, privateClean);
   2797         if (hasSwappedOutPss) {
   2798             proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss);
   2799         } else {
   2800             proto.write(MemInfoDumpProto.ProcessMemory.MemoryInfo.DIRTY_SWAP_KB, dirtySwap);
   2801         }
   2802 
   2803         proto.end(token);
   2804     }
   2805 
   2806     /**
   2807      * Dump mem info data to proto.
   2808      */
   2809     public static void dumpMemInfoTable(ProtoOutputStream proto, Debug.MemoryInfo memInfo,
   2810             boolean dumpDalvik, boolean dumpSummaryOnly,
   2811             long nativeMax, long nativeAllocated, long nativeFree,
   2812             long dalvikMax, long dalvikAllocated, long dalvikFree) {
   2813 
   2814         if (!dumpSummaryOnly) {
   2815             final long nhToken = proto.start(MemInfoDumpProto.ProcessMemory.NATIVE_HEAP);
   2816             dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Native Heap",
   2817                     memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
   2818                     memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
   2819                     memInfo.nativePrivateClean, memInfo.hasSwappedOutPss,
   2820                     memInfo.nativeSwappedOut, memInfo.nativeSwappedOutPss);
   2821             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, nativeMax);
   2822             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, nativeAllocated);
   2823             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, nativeFree);
   2824             proto.end(nhToken);
   2825 
   2826             final long dvToken = proto.start(MemInfoDumpProto.ProcessMemory.DALVIK_HEAP);
   2827             dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "Dalvik Heap",
   2828                     memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
   2829                     memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
   2830                     memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss,
   2831                     memInfo.dalvikSwappedOut, memInfo.dalvikSwappedOutPss);
   2832             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB, dalvikMax);
   2833             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated);
   2834             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB, dalvikFree);
   2835             proto.end(dvToken);
   2836 
   2837             int otherPss = memInfo.otherPss;
   2838             int otherSwappablePss = memInfo.otherSwappablePss;
   2839             int otherSharedDirty = memInfo.otherSharedDirty;
   2840             int otherPrivateDirty = memInfo.otherPrivateDirty;
   2841             int otherSharedClean = memInfo.otherSharedClean;
   2842             int otherPrivateClean = memInfo.otherPrivateClean;
   2843             int otherSwappedOut = memInfo.otherSwappedOut;
   2844             int otherSwappedOutPss = memInfo.otherSwappedOutPss;
   2845 
   2846             for (int i = 0; i < Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
   2847                 final int myPss = memInfo.getOtherPss(i);
   2848                 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
   2849                 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
   2850                 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
   2851                 final int mySharedClean = memInfo.getOtherSharedClean(i);
   2852                 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
   2853                 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
   2854                 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
   2855                 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
   2856                         || mySharedClean != 0 || myPrivateClean != 0
   2857                         || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
   2858                     dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.OTHER_HEAPS,
   2859                             Debug.MemoryInfo.getOtherLabel(i),
   2860                             myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
   2861                             mySharedClean, myPrivateClean,
   2862                             memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss);
   2863 
   2864                     otherPss -= myPss;
   2865                     otherSwappablePss -= mySwappablePss;
   2866                     otherSharedDirty -= mySharedDirty;
   2867                     otherPrivateDirty -= myPrivateDirty;
   2868                     otherSharedClean -= mySharedClean;
   2869                     otherPrivateClean -= myPrivateClean;
   2870                     otherSwappedOut -= mySwappedOut;
   2871                     otherSwappedOutPss -= mySwappedOutPss;
   2872                 }
   2873             }
   2874 
   2875             dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.UNKNOWN_HEAP, "Unknown",
   2876                     otherPss, otherSwappablePss,
   2877                     otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
   2878                     memInfo.hasSwappedOutPss, otherSwappedOut, otherSwappedOutPss);
   2879             final long tToken = proto.start(MemInfoDumpProto.ProcessMemory.TOTAL_HEAP);
   2880             dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.HeapInfo.MEM_INFO, "TOTAL",
   2881                     memInfo.getTotalPss(), memInfo.getTotalSwappablePss(),
   2882                     memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
   2883                     memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
   2884                     memInfo.hasSwappedOutPss, memInfo.getTotalSwappedOut(),
   2885                     memInfo.getTotalSwappedOutPss());
   2886             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_SIZE_KB,
   2887                     nativeMax + dalvikMax);
   2888             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_ALLOC_KB,
   2889                     nativeAllocated + dalvikAllocated);
   2890             proto.write(MemInfoDumpProto.ProcessMemory.HeapInfo.HEAP_FREE_KB,
   2891                     nativeFree + dalvikFree);
   2892             proto.end(tToken);
   2893 
   2894             if (dumpDalvik) {
   2895                 for (int i = Debug.MemoryInfo.NUM_OTHER_STATS;
   2896                         i < Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS;
   2897                         i++) {
   2898                     final int myPss = memInfo.getOtherPss(i);
   2899                     final int mySwappablePss = memInfo.getOtherSwappablePss(i);
   2900                     final int mySharedDirty = memInfo.getOtherSharedDirty(i);
   2901                     final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
   2902                     final int mySharedClean = memInfo.getOtherSharedClean(i);
   2903                     final int myPrivateClean = memInfo.getOtherPrivateClean(i);
   2904                     final int mySwappedOut = memInfo.getOtherSwappedOut(i);
   2905                     final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
   2906                     if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
   2907                             || mySharedClean != 0 || myPrivateClean != 0
   2908                             || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
   2909                         dumpMemoryInfo(proto, MemInfoDumpProto.ProcessMemory.DALVIK_DETAILS,
   2910                                 Debug.MemoryInfo.getOtherLabel(i),
   2911                                 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
   2912                                 mySharedClean, myPrivateClean,
   2913                                 memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss);
   2914                     }
   2915                 }
   2916             }
   2917         }
   2918 
   2919         final long asToken = proto.start(MemInfoDumpProto.ProcessMemory.APP_SUMMARY);
   2920         proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.JAVA_HEAP_PSS_KB,
   2921                 memInfo.getSummaryJavaHeap());
   2922         proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.NATIVE_HEAP_PSS_KB,
   2923                 memInfo.getSummaryNativeHeap());
   2924         proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.CODE_PSS_KB,
   2925                 memInfo.getSummaryCode());
   2926         proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.STACK_PSS_KB,
   2927                 memInfo.getSummaryStack());
   2928         proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.GRAPHICS_PSS_KB,
   2929                 memInfo.getSummaryGraphics());
   2930         proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.PRIVATE_OTHER_PSS_KB,
   2931                 memInfo.getSummaryPrivateOther());
   2932         proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.SYSTEM_PSS_KB,
   2933                 memInfo.getSummarySystem());
   2934         if (memInfo.hasSwappedOutPss) {
   2935             proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
   2936                     memInfo.getSummaryTotalSwapPss());
   2937         } else {
   2938             proto.write(MemInfoDumpProto.ProcessMemory.AppSummary.TOTAL_SWAP_PSS,
   2939                     memInfo.getSummaryTotalSwap());
   2940         }
   2941         proto.end(asToken);
   2942     }
   2943 
   2944     @UnsupportedAppUsage
   2945     public void registerOnActivityPausedListener(Activity activity,
   2946             OnActivityPausedListener listener) {
   2947         synchronized (mOnPauseListeners) {
   2948             ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
   2949             if (list == null) {
   2950                 list = new ArrayList<OnActivityPausedListener>();
   2951                 mOnPauseListeners.put(activity, list);
   2952             }
   2953             list.add(listener);
   2954         }
   2955     }
   2956 
   2957     @UnsupportedAppUsage
   2958     public void unregisterOnActivityPausedListener(Activity activity,
   2959             OnActivityPausedListener listener) {
   2960         synchronized (mOnPauseListeners) {
   2961             ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
   2962             if (list != null) {
   2963                 list.remove(listener);
   2964             }
   2965         }
   2966     }
   2967 
   2968     public final ActivityInfo resolveActivityInfo(Intent intent) {
   2969         ActivityInfo aInfo = intent.resolveActivityInfo(
   2970                 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
   2971         if (aInfo == null) {
   2972             // Throw an exception.
   2973             Instrumentation.checkStartActivityResult(
   2974                     ActivityManager.START_CLASS_NOT_FOUND, intent);
   2975         }
   2976         return aInfo;
   2977     }
   2978 
   2979     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
   2980     public final Activity startActivityNow(Activity parent, String id,
   2981         Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
   2982         Activity.NonConfigurationInstances lastNonConfigurationInstances, IBinder assistToken) {
   2983         ActivityClientRecord r = new ActivityClientRecord();
   2984             r.token = token;
   2985             r.assistToken = assistToken;
   2986             r.ident = 0;
   2987             r.intent = intent;
   2988             r.state = state;
   2989             r.parent = parent;
   2990             r.embeddedID = id;
   2991             r.activityInfo = activityInfo;
   2992             r.lastNonConfigurationInstances = lastNonConfigurationInstances;
   2993         if (localLOGV) {
   2994             ComponentName compname = intent.getComponent();
   2995             String name;
   2996             if (compname != null) {
   2997                 name = compname.toShortString();
   2998             } else {
   2999                 name = "(Intent " + intent + ").getComponent() returned null";
   3000             }
   3001             Slog.v(TAG, "Performing launch: action=" + intent.getAction()
   3002                     + ", comp=" + name
   3003                     + ", token=" + token);
   3004         }
   3005         // TODO(lifecycler): Can't switch to use #handleLaunchActivity() because it will try to
   3006         // call #reportSizeConfigurations(), but the server might not know anything about the
   3007         // activity if it was launched from LocalAcvitivyManager.
   3008         return performLaunchActivity(r, null /* customIntent */);
   3009     }
   3010 
   3011     @UnsupportedAppUsage
   3012     public final Activity getActivity(IBinder token) {
   3013         final ActivityClientRecord activityRecord = mActivities.get(token);
   3014         return activityRecord != null ? activityRecord.activity : null;
   3015     }
   3016 
   3017     @Override
   3018     public ActivityClientRecord getActivityClient(IBinder token) {
   3019         return mActivities.get(token);
   3020     }
   3021 
   3022     @Override
   3023     public void updatePendingConfiguration(Configuration config) {
   3024         synchronized (mResourcesManager) {
   3025             if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(config)) {
   3026                 mPendingConfiguration = config;
   3027             }
   3028         }
   3029     }
   3030 
   3031     @Override
   3032     public void updateProcessState(int processState, boolean fromIpc) {
   3033         synchronized (mAppThread) {
   3034             if (mLastProcessState == processState) {
   3035                 return;
   3036             }
   3037             mLastProcessState = processState;
   3038             // Defer the top state for VM to avoid aggressive JIT compilation affecting activity
   3039             // launch time.
   3040             if (processState == ActivityManager.PROCESS_STATE_TOP
   3041                     && mNumLaunchingActivities.get() > 0) {
   3042                 mPendingProcessState = processState;
   3043                 mH.postDelayed(this::applyPendingProcessState, PENDING_TOP_PROCESS_STATE_TIMEOUT);
   3044             } else {
   3045                 mPendingProcessState = PROCESS_STATE_UNKNOWN;
   3046                 updateVmProcessState(processState);
   3047             }
   3048             if (localLOGV) {
   3049                 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
   3050                         + (fromIpc ? " (from ipc" : ""));
   3051             }
   3052         }
   3053     }
   3054 
   3055     /** Update VM state based on ActivityManager.PROCESS_STATE_* constants. */
   3056     private void updateVmProcessState(int processState) {
   3057         // TODO: Tune this since things like gmail sync are important background but not jank
   3058         // perceptible.
   3059         final int state = processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
   3060                 ? VM_PROCESS_STATE_JANK_PERCEPTIBLE
   3061                 : VM_PROCESS_STATE_JANK_IMPERCEPTIBLE;
   3062         VMRuntime.getRuntime().updateProcessState(state);
   3063     }
   3064 
   3065     private void applyPendingProcessState() {
   3066         synchronized (mAppThread) {
   3067             if (mPendingProcessState == PROCESS_STATE_UNKNOWN) {
   3068                 return;
   3069             }
   3070             final int pendingState = mPendingProcessState;
   3071             mPendingProcessState = PROCESS_STATE_UNKNOWN;
   3072             // Only apply the pending state if the last state doesn't change.
   3073             if (pendingState == mLastProcessState) {
   3074                 updateVmProcessState(pendingState);
   3075             }
   3076         }
   3077     }
   3078 
   3079     @Override
   3080     public void countLaunchingActivities(int num) {
   3081         mNumLaunchingActivities.getAndAdd(num);
   3082     }
   3083 
   3084     @UnsupportedAppUsage
   3085     public final void sendActivityResult(
   3086             IBinder token, String id, int requestCode,
   3087             int resultCode, Intent data) {
   3088         if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
   3089                 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
   3090         ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
   3091         list.add(new ResultInfo(id, requestCode, resultCode, data));
   3092         final ClientTransaction clientTransaction = ClientTransaction.obtain(mAppThread, token);
   3093         clientTransaction.addCallback(ActivityResultItem.obtain(list));
   3094         try {
   3095             mAppThread.scheduleTransaction(clientTransaction);
   3096         } catch (RemoteException e) {
   3097             // Local scheduling
   3098         }
   3099     }
   3100 
   3101     @Override
   3102     TransactionExecutor getTransactionExecutor() {
   3103         return mTransactionExecutor;
   3104     }
   3105 
   3106     void sendMessage(int what, Object obj) {
   3107         sendMessage(what, obj, 0, 0, false);
   3108     }
   3109 
   3110     private void sendMessage(int what, Object obj, int arg1) {
   3111         sendMessage(what, obj, arg1, 0, false);
   3112     }
   3113 
   3114     private void sendMessage(int what, Object obj, int arg1, int arg2) {
   3115         sendMessage(what, obj, arg1, arg2, false);
   3116     }
   3117 
   3118     private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
   3119         if (DEBUG_MESSAGES) {
   3120             Slog.v(TAG,
   3121                     "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
   3122         }
   3123         Message msg = Message.obtain();
   3124         msg.what = what;
   3125         msg.obj = obj;
   3126         msg.arg1 = arg1;
   3127         msg.arg2 = arg2;
   3128         if (async) {
   3129             msg.setAsynchronous(true);
   3130         }
   3131         mH.sendMessage(msg);
   3132     }
   3133 
   3134     private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
   3135         if (DEBUG_MESSAGES) Slog.v(
   3136                 TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
   3137                         "seq= " + seq);
   3138         Message msg = Message.obtain();
   3139         msg.what = what;
   3140         SomeArgs args = SomeArgs.obtain();
   3141         args.arg1 = obj;
   3142         args.argi1 = arg1;
   3143         args.argi2 = arg2;
   3144         args.argi3 = seq;
   3145         msg.obj = args;
   3146         mH.sendMessage(msg);
   3147     }
   3148 
   3149     final void scheduleContextCleanup(ContextImpl context, String who,
   3150             String what) {
   3151         ContextCleanupInfo cci = new ContextCleanupInfo();
   3152         cci.context = context;
   3153         cci.who = who;
   3154         cci.what = what;
   3155         sendMessage(H.CLEAN_UP_CONTEXT, cci);
   3156     }
   3157 
   3158     /**  Core implementation of activity launch. */
   3159     private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
   3160         ActivityInfo aInfo = r.activityInfo;
   3161         if (r.packageInfo == null) {
   3162             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
   3163                     Context.CONTEXT_INCLUDE_CODE);
   3164         }
   3165 
   3166         ComponentName component = r.intent.getComponent();
   3167         if (component == null) {
   3168             component = r.intent.resolveActivity(
   3169                 mInitialApplication.getPackageManager());
   3170             r.intent.setComponent(component);
   3171         }
   3172 
   3173         if (r.activityInfo.targetActivity != null) {
   3174             component = new ComponentName(r.activityInfo.packageName,
   3175                     r.activityInfo.targetActivity);
   3176         }
   3177 
   3178         ContextImpl appContext = createBaseContextForActivity(r);
   3179         Activity activity = null;
   3180         try {
   3181             java.lang.ClassLoader cl = appContext.getClassLoader();
   3182             activity = mInstrumentation.newActivity(
   3183                     cl, component.getClassName(), r.intent);
   3184             StrictMode.incrementExpectedActivityCount(activity.getClass());
   3185             r.intent.setExtrasClassLoader(cl);
   3186             r.intent.prepareToEnterProcess();
   3187             if (r.state != null) {
   3188                 r.state.setClassLoader(cl);
   3189             }
   3190         } catch (Exception e) {
   3191             if (!mInstrumentation.onException(activity, e)) {
   3192                 throw new RuntimeException(
   3193                     "Unable to instantiate activity " + component
   3194                     + ": " + e.toString(), e);
   3195             }
   3196         }
   3197 
   3198         try {
   3199             Application app = r.packageInfo.makeApplication(false, mInstrumentation);
   3200 
   3201             if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
   3202             if (localLOGV) Slog.v(
   3203                     TAG, r + ": app=" + app
   3204                     + ", appName=" + app.getPackageName()
   3205                     + ", pkg=" + r.packageInfo.getPackageName()
   3206                     + ", comp=" + r.intent.getComponent().toShortString()
   3207                     + ", dir=" + r.packageInfo.getAppDir());
   3208 
   3209             if (activity != null) {
   3210                 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
   3211                 Configuration config = new Configuration(mCompatConfiguration);
   3212                 if (r.overrideConfig != null) {
   3213                     config.updateFrom(r.overrideConfig);
   3214                 }
   3215                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
   3216                         + r.activityInfo.name + " with config " + config);
   3217                 Window window = null;
   3218                 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
   3219                     window = r.mPendingRemoveWindow;
   3220                     r.mPendingRemoveWindow = null;
   3221                     r.mPendingRemoveWindowManager = null;
   3222                 }
   3223                 appContext.setOuterContext(activity);
   3224                 activity.attach(appContext, this, getInstrumentation(), r.token,
   3225                         r.ident, app, r.intent, r.activityInfo, title, r.parent,
   3226                         r.embeddedID, r.lastNonConfigurationInstances, config,
   3227                         r.referrer, r.voiceInteractor, window, r.configCallback,
   3228                         r.assistToken);
   3229 
   3230                 if (customIntent != null) {
   3231                     activity.mIntent = customIntent;
   3232                 }
   3233                 r.lastNonConfigurationInstances = null;
   3234                 checkAndBlockForNetworkAccess();
   3235                 activity.mStartedActivity = false;
   3236                 int theme = r.activityInfo.getThemeResource();
   3237                 if (theme != 0) {
   3238                     activity.setTheme(theme);
   3239                 }
   3240 
   3241                 activity.mCalled = false;
   3242                 if (r.isPersistable()) {
   3243                     mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
   3244                 } else {
   3245                     mInstrumentation.callActivityOnCreate(activity, r.state);
   3246                 }
   3247                 if (!activity.mCalled) {
   3248                     throw new SuperNotCalledException(
   3249                         "Activity " + r.intent.getComponent().toShortString() +
   3250                         " did not call through to super.onCreate()");
   3251                 }
   3252                 r.activity = activity;
   3253             }
   3254             r.setState(ON_CREATE);
   3255 
   3256             // updatePendingActivityConfiguration() reads from mActivities to update
   3257             // ActivityClientRecord which runs in a different thread. Protect modifications to
   3258             // mActivities to avoid race.
   3259             synchronized (mResourcesManager) {
   3260                 mActivities.put(r.token, r);
   3261             }
   3262 
   3263         } catch (SuperNotCalledException e) {
   3264             throw e;
   3265 
   3266         } catch (Exception e) {
   3267             if (!mInstrumentation.onException(activity, e)) {
   3268                 throw new RuntimeException(
   3269                     "Unable to start activity " + component
   3270                     + ": " + e.toString(), e);
   3271             }
   3272         }
   3273 
   3274         return activity;
   3275     }
   3276 
   3277     @Override
   3278     public void handleStartActivity(ActivityClientRecord r,
   3279             PendingTransactionActions pendingActions) {
   3280         final Activity activity = r.activity;
   3281         if (r.activity == null) {
   3282             // TODO(lifecycler): What do we do in this case?
   3283             return;
   3284         }
   3285         if (!r.stopped) {
   3286             throw new IllegalStateException("Can't start activity that is not stopped.");
   3287         }
   3288         if (r.activity.mFinished) {
   3289             // TODO(lifecycler): How can this happen?
   3290             return;
   3291         }
   3292 
   3293         // Start
   3294         activity.performStart("handleStartActivity");
   3295         r.setState(ON_START);
   3296 
   3297         if (pendingActions == null) {
   3298             // No more work to do.
   3299             return;
   3300         }
   3301 
   3302         // Restore instance state
   3303         if (pendingActions.shouldRestoreInstanceState()) {
   3304             if (r.isPersistable()) {
   3305                 if (r.state != null || r.persistentState != null) {
   3306                     mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
   3307                             r.persistentState);
   3308                 }
   3309             } else if (r.state != null) {
   3310                 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
   3311             }
   3312         }
   3313 
   3314         // Call postOnCreate()
   3315         if (pendingActions.shouldCallOnPostCreate()) {
   3316             activity.mCalled = false;
   3317             if (r.isPersistable()) {
   3318                 mInstrumentation.callActivityOnPostCreate(activity, r.state,
   3319                         r.persistentState);
   3320             } else {
   3321                 mInstrumentation.callActivityOnPostCreate(activity, r.state);
   3322             }
   3323             if (!activity.mCalled) {
   3324                 throw new SuperNotCalledException(
   3325                         "Activity " + r.intent.getComponent().toShortString()
   3326                                 + " did not call through to super.onPostCreate()");
   3327             }
   3328         }
   3329     }
   3330 
   3331     /**
   3332      * Checks if {@link #mNetworkBlockSeq} is {@link #INVALID_PROC_STATE_SEQ} and if so, returns
   3333      * immediately. Otherwise, makes a blocking call to ActivityManagerService to wait for the
   3334      * network rules to get updated.
   3335      */
   3336     private void checkAndBlockForNetworkAccess() {
   3337         synchronized (mNetworkPolicyLock) {
   3338             if (mNetworkBlockSeq != INVALID_PROC_STATE_SEQ) {
   3339                 try {
   3340                     ActivityManager.getService().waitForNetworkStateUpdate(mNetworkBlockSeq);
   3341                     mNetworkBlockSeq = INVALID_PROC_STATE_SEQ;
   3342                 } catch (RemoteException ignored) {}
   3343             }
   3344         }
   3345     }
   3346 
   3347     private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
   3348         final int displayId;
   3349         try {
   3350             displayId = ActivityTaskManager.getService().getActivityDisplayId(r.token);
   3351         } catch (RemoteException e) {
   3352             throw e.rethrowFromSystemServer();
   3353         }
   3354 
   3355         ContextImpl appContext = ContextImpl.createActivityContext(
   3356                 this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
   3357 
   3358         final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
   3359         // For debugging purposes, if the activity's package name contains the value of
   3360         // the "debug.use-second-display" system property as a substring, then show
   3361         // its content on a secondary display if there is one.
   3362         String pkgName = SystemProperties.get("debug.second-display.pkg");
   3363         if (pkgName != null && !pkgName.isEmpty()
   3364                 && r.packageInfo.mPackageName.contains(pkgName)) {
   3365             for (int id : dm.getDisplayIds()) {
   3366                 if (id != Display.DEFAULT_DISPLAY) {
   3367                     Display display =
   3368                             dm.getCompatibleDisplay(id, appContext.getResources());
   3369                     appContext = (ContextImpl) appContext.createDisplayContext(display);
   3370                     break;
   3371                 }
   3372             }
   3373         }
   3374         return appContext;
   3375     }
   3376 
   3377     /**
   3378      * Extended implementation of activity launch. Used when server requests a launch or relaunch.
   3379      */
   3380     @Override
   3381     public Activity handleLaunchActivity(ActivityClientRecord r,
   3382             PendingTransactionActions pendingActions, Intent customIntent) {
   3383         // If we are getting ready to gc after going to the background, well
   3384         // we are back active so skip it.
   3385         unscheduleGcIdler();
   3386         mSomeActivitiesChanged = true;
   3387 
   3388         if (r.profilerInfo != null) {
   3389             mProfiler.setProfiler(r.profilerInfo);
   3390             mProfiler.startProfiling();
   3391         }
   3392 
   3393         // Make sure we are running with the most recent config.
   3394         handleConfigurationChanged(null, null);
   3395 
   3396         if (localLOGV) Slog.v(
   3397             TAG, "Handling launch of " + r);
   3398 
   3399         // Initialize before creating the activity
   3400         if (!ThreadedRenderer.sRendererDisabled
   3401                 && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
   3402             HardwareRenderer.preload();
   3403         }
   3404         WindowManagerGlobal.initialize();
   3405 
   3406         // Hint the GraphicsEnvironment that an activity is launching on the process.
   3407         GraphicsEnvironment.hintActivityLaunch();
   3408 
   3409         final Activity a = performLaunchActivity(r, customIntent);
   3410 
   3411         if (a != null) {
   3412             r.createdConfig = new Configuration(mConfiguration);
   3413             reportSizeConfigurations(r);
   3414             if (!r.activity.mFinished && pendingActions != null) {
   3415                 pendingActions.setOldState(r.state);
   3416                 pendingActions.setRestoreInstanceState(true);
   3417                 pendingActions.setCallOnPostCreate(true);
   3418             }
   3419         } else {
   3420             // If there was an error, for any reason, tell the activity manager to stop us.
   3421             try {
   3422                 ActivityTaskManager.getService()
   3423                         .finishActivity(r.token, Activity.RESULT_CANCELED, null,
   3424                                 Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
   3425             } catch (RemoteException ex) {
   3426                 throw ex.rethrowFromSystemServer();
   3427             }
   3428         }
   3429 
   3430         return a;
   3431     }
   3432 
   3433     private void reportSizeConfigurations(ActivityClientRecord r) {
   3434         if (mActivitiesToBeDestroyed.containsKey(r.token)) {
   3435             // Size configurations of a destroyed activity is meaningless.
   3436             return;
   3437         }
   3438         Configuration[] configurations = r.activity.getResources().getSizeConfigurations();
   3439         if (configurations == null) {
   3440             return;
   3441         }
   3442         SparseIntArray horizontal = new SparseIntArray();
   3443         SparseIntArray vertical = new SparseIntArray();
   3444         SparseIntArray smallest = new SparseIntArray();
   3445         for (int i = configurations.length - 1; i >= 0; i--) {
   3446             Configuration config = configurations[i];
   3447             if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
   3448                 vertical.put(config.screenHeightDp, 0);
   3449             }
   3450             if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
   3451                 horizontal.put(config.screenWidthDp, 0);
   3452             }
   3453             if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
   3454                 smallest.put(config.smallestScreenWidthDp, 0);
   3455             }
   3456         }
   3457         try {
   3458             ActivityTaskManager.getService().reportSizeConfigurations(r.token,
   3459                     horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
   3460         } catch (RemoteException ex) {
   3461             throw ex.rethrowFromSystemServer();
   3462         }
   3463     }
   3464 
   3465     private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
   3466         final int N = intents.size();
   3467         for (int i=0; i<N; i++) {
   3468             ReferrerIntent intent = intents.get(i);
   3469             intent.setExtrasClassLoader(r.activity.getClassLoader());
   3470             intent.prepareToEnterProcess();
   3471             r.activity.mFragments.noteStateNotSaved();
   3472             mInstrumentation.callActivityOnNewIntent(r.activity, intent);
   3473         }
   3474     }
   3475 
   3476     @Override
   3477     public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) {
   3478         final ActivityClientRecord r = mActivities.get(token);
   3479         if (r == null) {
   3480             return;
   3481         }
   3482 
   3483         checkAndBlockForNetworkAccess();
   3484         deliverNewIntents(r, intents);
   3485     }
   3486 
   3487     public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
   3488         // Filling for autofill has a few differences:
   3489         // - it does not need an AssistContent
   3490         // - it does not call onProvideAssistData()
   3491         // - it needs an IAutoFillCallback
   3492         boolean forAutofill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTOFILL;
   3493 
   3494         // TODO: decide if lastSessionId logic applies to autofill sessions
   3495         if (mLastSessionId != cmd.sessionId) {
   3496             // Clear the existing structures
   3497             mLastSessionId = cmd.sessionId;
   3498             for (int i = mLastAssistStructures.size() - 1; i >= 0; i--) {
   3499                 AssistStructure structure = mLastAssistStructures.get(i).get();
   3500                 if (structure != null) {
   3501                     structure.clearSendChannel();
   3502                 }
   3503                 mLastAssistStructures.remove(i);
   3504             }
   3505         }
   3506 
   3507         Bundle data = new Bundle();
   3508         AssistStructure structure = null;
   3509         AssistContent content = forAutofill ? null : new AssistContent();
   3510         final long startTime = SystemClock.uptimeMillis();
   3511         ActivityClientRecord r = mActivities.get(cmd.activityToken);
   3512         Uri referrer = null;
   3513         if (r != null) {
   3514             if (!forAutofill) {
   3515                 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
   3516                 r.activity.onProvideAssistData(data);
   3517                 referrer = r.activity.onProvideReferrer();
   3518             }
   3519             if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutofill) {
   3520                 structure = new AssistStructure(r.activity, forAutofill, cmd.flags);
   3521                 Intent activityIntent = r.activity.getIntent();
   3522                 boolean notSecure = r.window == null ||
   3523                         (r.window.getAttributes().flags
   3524                                 & WindowManager.LayoutParams.FLAG_SECURE) == 0;
   3525                 if (activityIntent != null && notSecure) {
   3526                     if (!forAutofill) {
   3527                         Intent intent = new Intent(activityIntent);
   3528                         intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
   3529                                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
   3530                         intent.removeUnsafeExtras();
   3531                         content.setDefaultIntent(intent);
   3532                     }
   3533                 } else {
   3534                     if (!forAutofill) {
   3535                         content.setDefaultIntent(new Intent());
   3536                     }
   3537                 }
   3538                 if (!forAutofill) {
   3539                     r.activity.onProvideAssistContent(content);
   3540                 }
   3541             }
   3542 
   3543         }
   3544         if (structure == null) {
   3545             structure = new AssistStructure();
   3546         }
   3547 
   3548         // TODO: decide if lastSessionId logic applies to autofill sessions
   3549 
   3550         structure.setAcquisitionStartTime(startTime);
   3551         structure.setAcquisitionEndTime(SystemClock.uptimeMillis());
   3552 
   3553         mLastAssistStructures.add(new WeakReference<>(structure));
   3554         IActivityTaskManager mgr = ActivityTaskManager.getService();
   3555         try {
   3556             mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
   3557         } catch (RemoteException e) {
   3558             throw e.rethrowFromSystemServer();
   3559         }
   3560     }
   3561 
   3562     /** Fetches the user actions for the corresponding activity */
   3563     private void handleRequestDirectActions(@NonNull IBinder activityToken,
   3564             @NonNull IVoiceInteractor interactor, @NonNull CancellationSignal cancellationSignal,
   3565             @NonNull RemoteCallback callback) {
   3566         final ActivityClientRecord r = mActivities.get(activityToken);
   3567         if (r == null) {
   3568             Log.w(TAG, "requestDirectActions(): no activity for " + activityToken);
   3569             callback.sendResult(null);
   3570             return;
   3571         }
   3572         final int lifecycleState = r.getLifecycleState();
   3573         if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
   3574             Log.w(TAG, "requestDirectActions(" + r + "): wrong lifecycle: " + lifecycleState);
   3575             callback.sendResult(null);
   3576             return;
   3577         }
   3578         if (r.activity.mVoiceInteractor == null
   3579                 || r.activity.mVoiceInteractor.mInteractor.asBinder()
   3580                 != interactor.asBinder()) {
   3581             if (r.activity.mVoiceInteractor != null) {
   3582                 r.activity.mVoiceInteractor.destroy();
   3583             }
   3584             r.activity.mVoiceInteractor = new VoiceInteractor(interactor, r.activity,
   3585                     r.activity, Looper.myLooper());
   3586         }
   3587         r.activity.onGetDirectActions(cancellationSignal, (actions) -> {
   3588             Preconditions.checkNotNull(actions);
   3589             Preconditions.checkCollectionElementsNotNull(actions, "actions");
   3590             if (!actions.isEmpty()) {
   3591                 final int actionCount = actions.size();
   3592                 for (int i = 0; i < actionCount; i++) {
   3593                     final DirectAction action = actions.get(i);
   3594                     action.setSource(r.activity.getTaskId(), r.activity.getAssistToken());
   3595                 }
   3596                 final Bundle result = new Bundle();
   3597                 result.putParcelable(DirectAction.KEY_ACTIONS_LIST,
   3598                         new ParceledListSlice<>(actions));
   3599                 callback.sendResult(result);
   3600             } else {
   3601                 callback.sendResult(null);
   3602             }
   3603         });
   3604     }
   3605 
   3606     /** Performs an actions in the corresponding activity */
   3607     private void handlePerformDirectAction(@NonNull IBinder activityToken,
   3608             @NonNull String actionId, @Nullable Bundle arguments,
   3609             @NonNull CancellationSignal cancellationSignal,
   3610             @NonNull RemoteCallback resultCallback) {
   3611         final ActivityClientRecord r = mActivities.get(activityToken);
   3612         if (r != null) {
   3613             final int lifecycleState = r.getLifecycleState();
   3614             if (lifecycleState < ON_START || lifecycleState >= ON_STOP) {
   3615                 resultCallback.sendResult(null);
   3616                 return;
   3617             }
   3618             final Bundle nonNullArguments = (arguments != null) ? arguments : Bundle.EMPTY;
   3619             r.activity.onPerformDirectAction(actionId, nonNullArguments, cancellationSignal,
   3620                     resultCallback::sendResult);
   3621         } else {
   3622             resultCallback.sendResult(null);
   3623         }
   3624     }
   3625 
   3626     public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
   3627         ActivityClientRecord r = mActivities.get(token);
   3628         if (r != null) {
   3629             r.activity.onTranslucentConversionComplete(drawComplete);
   3630         }
   3631     }
   3632 
   3633     public void onNewActivityOptions(IBinder token, ActivityOptions options) {
   3634         ActivityClientRecord r = mActivities.get(token);
   3635         if (r != null) {
   3636             r.activity.onNewActivityOptions(options);
   3637         }
   3638     }
   3639 
   3640     public void handleInstallProvider(ProviderInfo info) {
   3641         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   3642         try {
   3643             installContentProviders(mInitialApplication, Arrays.asList(info));
   3644         } finally {
   3645             StrictMode.setThreadPolicy(oldPolicy);
   3646         }
   3647     }
   3648 
   3649     private void handleEnterAnimationComplete(IBinder token) {
   3650         ActivityClientRecord r = mActivities.get(token);
   3651         if (r != null) {
   3652             r.activity.dispatchEnterAnimationComplete();
   3653         }
   3654     }
   3655 
   3656     private void handleStartBinderTracking() {
   3657         Binder.enableTracing();
   3658     }
   3659 
   3660     private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) {
   3661         try {
   3662             Binder.disableTracing();
   3663             Binder.getTransactionTracker().writeTracesToFile(fd);
   3664         } finally {
   3665             IoUtils.closeQuietly(fd);
   3666             Binder.getTransactionTracker().clearTraces();
   3667         }
   3668     }
   3669 
   3670     @Override
   3671     public void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
   3672             Configuration overrideConfig) {
   3673         final ActivityClientRecord r = mActivities.get(token);
   3674         if (r != null) {
   3675             final Configuration newConfig = new Configuration(mConfiguration);
   3676             if (overrideConfig != null) {
   3677                 newConfig.updateFrom(overrideConfig);
   3678             }
   3679             r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
   3680         }
   3681     }
   3682 
   3683     @Override
   3684     public void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode,
   3685             Configuration overrideConfig) {
   3686         final ActivityClientRecord r = mActivities.get(token);
   3687         if (r != null) {
   3688             final Configuration newConfig = new Configuration(mConfiguration);
   3689             if (overrideConfig != null) {
   3690                 newConfig.updateFrom(overrideConfig);
   3691             }
   3692             r.activity.dispatchPictureInPictureModeChanged(isInPipMode, newConfig);
   3693         }
   3694     }
   3695 
   3696     private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) {
   3697         final ActivityClientRecord r = mActivities.get(token);
   3698         if (r != null) {
   3699             r.voiceInteractor = interactor;
   3700             r.activity.setVoiceInteractor(interactor);
   3701             if (interactor == null) {
   3702                 r.activity.onLocalVoiceInteractionStopped();
   3703             } else {
   3704                 r.activity.onLocalVoiceInteractionStarted();
   3705             }
   3706         }
   3707     }
   3708 
   3709     private static boolean attemptAttachAgent(String agent, ClassLoader classLoader) {
   3710         try {
   3711             VMDebug.attachAgent(agent, classLoader);
   3712             return true;
   3713         } catch (IOException e) {
   3714             Slog.e(TAG, "Attaching agent with " + classLoader + " failed: " + agent);
   3715             return false;
   3716         }
   3717     }
   3718 
   3719     static void handleAttachAgent(String agent, LoadedApk loadedApk) {
   3720         ClassLoader classLoader = loadedApk != null ? loadedApk.getClassLoader() : null;
   3721         if (attemptAttachAgent(agent, classLoader)) {
   3722             return;
   3723         }
   3724         if (classLoader != null) {
   3725             attemptAttachAgent(agent, null);
   3726         }
   3727     }
   3728 
   3729     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
   3730 
   3731     /**
   3732      * Return the Intent that's currently being handled by a
   3733      * BroadcastReceiver on this thread, or null if none.
   3734      * @hide
   3735      */
   3736     public static Intent getIntentBeingBroadcast() {
   3737         return sCurrentBroadcastIntent.get();
   3738     }
   3739 
   3740     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
   3741     private void handleReceiver(ReceiverData data) {
   3742         // If we are getting ready to gc after going to the background, well
   3743         // we are back active so skip it.
   3744         unscheduleGcIdler();
   3745 
   3746         String component = data.intent.getComponent().getClassName();
   3747 
   3748         LoadedApk packageInfo = getPackageInfoNoCheck(
   3749                 data.info.applicationInfo, data.compatInfo);
   3750 
   3751         IActivityManager mgr = ActivityManager.getService();
   3752 
   3753         Application app;
   3754         BroadcastReceiver receiver;
   3755         ContextImpl context;
   3756         try {
   3757             app = packageInfo.makeApplication(false, mInstrumentation);
   3758             context = (ContextImpl) app.getBaseContext();
   3759             if (data.info.splitName != null) {
   3760                 context = (ContextImpl) context.createContextForSplit(data.info.splitName);
   3761             }
   3762             java.lang.ClassLoader cl = context.getClassLoader();
   3763             data.intent.setExtrasClassLoader(cl);
   3764             data.intent.prepareToEnterProcess();
   3765             data.setExtrasClassLoader(cl);
   3766             receiver = packageInfo.getAppFactory()
   3767                     .instantiateReceiver(cl, data.info.name, data.intent);
   3768         } catch (Exception e) {
   3769             if (DEBUG_BROADCAST) Slog.i(TAG,
   3770                     "Finishing failed broadcast to " + data.intent.getComponent());
   3771             data.sendFinished(mgr);
   3772             throw new RuntimeException(
   3773                 "Unable to instantiate receiver " + component
   3774                 + ": " + e.toString(), e);
   3775         }
   3776 
   3777         try {
   3778             if (localLOGV) Slog.v(
   3779                 TAG, "Performing receive of " + data.intent
   3780                 + ": app=" + app
   3781                 + ", appName=" + app.getPackageName()
   3782                 + ", pkg=" + packageInfo.getPackageName()
   3783                 + ", comp=" + data.intent.getComponent().toShortString()
   3784                 + ", dir=" + packageInfo.getAppDir());
   3785 
   3786             sCurrentBroadcastIntent.set(data.intent);
   3787             receiver.setPendingResult(data);
   3788             receiver.onReceive(context.getReceiverRestrictedContext(),
   3789                     data.intent);
   3790         } catch (Exception e) {
   3791             if (DEBUG_BROADCAST) Slog.i(TAG,
   3792                     "Finishing failed broadcast to " + data.intent.getComponent());
   3793             data.sendFinished(mgr);
   3794             if (!mInstrumentation.onException(receiver, e)) {
   3795                 throw new RuntimeException(
   3796                     "Unable to start receiver " + component
   3797                     + ": " + e.toString(), e);
   3798             }
   3799         } finally {
   3800             sCurrentBroadcastIntent.set(null);
   3801         }
   3802 
   3803         if (receiver.getPendingResult() != null) {
   3804             data.finish();
   3805         }
   3806     }
   3807 
   3808     // Instantiate a BackupAgent and tell it that it's alive
   3809     private void handleCreateBackupAgent(CreateBackupAgentData data) {
   3810         if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
   3811 
   3812         // Sanity check the requested target package's uid against ours
   3813         try {
   3814             PackageInfo requestedPackage = getPackageManager().getPackageInfo(
   3815                     data.appInfo.packageName, 0, UserHandle.myUserId());
   3816             if (requestedPackage.applicationInfo.uid != Process.myUid()) {
   3817                 Slog.w(TAG, "Asked to instantiate non-matching package "
   3818                         + data.appInfo.packageName);
   3819                 return;
   3820             }
   3821         } catch (RemoteException e) {
   3822             throw e.rethrowFromSystemServer();
   3823         }
   3824 
   3825         // no longer idle; we have backup work to do
   3826         unscheduleGcIdler();
   3827 
   3828         // instantiate the BackupAgent class named in the manifest
   3829         LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
   3830         String packageName = packageInfo.mPackageName;
   3831         if (packageName == null) {
   3832             Slog.d(TAG, "Asked to create backup agent for nonexistent package");
   3833             return;
   3834         }
   3835 
   3836         String classname = data.appInfo.backupAgentName;
   3837         // full backup operation but no app-supplied agent?  use the default implementation
   3838         if (classname == null && (data.backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL
   3839                 || data.backupMode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL)) {
   3840             classname = "android.app.backup.FullBackupAgent";
   3841         }
   3842 
   3843         try {
   3844             IBinder binder = null;
   3845             ArrayMap<String, BackupAgent> backupAgents = getBackupAgentsForUser(data.userId);
   3846             BackupAgent agent = backupAgents.get(packageName);
   3847             if (agent != null) {
   3848                 // reusing the existing instance
   3849                 if (DEBUG_BACKUP) {
   3850                     Slog.v(TAG, "Reusing existing agent instance");
   3851                 }
   3852                 binder = agent.onBind();
   3853             } else {
   3854                 try {
   3855                     if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
   3856 
   3857                     java.lang.ClassLoader cl = packageInfo.getClassLoader();
   3858                     agent = (BackupAgent) cl.loadClass(classname).newInstance();
   3859 
   3860                     // set up the agent's context
   3861                     ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
   3862                     context.setOuterContext(agent);
   3863                     agent.attach(context);
   3864 
   3865                     agent.onCreate(UserHandle.of(data.userId));
   3866                     binder = agent.onBind();
   3867                     backupAgents.put(packageName, agent);
   3868                 } catch (Exception e) {
   3869                     // If this is during restore, fail silently; otherwise go
   3870                     // ahead and let the user see the crash.
   3871                     Slog.e(TAG, "Agent threw during creation: " + e);
   3872                     if (data.backupMode != ApplicationThreadConstants.BACKUP_MODE_RESTORE
   3873                             && data.backupMode !=
   3874                                     ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL) {
   3875                         throw e;
   3876                     }
   3877                     // falling through with 'binder' still null
   3878                 }
   3879             }
   3880 
   3881             // tell the OS that we're live now
   3882             try {
   3883                 ActivityManager.getService().backupAgentCreated(packageName, binder, data.userId);
   3884             } catch (RemoteException e) {
   3885                 throw e.rethrowFromSystemServer();
   3886             }
   3887         } catch (Exception e) {
   3888             throw new RuntimeException("Unable to create BackupAgent "
   3889                     + classname + ": " + e.toString(), e);
   3890         }
   3891     }
   3892 
   3893     // Tear down a BackupAgent
   3894     private void handleDestroyBackupAgent(CreateBackupAgentData data) {
   3895         if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
   3896 
   3897         LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
   3898         String packageName = packageInfo.mPackageName;
   3899         ArrayMap<String, BackupAgent> backupAgents = getBackupAgentsForUser(data.userId);
   3900         BackupAgent agent = backupAgents.get(packageName);
   3901         if (agent != null) {
   3902             try {
   3903                 agent.onDestroy();
   3904             } catch (Exception e) {
   3905                 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
   3906                 e.printStackTrace();
   3907             }
   3908             backupAgents.remove(packageName);
   3909         } else {
   3910             Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
   3911         }
   3912     }
   3913 
   3914     private ArrayMap<String, BackupAgent> getBackupAgentsForUser(int userId) {
   3915         ArrayMap<String, BackupAgent> backupAgents = mBackupAgentsByUser.get(userId);
   3916         if (backupAgents == null) {
   3917             backupAgents = new ArrayMap<>();
   3918             mBackupAgentsByUser.put(userId, backupAgents);
   3919         }
   3920         return backupAgents;
   3921     }
   3922 
   3923     @UnsupportedAppUsage
   3924     private void handleCreateService(CreateServiceData data) {
   3925         // If we are getting ready to gc after going to the background, well
   3926         // we are back active so skip it.
   3927         unscheduleGcIdler();
   3928 
   3929         LoadedApk packageInfo = getPackageInfoNoCheck(
   3930                 data.info.applicationInfo, data.compatInfo);
   3931         Service service = null;
   3932         try {
   3933             java.lang.ClassLoader cl = packageInfo.getClassLoader();
   3934             service = packageInfo.getAppFactory()
   3935                     .instantiateService(cl, data.info.name, data.intent);
   3936         } catch (Exception e) {
   3937             if (!mInstrumentation.onException(service, e)) {
   3938                 throw new RuntimeException(
   3939                     "Unable to instantiate service " + data.info.name
   3940                     + ": " + e.toString(), e);
   3941             }
   3942         }
   3943 
   3944         try {
   3945             if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
   3946 
   3947             ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
   3948             context.setOuterContext(service);
   3949 
   3950             Application app = packageInfo.makeApplication(false, mInstrumentation);
   3951             service.attach(context, this, data.info.name, data.token, app,
   3952                     ActivityManager.getService());
   3953             service.onCreate();
   3954             mServices.put(data.token, service);
   3955             try {
   3956                 ActivityManager.getService().serviceDoneExecuting(
   3957                         data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
   3958             } catch (RemoteException e) {
   3959                 throw e.rethrowFromSystemServer();
   3960             }
   3961         } catch (Exception e) {
   3962             if (!mInstrumentation.onException(service, e)) {
   3963                 throw new RuntimeException(
   3964                     "Unable to create service " + data.info.name
   3965                     + ": " + e.toString(), e);
   3966             }
   3967         }
   3968     }
   3969 
   3970     private void handleBindService(BindServiceData data) {
   3971         Service s = mServices.get(data.token);
   3972         if (DEBUG_SERVICE)
   3973             Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
   3974         if (s != null) {
   3975             try {
   3976                 data.intent.setExtrasClassLoader(s.getClassLoader());
   3977                 data.intent.prepareToEnterProcess();
   3978                 try {
   3979                     if (!data.rebind) {
   3980                         IBinder binder = s.onBind(data.intent);
   3981                         ActivityManager.getService().publishService(
   3982                                 data.token, data.intent, binder);
   3983                     } else {
   3984                         s.onRebind(data.intent);
   3985                         ActivityManager.getService().serviceDoneExecuting(
   3986                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
   3987                     }
   3988                 } catch (RemoteException ex) {
   3989                     throw ex.rethrowFromSystemServer();
   3990                 }
   3991             } catch (Exception e) {
   3992                 if (!mInstrumentation.onException(s, e)) {
   3993                     throw new RuntimeException(
   3994                             "Unable to bind to service " + s
   3995                             + " with " + data.intent + ": " + e.toString(), e);
   3996                 }
   3997             }
   3998         }
   3999     }
   4000 
   4001     private void handleUnbindService(BindServiceData data) {
   4002         Service s = mServices.get(data.token);
   4003         if (s != null) {
   4004             try {
   4005                 data.intent.setExtrasClassLoader(s.getClassLoader());
   4006                 data.intent.prepareToEnterProcess();
   4007                 boolean doRebind = s.onUnbind(data.intent);
   4008                 try {
   4009                     if (doRebind) {
   4010                         ActivityManager.getService().unbindFinished(
   4011                                 data.token, data.intent, doRebind);
   4012                     } else {
   4013                         ActivityManager.getService().serviceDoneExecuting(
   4014                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
   4015                     }
   4016                 } catch (RemoteException ex) {
   4017                     throw ex.rethrowFromSystemServer();
   4018                 }
   4019             } catch (Exception e) {
   4020                 if (!mInstrumentation.onException(s, e)) {
   4021                     throw new RuntimeException(
   4022                             "Unable to unbind to service " + s
   4023                             + " with " + data.intent + ": " + e.toString(), e);
   4024                 }
   4025             }
   4026         }
   4027     }
   4028 
   4029     private void handleDumpService(DumpComponentInfo info) {
   4030         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   4031         try {
   4032             Service s = mServices.get(info.token);
   4033             if (s != null) {
   4034                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
   4035                         info.fd.getFileDescriptor()));
   4036                 s.dump(info.fd.getFileDescriptor(), pw, info.args);
   4037                 pw.flush();
   4038             }
   4039         } finally {
   4040             IoUtils.closeQuietly(info.fd);
   4041             StrictMode.setThreadPolicy(oldPolicy);
   4042         }
   4043     }
   4044 
   4045     private void handleDumpActivity(DumpComponentInfo info) {
   4046         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   4047         try {
   4048             ActivityClientRecord r = mActivities.get(info.token);
   4049             if (r != null && r.activity != null) {
   4050                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
   4051                         info.fd.getFileDescriptor()));
   4052                 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
   4053                 pw.flush();
   4054             }
   4055         } finally {
   4056             IoUtils.closeQuietly(info.fd);
   4057             StrictMode.setThreadPolicy(oldPolicy);
   4058         }
   4059     }
   4060 
   4061     private void handleDumpProvider(DumpComponentInfo info) {
   4062         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
   4063         try {
   4064             ProviderClientRecord r = mLocalProviders.get(info.token);
   4065             if (r != null && r.mLocalProvider != null) {
   4066                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
   4067                         info.fd.getFileDescriptor()));
   4068                 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
   4069                 pw.flush();
   4070             }
   4071         } finally {
   4072             IoUtils.closeQuietly(info.fd);
   4073             StrictMode.setThreadPolicy(oldPolicy);
   4074         }
   4075     }
   4076 
   4077     private void handleServiceArgs(ServiceArgsData data) {
   4078         Service s = mServices.get(data.token);
   4079         if (s != null) {
   4080             try {
   4081                 if (data.args != null) {
   4082                     data.args.setExtrasClassLoader(s.getClassLoader());
   4083                     data.args.prepareToEnterProcess();
   4084                 }
   4085                 int res;
   4086                 if (!data.taskRemoved) {
   4087                     res = s.onStartCommand(data.args, data.flags, data.startId);
   4088                 } else {
   4089                     s.onTaskRemoved(data.args);
   4090                     res = Service.START_TASK_REMOVED_COMPLETE;
   4091                 }
   4092 
   4093                 QueuedWork.waitToFinish();
   4094 
   4095                 try {
   4096                     ActivityManager.getService().serviceDoneExecuting(
   4097                             data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
   4098                 } catch (RemoteException e) {
   4099                     throw e.rethrowFromSystemServer();
   4100                 }
   4101             } catch (Exception e) {
   4102                 if (!mInstrumentation.onException(s, e)) {
   4103                     throw new RuntimeException(
   4104                             "Unable to start service " + s
   4105                             + " with " + data.args + ": " + e.toString(), e);
   4106                 }
   4107             }
   4108         }
   4109     }
   4110 
   4111     private void handleStopService(IBinder token) {
   4112         Service s = mServices.remove(token);
   4113         if (s != null) {
   4114             try {
   4115                 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
   4116                 s.onDestroy();
   4117                 s.detachAndCleanUp();
   4118                 Context context = s.getBaseContext();
   4119                 if (context instanceof ContextImpl) {
   4120                     final String who = s.getClassName();
   4121                     ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
   4122                 }
   4123 
   4124                 QueuedWork.waitToFinish();
   4125 
   4126                 try {
   4127                     ActivityManager.getService().serviceDoneExecuting(
   4128                             token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
   4129                 } catch (RemoteException e) {
   4130                     throw e.rethrowFromSystemServer();
   4131                 }
   4132             } catch (Exception e) {
   4133                 if (!mInstrumentation.onException(s, e)) {
   4134                     throw new RuntimeException(
   4135                             "Unable to stop service " + s
   4136                             + ": " + e.toString(), e);
   4137                 }
   4138                 Slog.i(TAG, "handleStopService: exception for " + token, e);
   4139             }
   4140         } else {
   4141             Slog.i(TAG, "handleStopService: token=" + token + " not found.");
   4142         }
   4143         //Slog.i(TAG, "Running services: " + mServices);
   4144     }
   4145 
   4146     /**
   4147      * Resume the activity.
   4148      * @param token Target activity token.
   4149      * @param finalStateRequest Flag indicating if this is part of final state resolution for a
   4150      *                          transaction.
   4151      * @param reason Reason for performing the action.
   4152      *
   4153      * @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise.
   4154      */
   4155     @VisibleForTesting
   4156     public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
   4157             String reason) {
   4158         final ActivityClientRecord r = mActivities.get(token);
   4159         if (localLOGV) {
   4160             Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
   4161         }
   4162         if (r == null || r.activity.mFinished) {
   4163             return null;
   4164         }
   4165         if (r.getLifecycleState() == ON_RESUME) {
   4166             if (!finalStateRequest) {
   4167                 final RuntimeException e = new IllegalStateException(
   4168                         "Trying to resume activity which is already resumed");
   4169                 Slog.e(TAG, e.getMessage(), e);
   4170                 Slog.e(TAG, r.getStateString());
   4171                 // TODO(lifecycler): A double resume request is possible when an activity
   4172                 // receives two consequent transactions with relaunch requests and "resumed"
   4173                 // final state requests and the second relaunch is omitted. We still try to
   4174                 // handle two resume requests for the final state. For cases other than this
   4175                 // one, we don't expect it to happen.
   4176             }
   4177             return null;
   4178         }
   4179         if (finalStateRequest) {
   4180             r.hideForNow = false;
   4181             r.activity.mStartedActivity = false;
   4182         }
   4183         try {
   4184             r.activity.onStateNotSaved();
   4185             r.activity.mFragments.noteStateNotSaved();
   4186             checkAndBlockForNetworkAccess();
   4187             if (r.pendingIntents != null) {
   4188                 deliverNewIntents(r, r.pendingIntents);
   4189                 r.pendingIntents = null;
   4190             }
   4191             if (r.pendingResults != null) {
   4192                 deliverResults(r, r.pendingResults, reason);
   4193                 r.pendingResults = null;
   4194             }
   4195             r.activity.performResume(r.startsNotResumed, reason);
   4196 
   4197             r.state = null;
   4198             r.persistentState = null;
   4199             r.setState(ON_RESUME);
   4200 
   4201             reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming");
   4202         } catch (Exception e) {
   4203             if (!mInstrumentation.onException(r.activity, e)) {
   4204                 throw new RuntimeException("Unable to resume activity "
   4205                         + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
   4206             }
   4207         }
   4208         return r;
   4209     }
   4210 
   4211     static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
   4212         if (r.mPreserveWindow && !force) {
   4213             return;
   4214         }
   4215         if (r.mPendingRemoveWindow != null) {
   4216             r.mPendingRemoveWindowManager.removeViewImmediate(
   4217                     r.mPendingRemoveWindow.getDecorView());
   4218             IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken();
   4219             if (wtoken != null) {
   4220                 WindowManagerGlobal.getInstance().closeAll(wtoken,
   4221                         r.activity.getClass().getName(), "Activity");
   4222             }
   4223         }
   4224         r.mPendingRemoveWindow = null;
   4225         r.mPendingRemoveWindowManager = null;
   4226     }
   4227 
   4228     @Override
   4229     public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
   4230             String reason) {
   4231         // If we are getting ready to gc after going to the background, well
   4232         // we are back active so skip it.
   4233         unscheduleGcIdler();
   4234         mSomeActivitiesChanged = true;
   4235 
   4236         // TODO Push resumeArgs into the activity for consideration
   4237         final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
   4238         if (r == null) {
   4239             // We didn't actually resume the activity, so skipping any follow-up actions.
   4240             return;
   4241         }
   4242         if (mActivitiesToBeDestroyed.containsKey(token)) {
   4243             // Although the activity is resumed, it is going to be destroyed. So the following
   4244             // UI operations are unnecessary and also prevents exception because its token may
   4245             // be gone that window manager cannot recognize it. All necessary cleanup actions
   4246             // performed below will be done while handling destruction.
   4247             return;
   4248         }
   4249 
   4250         final Activity a = r.activity;
   4251 
   4252         if (localLOGV) {
   4253             Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity
   4254                     + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished);
   4255         }
   4256 
   4257         final int forwardBit = isForward
   4258                 ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
   4259 
   4260         // If the window hasn't yet been added to the window manager,
   4261         // and this guy didn't finish itself or start another activity,
   4262         // then go ahead and add the window.
   4263         boolean willBeVisible = !a.mStartedActivity;
   4264         if (!willBeVisible) {
   4265             try {
   4266                 willBeVisible = ActivityTaskManager.getService().willActivityBeVisible(
   4267                         a.getActivityToken());
   4268             } catch (RemoteException e) {
   4269                 throw e.rethrowFromSystemServer();
   4270             }
   4271         }
   4272         if (r.window == null && !a.mFinished && willBeVisible) {
   4273             r.window = r.activity.getWindow();
   4274             View decor = r.window.getDecorView();
   4275             decor.setVisibility(View.INVISIBLE);
   4276             ViewManager wm = a.getWindowManager();
   4277             WindowManager.LayoutParams l = r.window.getAttributes();
   4278             a.mDecor = decor;
   4279             l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
   4280             l.softInputMode |= forwardBit;
   4281             if (r.mPreserveWindow) {
   4282                 a.mWindowAdded = true;
   4283                 r.mPreserveWindow = false;
   4284                 // Normally the ViewRoot sets up callbacks with the Activity
   4285                 // in addView->ViewRootImpl#setView. If we are instead reusing
   4286                 // the decor view we have to notify the view root that the
   4287                 // callbacks may have changed.
   4288                 ViewRootImpl impl = decor.getViewRootImpl();
   4289                 if (impl != null) {
   4290                     impl.notifyChildRebuilt();
   4291                 }
   4292             }
   4293             if (a.mVisibleFromClient) {
   4294                 if (!a.mWindowAdded) {
   4295                     a.mWindowAdded = true;
   4296                     wm.addView(decor, l);
   4297                 } else {
   4298                     // The activity will get a callback for this {@link LayoutParams} change
   4299                     // earlier. However, at that time the decor will not be set (this is set
   4300                     // in this method), so no action will be taken. This call ensures the
   4301                     // callback occurs with the decor set.
   4302                     a.onWindowAttributesChanged(l);
   4303                 }
   4304             }
   4305 
   4306             // If the window has already been added, but during resume
   4307             // we started another activity, then don't yet make the
   4308             // window visible.
   4309         } else if (!willBeVisible) {
   4310             if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
   4311             r.hideForNow = true;
   4312         }
   4313 
   4314         // Get rid of anything left hanging around.
   4315         cleanUpPendingRemoveWindows(r, false /* force */);
   4316 
   4317         // The window is now visible if it has been added, we are not
   4318         // simply finishing, and we are not starting another activity.
   4319         if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
   4320             if (r.newConfig != null) {
   4321                 performConfigurationChangedForActivity(r, r.newConfig);
   4322                 if (DEBUG_CONFIGURATION) {
   4323                     Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
   4324                             + r.activity.mCurrentConfig);
   4325                 }
   4326                 r.newConfig = null;
   4327             }
   4328             if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
   4329             WindowManager.LayoutParams l = r.window.getAttributes();
   4330             if ((l.softInputMode
   4331                     & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
   4332                     != forwardBit) {
   4333                 l.softInputMode = (l.softInputMode
   4334                         & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
   4335                         | forwardBit;
   4336                 if (r.activity.mVisibleFromClient) {
   4337                     ViewManager wm = a.getWindowManager();
   4338                     View decor = r.window.getDecorView();
   4339                     wm.updateViewLayout(decor, l);
   4340                 }
   4341             }
   4342 
   4343             r.activity.mVisibleFromServer = true;
   4344             mNumVisibleActivities++;
   4345             if (r.activity.mVisibleFromClient) {
   4346                 r.activity.makeVisible();
   4347             }
   4348         }
   4349 
   4350         r.nextIdle = mNewActivities;
   4351         mNewActivities = r;
   4352         if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
   4353         Looper.myQueue().addIdleHandler(new Idler());
   4354     }
   4355 
   4356 
   4357     @Override
   4358     public void handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason) {
   4359         ActivityClientRecord r = mActivities.get(token);
   4360         if (r == null || r.activity == null) {
   4361             Slog.w(TAG, "Not found target activity to report position change for token: " + token);
   4362             return;
   4363         }
   4364 
   4365         if (DEBUG_ORDER) {
   4366             Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
   4367         }
   4368 
   4369         if (r.isTopResumedActivity == onTop) {
   4370             throw new IllegalStateException("Activity top position already set to onTop=" + onTop);
   4371         }
   4372 
   4373         r.isTopResumedActivity = onTop;
   4374 
   4375         if (r.getLifecycleState() == ON_RESUME) {
   4376             reportTopResumedActivityChanged(r, onTop, "topStateChangedWhenResumed");
   4377         } else {
   4378             if (DEBUG_ORDER) {
   4379                 Slog.d(TAG, "Won't deliver top position change in state=" + r.getLifecycleState());
   4380             }
   4381         }
   4382     }
   4383 
   4384     /**
   4385      * Call {@link Activity#onTopResumedActivityChanged(boolean)} if its top resumed state changed
   4386      * since the last report.
   4387      */
   4388     private void reportTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
   4389             String reason) {
   4390         if (r.lastReportedTopResumedState != onTop) {
   4391             r.lastReportedTopResumedState = onTop;
   4392             r.activity.performTopResumedActivityChanged(onTop, reason);
   4393         }
   4394     }
   4395 
   4396     @Override
   4397     public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
   4398             int configChanges, PendingTransactionActions pendingActions, String reason) {
   4399         ActivityClientRecord r = mActivities.get(token);
   4400         if (r != null) {
   4401             if (userLeaving) {
   4402                 performUserLeavingActivity(r);
   4403             }
   4404 
   4405             r.activity.mConfigChangeFlags |= configChanges;
   4406             performPauseActivity(r, finished, reason, pendingActions);
   4407 
   4408             // Make sure any pending writes are now committed.
   4409             if (r.isPreHoneycomb()) {
   4410                 QueuedWork.waitToFinish();
   4411             }
   4412             mSomeActivitiesChanged = true;
   4413         }
   4414     }
   4415 
   4416     final void performUserLeavingActivity(ActivityClientRecord r) {
   4417         mInstrumentation.callActivityOnUserLeaving(r.activity);
   4418     }
   4419 
   4420     final Bundle performPauseActivity(IBinder token, boolean finished, String reason,
   4421             PendingTransactionActions pendingActions) {
   4422         ActivityClientRecord r = mActivities.get(token);
   4423         return r != null ? performPauseActivity(r, finished, reason, pendingActions) : null;
   4424     }
   4425 
   4426     /**
   4427      * Pause the activity.
   4428      * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
   4429      */
   4430     private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
   4431             PendingTransactionActions pendingActions) {
   4432         if (r.paused) {
   4433             if (r.activity.mFinished) {
   4434                 // If we are finishing, we won't call onResume() in certain cases.
   4435                 // So here we likewise don't want to call onPause() if the activity
   4436                 // isn't resumed.
   4437                 return null;
   4438             }
   4439             RuntimeException e = new RuntimeException(
   4440                     "Performing pause of activity that is not resumed: "
   4441                     + r.intent.getComponent().toShortString());
   4442             Slog.e(TAG, e.getMessage(), e);
   4443         }
   4444         if (finished) {
   4445             r.activity.mFinished = true;
   4446         }
   4447 
   4448         // Pre-Honeycomb apps always save their state before pausing
   4449         final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
   4450         if (shouldSaveState) {
   4451             callActivityOnSaveInstanceState(r);
   4452         }
   4453 
   4454         performPauseActivityIfNeeded(r, reason);
   4455 
   4456         // Notify any outstanding on paused listeners
   4457         ArrayList<OnActivityPausedListener> listeners;
   4458         synchronized (mOnPauseListeners) {
   4459             listeners = mOnPauseListeners.remove(r.activity);
   4460         }
   4461         int size = (listeners != null ? listeners.size() : 0);
   4462         for (int i = 0; i < size; i++) {
   4463             listeners.get(i).onPaused(r.activity);
   4464         }
   4465 
   4466         final Bundle oldState = pendingActions != null ? pendingActions.getOldState() : null;
   4467         if (oldState != null) {
   4468             // We need to keep around the original state, in case we need to be created again.
   4469             // But we only do this for pre-Honeycomb apps, which always save their state when
   4470             // pausing, so we can not have them save their state when restarting from a paused
   4471             // state. For HC and later, we want to (and can) let the state be saved as the
   4472             // normal part of stopping the activity.
   4473             if (r.isPreHoneycomb()) {
   4474                 r.state = oldState;
   4475             }
   4476         }
   4477 
   4478         return shouldSaveState ? r.state : null;
   4479     }
   4480 
   4481     private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
   4482         if (r.paused) {
   4483             // You are already paused silly...
   4484             return;
   4485         }
   4486 
   4487         // Always reporting top resumed position loss when pausing an activity. If necessary, it
   4488         // will be restored in performResumeActivity().
   4489         reportTopResumedActivityChanged(r, false /* onTop */, "pausing");
   4490 
   4491         try {
   4492             r.activity.mCalled = false;
   4493             mInstrumentation.callActivityOnPause(r.activity);
   4494             if (!r.activity.mCalled) {
   4495                 throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
   4496                         + " did not call through to super.onPause()");
   4497             }
   4498         } catch (SuperNotCalledException e) {
   4499             throw e;
   4500         } catch (Exception e) {
   4501             if (!mInstrumentation.onException(r.activity, e)) {
   4502                 throw new RuntimeException("Unable to pause activity "
   4503                         + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
   4504             }
   4505         }
   4506         r.setState(ON_PAUSE);
   4507     }
   4508 
   4509     /** Called from {@link LocalActivityManager}. */
   4510     @UnsupportedAppUsage
   4511     final void performStopActivity(IBinder token, boolean saveState, String reason) {
   4512         ActivityClientRecord r = mActivities.get(token);
   4513         performStopActivityInner(r, null /* stopInfo */, false /* keepShown */, saveState,
   4514                 false /* finalStateRequest */, reason);
   4515     }
   4516 
   4517     private static final class ProviderRefCount {
   4518         public final ContentProviderHolder holder;
   4519         public final ProviderClientRecord client;
   4520         public int stableCount;
   4521         public int unstableCount;
   4522 
   4523         // When this is set, the stable and unstable ref counts are 0 and
   4524         // we have a pending operation scheduled to remove the ref count
   4525         // from the activity manager.  On the activity manager we are still
   4526         // holding an unstable ref, though it is not reflected in the counts
   4527         // here.
   4528         public boolean removePending;
   4529 
   4530         ProviderRefCount(ContentProviderHolder inHolder,
   4531                 ProviderClientRecord inClient, int sCount, int uCount) {
   4532             holder = inHolder;
   4533             client = inClient;
   4534             stableCount = sCount;
   4535             unstableCount = uCount;
   4536         }
   4537     }
   4538 
   4539     /**
   4540      * Core implementation of stopping an activity.  Note this is a little
   4541      * tricky because the server's meaning of stop is slightly different
   4542      * than our client -- for the server, stop means to save state and give
   4543      * it the result when it is done, but the window may still be visible.
   4544      * For the client, we want to call onStop()/onStart() to indicate when
   4545      * the activity's UI visibility changes.
   4546      * @param r Target activity client record.
   4547      * @param info Action that will report activity stop to server.
   4548      * @param keepShown Flag indicating whether the activity is still shown.
   4549      * @param saveState Flag indicating whether the activity state should be saved.
   4550      * @param finalStateRequest Flag indicating if this call is handling final lifecycle state
   4551      *                          request for a transaction.
   4552      * @param reason Reason for performing this operation.
   4553      */
   4554     private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
   4555             boolean saveState, boolean finalStateRequest, String reason) {
   4556         if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
   4557         if (r != null) {
   4558             if (!keepShown && r.stopped) {
   4559                 if (r.activity.mFinished) {
   4560                     // If we are finishing, we won't call onResume() in certain
   4561                     // cases.  So here we likewise don't want to call onStop()
   4562                     // if the activity isn't resumed.
   4563                     return;
   4564                 }
   4565                 if (!finalStateRequest) {
   4566                     final RuntimeException e = new RuntimeException(
   4567                             "Performing stop of activity that is already stopped: "
   4568                                     + r.intent.getComponent().toShortString());
   4569                     Slog.e(TAG, e.getMessage(), e);
   4570                     Slog.e(TAG, r.getStateString());
   4571                 }
   4572             }
   4573 
   4574             // One must first be paused before stopped...
   4575             performPauseActivityIfNeeded(r, reason);
   4576 
   4577             if (info != null) {
   4578                 try {
   4579                     // First create a thumbnail for the activity...
   4580                     // For now, don't create the thumbnail here; we are
   4581                     // doing that by doing a screen snapshot.
   4582                     info.setDescription(r.activity.onCreateDescription());
   4583                 } catch (Exception e) {
   4584                     if (!mInstrumentation.onException(r.activity, e)) {
   4585                         throw new RuntimeException(
   4586                                 "Unable to save state of activity "
   4587                                 + r.intent.getComponent().toShortString()
   4588                                 + ": " + e.toString(), e);
   4589                     }
   4590                 }
   4591             }
   4592 
   4593             if (!keepShown) {
   4594                 callActivityOnStop(r, saveState, reason);
   4595             }
   4596         }
   4597     }
   4598 
   4599     /**
   4600      * Calls {@link Activity#onStop()} and {@link Activity#onSaveInstanceState(Bundle)}, and updates
   4601      * the client record's state.
   4602      * All calls to stop an activity must be done through this method to make sure that
   4603      * {@link Activity#onSaveInstanceState(Bundle)} is also executed in the same call.
   4604      */
   4605     private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
   4606         // Before P onSaveInstanceState was called before onStop, starting with P it's
   4607         // called after. Before Honeycomb state was always saved before onPause.
   4608         final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
   4609                 && !r.isPreHoneycomb();
   4610         final boolean isPreP = r.isPreP();
   4611         if (shouldSaveState && isPreP) {
   4612             callActivityOnSaveInstanceState(r);
   4613         }
   4614 
   4615         try {
   4616             r.activity.performStop(r.mPreserveWindow, reason);
   4617         } catch (SuperNotCalledException e) {
   4618             throw e;
   4619         } catch (Exception e) {
   4620             if (!mInstrumentation.onException(r.activity, e)) {
   4621                 throw new RuntimeException(
   4622                         "Unable to stop activity "
   4623                                 + r.intent.getComponent().toShortString()
   4624                                 + ": " + e.toString(), e);
   4625             }
   4626         }
   4627         r.setState(ON_STOP);
   4628 
   4629         if (shouldSaveState && !isPreP) {
   4630             callActivityOnSaveInstanceState(r);
   4631         }
   4632     }
   4633 
   4634     private void updateVisibility(ActivityClientRecord r, boolean show) {
   4635         View v = r.activity.mDecor;
   4636         if (v != null) {
   4637             if (show) {
   4638                 if (!r.activity.mVisibleFromServer) {
   4639                     r.activity.mVisibleFromServer = true;
   4640                     mNumVisibleActivities++;
   4641                     if (r.activity.mVisibleFromClient) {
   4642                         r.activity.makeVisible();
   4643                     }
   4644                 }
   4645                 if (r.newConfig != null) {
   4646                     performConfigurationChangedForActivity(r, r.newConfig);
   4647                     if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
   4648                             + r.activityInfo.name + " with new config "
   4649                             + r.activity.mCurrentConfig);
   4650                     r.newConfig = null;
   4651                 }
   4652             } else {
   4653                 if (r.activity.mVisibleFromServer) {
   4654                     r.activity.mVisibleFromServer = false;
   4655                     mNumVisibleActivities--;
   4656                     v.setVisibility(View.INVISIBLE);
   4657                 }
   4658             }
   4659         }
   4660     }
   4661 
   4662     @Override
   4663     public void handleStopActivity(IBinder token, boolean show, int configChanges,
   4664             PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
   4665         final ActivityClientRecord r = mActivities.get(token);
   4666         r.activity.mConfigChangeFlags |= configChanges;
   4667 
   4668         final StopInfo stopInfo = new StopInfo();
   4669         performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
   4670                 reason);
   4671 
   4672         if (localLOGV) Slog.v(
   4673             TAG, "Finishing stop of " + r + ": show=" + show
   4674             + " win=" + r.window);
   4675 
   4676         updateVisibility(r, show);
   4677 
   4678         // Make sure any pending writes are now committed.
   4679         if (!r.isPreHoneycomb()) {
   4680             QueuedWork.waitToFinish();
   4681         }
   4682 
   4683         stopInfo.setActivity(r);
   4684         stopInfo.setState(r.state);
   4685         stopInfo.setPersistentState(r.persistentState);
   4686         pendingActions.setStopInfo(stopInfo);
   4687         mSomeActivitiesChanged = true;
   4688     }
   4689 
   4690     /**
   4691      * Schedule the call to tell the activity manager we have stopped.  We don't do this
   4692      * immediately, because we want to have a chance for any other pending work (in particular
   4693      * memory trim requests) to complete before you tell the activity manager to proceed and allow
   4694      * us to go fully into the background.
   4695      */
   4696     @Override
   4697     public void reportStop(PendingTransactionActions pendingActions) {
   4698         mH.post(pendingActions.getStopInfo());
   4699     }
   4700 
   4701     @Override
   4702     public void performRestartActivity(IBinder token, boolean start) {
   4703         ActivityClientRecord r = mActivities.get(token);
   4704         if (r.stopped) {
   4705             r.activity.performRestart(start, "performRestartActivity");
   4706             if (start) {
   4707                 r.setState(ON_START);
   4708             }
   4709         }
   4710     }
   4711 
   4712     @Override
   4713     public void handleWindowVisibility(IBinder token, boolean show) {
   4714         ActivityClientRecord r = mActivities.get(token);
   4715 
   4716         if (r == null) {
   4717             Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
   4718             return;
   4719         }
   4720 
   4721         if (!show && !r.stopped) {
   4722             performStopActivityInner(r, null /* stopInfo */, show, false /* saveState */,
   4723                     false /* finalStateRequest */, "handleWindowVisibility");
   4724         } else if (show && r.getLifecycleState() == ON_STOP) {
   4725             // If we are getting ready to gc after going to the background, well
   4726             // we are back active so skip it.
   4727             unscheduleGcIdler();
   4728 
   4729             r.activity.performRestart(true /* start */, "handleWindowVisibility");
   4730             r.setState(ON_START);
   4731         }
   4732         if (r.activity.mDecor != null) {
   4733             if (false) Slog.v(
   4734                 TAG, "Handle window " + r + " visibility: " + show);
   4735             updateVisibility(r, show);
   4736         }
   4737         mSomeActivitiesChanged = true;
   4738     }
   4739 
   4740     // TODO: This method should be changed to use {@link #performStopActivityInner} to perform to
   4741     // stop operation on the activity to reduce code duplication and the chance of fixing a bug in
   4742     // one place and missing the other.
   4743     private void handleSleeping(IBinder token, boolean sleeping) {
   4744         ActivityClientRecord r = mActivities.get(token);
   4745 
   4746         if (r == null) {
   4747             Log.w(TAG, "handleSleeping: no activity for token " + token);
   4748             return;
   4749         }
   4750 
   4751         if (sleeping) {
   4752             if (!r.stopped && !r.isPreHoneycomb()) {
   4753                 callActivityOnStop(r, true /* saveState */, "sleeping");
   4754             }
   4755 
   4756             // Make sure any pending writes are now committed.
   4757             if (!r.isPreHoneycomb()) {
   4758                 QueuedWork.waitToFinish();
   4759             }
   4760 
   4761             // Tell activity manager we slept.
   4762             try {
   4763                 ActivityTaskManager.getService().activitySlept(r.token);
   4764             } catch (RemoteException ex) {
   4765                 throw ex.rethrowFromSystemServer();
   4766             }
   4767         } else {
   4768             if (r.stopped && r.activity.mVisibleFromServer) {
   4769                 r.activity.performRestart(true /* start */, "handleSleeping");
   4770                 r.setState(ON_START);
   4771             }
   4772         }
   4773     }
   4774 
   4775     private void handleSetCoreSettings(Bundle coreSettings) {
   4776         synchronized (mResourcesManager) {
   4777             mCoreSettings = coreSettings;
   4778         }
   4779         onCoreSettingsChange();
   4780     }
   4781 
   4782     private void onCoreSettingsChange() {
   4783         if (updateDebugViewAttributeState()) {
   4784             // request all activities to relaunch for the changes to take place
   4785             relaunchAllActivities(false /* preserveWindows */);
   4786         }
   4787     }
   4788 
   4789     private boolean updateDebugViewAttributeState() {
   4790         boolean previousState = View.sDebugViewAttributes;
   4791 
   4792         View.sDebugViewAttributesApplicationPackage = mCoreSettings.getString(
   4793                 Settings.Global.DEBUG_VIEW_ATTRIBUTES_APPLICATION_PACKAGE, "");
   4794         String currentPackage = (mBoundApplication != null && mBoundApplication.appInfo != null)
   4795                 ? mBoundApplication.appInfo.packageName : "";
   4796         View.sDebugViewAttributes =
   4797                 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0
   4798                         || View.sDebugViewAttributesApplicationPackage.equals(currentPackage);
   4799         return previousState != View.sDebugViewAttributes;
   4800     }
   4801 
   4802     private void relaunchAllActivities(boolean preserveWindows) {
   4803         for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
   4804             final ActivityClientRecord r = entry.getValue();
   4805             if (!r.activity.mFinished) {
   4806                 if (preserveWindows && r.window != null) {
   4807                     r.mPreserveWindow = true;
   4808                 }
   4809                 scheduleRelaunchActivity(entry.getKey());
   4810             }
   4811         }
   4812     }
   4813 
   4814     private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
   4815         LoadedApk apk = peekPackageInfo(data.pkg, false);
   4816         if (apk != null) {
   4817             apk.setCompatibilityInfo(data.info);
   4818         }
   4819         apk = peekPackageInfo(data.pkg, true);
   4820         if (apk != null) {
   4821             apk.setCompatibilityInfo(data.info);
   4822         }
   4823         handleConfigurationChanged(mConfiguration, data.info);
   4824         WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
   4825     }
   4826 
   4827     private void deliverResults(ActivityClientRecord r, List<ResultInfo> results, String reason) {
   4828         final int N = results.size();
   4829         for (int i=0; i<N; i++) {
   4830             ResultInfo ri = results.get(i);
   4831             try {
   4832                 if (ri.mData != null) {
   4833                     ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
   4834                     ri.mData.prepareToEnterProcess();
   4835                 }
   4836                 if (DEBUG_RESULTS) Slog.v(TAG,
   4837                         "Delivering result to activity " + r + " : " + ri);
   4838                 r.activity.dispatchActivityResult(ri.mResultWho,
   4839                         ri.mRequestCode, ri.mResultCode, ri.mData, reason);
   4840             } catch (Exception e) {
   4841                 if (!mInstrumentation.onException(r.activity, e)) {
   4842                     throw new RuntimeException(
   4843                             "Failure delivering result " + ri + " to activity "
   4844                             + r.intent.getComponent().toShortString()
   4845                             + ": " + e.toString(), e);
   4846                 }
   4847             }
   4848         }
   4849     }
   4850 
   4851     @Override
   4852     public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
   4853         ActivityClientRecord r = mActivities.get(token);
   4854         if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
   4855         if (r != null) {
   4856             final boolean resumed = !r.paused;
   4857             if (!r.activity.mFinished && r.activity.mDecor != null
   4858                     && r.hideForNow && resumed) {
   4859                 // We had hidden the activity because it started another
   4860                 // one...  we have gotten a result back and we are not
   4861                 // paused, so make sure our window is visible.
   4862                 updateVisibility(r, true);
   4863             }
   4864             if (resumed) {
   4865                 try {
   4866                     // Now we are idle.
   4867                     r.activity.mCalled = false;
   4868                     mInstrumentation.callActivityOnPause(r.activity);
   4869                     if (!r.activity.mCalled) {
   4870                         throw new SuperNotCalledException(
   4871                             "Activity " + r.intent.getComponent().toShortString()
   4872                             + " did not call through to super.onPause()");
   4873                     }
   4874                 } catch (SuperNotCalledException e) {
   4875                     throw e;
   4876                 } catch (Exception e) {
   4877                     if (!mInstrumentation.onException(r.activity, e)) {
   4878                         throw new RuntimeException(
   4879                                 "Unable to pause activity "
   4880                                 + r.intent.getComponent().toShortString()
   4881                                 + ": " + e.toString(), e);
   4882                     }
   4883                 }
   4884             }
   4885             checkAndBlockForNetworkAccess();
   4886             deliverResults(r, results, reason);
   4887             if (resumed) {
   4888                 r.activity.performResume(false, reason);
   4889             }
   4890         }
   4891     }
   4892 
   4893     /** Core implementation of activity destroy call. */
   4894     ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
   4895             int configChanges, boolean getNonConfigInstance, String reason) {
   4896         ActivityClientRecord r = mActivities.get(token);
   4897         Class<? extends Activity> activityClass = null;
   4898         if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
   4899         if (r != null) {
   4900             activityClass = r.activity.getClass();
   4901             r.activity.mConfigChangeFlags |= configChanges;
   4902             if (finishing) {
   4903                 r.activity.mFinished = true;
   4904             }
   4905 
   4906             performPauseActivityIfNeeded(r, "destroy");
   4907 
   4908             if (!r.stopped) {
   4909                 callActivityOnStop(r, false /* saveState */, "destroy");
   4910             }
   4911             if (getNonConfigInstance) {
   4912                 try {
   4913                     r.lastNonConfigurationInstances
   4914                             = r.activity.retainNonConfigurationInstances();
   4915                 } catch (Exception e) {
   4916                     if (!mInstrumentation.onException(r.activity, e)) {
   4917                         throw new RuntimeException(
   4918                                 "Unable to retain activity "
   4919                                 + r.intent.getComponent().toShortString()
   4920                                 + ": " + e.toString(), e);
   4921                     }
   4922                 }
   4923             }
   4924             try {
   4925                 r.activity.mCalled = false;
   4926                 mInstrumentation.callActivityOnDestroy(r.activity);
   4927                 if (!r.activity.mCalled) {
   4928                     throw new SuperNotCalledException(
   4929                         "Activity " + safeToComponentShortString(r.intent) +
   4930                         " did not call through to super.onDestroy()");
   4931                 }
   4932                 if (r.window != null) {
   4933                     r.window.closeAllPanels();
   4934                 }
   4935             } catch (SuperNotCalledException e) {
   4936                 throw e;
   4937             } catch (Exception e) {
   4938                 if (!mInstrumentation.onException(r.activity, e)) {
   4939                     throw new RuntimeException(
   4940                             "Unable to destroy activity " + safeToComponentShortString(r.intent)
   4941                             + ": " + e.toString(), e);
   4942                 }
   4943             }
   4944             r.setState(ON_DESTROY);
   4945         }
   4946         schedulePurgeIdler();
   4947         // updatePendingActivityConfiguration() reads from mActivities to update
   4948         // ActivityClientRecord which runs in a different thread. Protect modifications to
   4949         // mActivities to avoid race.
   4950         synchronized (mResourcesManager) {
   4951             mActivities.remove(token);
   4952         }
   4953         StrictMode.decrementExpectedActivityCount(activityClass);
   4954         return r;
   4955     }
   4956 
   4957     private static String safeToComponentShortString(Intent intent) {
   4958         ComponentName component = intent.getComponent();
   4959         return component == null ? "[Unknown]" : component.toShortString();
   4960     }
   4961 
   4962     @Override
   4963     public Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed() {
   4964         return mActivitiesToBeDestroyed;
   4965     }
   4966 
   4967     @Override
   4968     public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
   4969             boolean getNonConfigInstance, String reason) {
   4970         ActivityClientRecord r = performDestroyActivity(token, finishing,
   4971                 configChanges, getNonConfigInstance, reason);
   4972         if (r != null) {
   4973             cleanUpPendingRemoveWindows(r, finishing);
   4974             WindowManager wm = r.activity.getWindowManager();
   4975             View v = r.activity.mDecor;
   4976             if (v != null) {
   4977                 if (r.activity.mVisibleFromServer) {
   4978                     mNumVisibleActivities--;
   4979                 }
   4980                 IBinder wtoken = v.getWindowToken();
   4981                 if (r.activity.mWindowAdded) {
   4982                     if (r.mPreserveWindow) {
   4983                         // Hold off on removing this until the new activity's
   4984                         // window is being added.
   4985                         r.mPendingRemoveWindow = r.window;
   4986                         r.mPendingRemoveWindowManager = wm;
   4987                         // We can only keep the part of the view hierarchy that we control,
   4988                         // everything else must be removed, because it might not be able to
   4989                         // behave properly when activity is relaunching.
   4990                         r.window.clearContentView();
   4991                     } else {
   4992                         wm.removeViewImmediate(v);
   4993                     }
   4994                 }
   4995                 if (wtoken != null && r.mPendingRemoveWindow == null) {
   4996                     WindowManagerGlobal.getInstance().closeAll(wtoken,
   4997                             r.activity.getClass().getName(), "Activity");
   4998                 } else if (r.mPendingRemoveWindow != null) {
   4999                     // We're preserving only one window, others should be closed so app views
   5000                     // will be detached before the final tear down. It should be done now because
   5001                     // some components (e.g. WebView) rely on detach callbacks to perform receiver
   5002                     // unregister and other cleanup.
   5003                     WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
   5004                             r.activity.getClass().getName(), "Activity");
   5005                 }
   5006                 r.activity.mDecor = null;
   5007             }
   5008             if (r.mPendingRemoveWindow == null) {
   5009                 // If we are delaying the removal of the activity window, then
   5010                 // we can't clean up all windows here.  Note that we can't do
   5011                 // so later either, which means any windows that aren't closed
   5012                 // by the app will leak.  Well we try to warning them a lot
   5013                 // about leaking windows, because that is a bug, so if they are
   5014                 // using this recreate facility then they get to live with leaks.
   5015                 WindowManagerGlobal.getInstance().closeAll(token,
   5016                         r.activity.getClass().getName(), "Activity");
   5017             }
   5018 
   5019             // Mocked out contexts won't be participating in the normal
   5020             // process lifecycle, but if we're running with a proper
   5021             // ApplicationContext we need to have it tear down things
   5022             // cleanly.
   5023             Context c = r.activity.getBaseContext();
   5024             if (c instanceof ContextImpl) {
   5025                 ((ContextImpl) c).scheduleFinalCleanup(
   5026                         r.activity.getClass().getName(), "Activity");
   5027             }
   5028         }
   5029         if (finishing) {
   5030             try {
   5031                 ActivityTaskManager.getService().activityDestroyed(token);
   5032             } catch (RemoteException ex) {
   5033                 throw ex.rethrowFromSystemServer();
   5034             }
   5035         }
   5036         mSomeActivitiesChanged = true;
   5037     }
   5038 
   5039     @Override
   5040     public ActivityClientRecord prepareRelaunchActivity(IBinder token,
   5041             List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
   5042             int configChanges, MergedConfiguration config, boolean preserveWindow) {
   5043         ActivityClientRecord target = null;
   5044         boolean scheduleRelaunch = false;
   5045 
   5046         synchronized (mResourcesManager) {
   5047             for (int i=0; i<mRelaunchingActivities.size(); i++) {
   5048                 ActivityClientRecord r = mRelaunchingActivities.get(i);
   5049                 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r);
   5050                 if (r.token == token) {
   5051                     target = r;
   5052                     if (pendingResults != null) {
   5053                         if (r.pendingResults != null) {
   5054                             r.pendingResults.addAll(pendingResults);
   5055                         } else {
   5056                             r.pendingResults = pendingResults;
   5057                         }
   5058                     }
   5059                     if (pendingNewIntents != null) {
   5060                         if (r.pendingIntents != null) {
   5061                             r.pendingIntents.addAll(pendingNewIntents);
   5062                         } else {
   5063                             r.pendingIntents = pendingNewIntents;
   5064                         }
   5065                     }
   5066                     break;
   5067                 }
   5068             }
   5069 
   5070             if (target == null) {
   5071                 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null");
   5072                 target = new ActivityClientRecord();
   5073                 target.token = token;
   5074                 target.pendingResults = pendingResults;
   5075                 target.pendingIntents = pendingNewIntents;
   5076                 target.mPreserveWindow = preserveWindow;
   5077                 mRelaunchingActivities.add(target);
   5078                 scheduleRelaunch = true;
   5079             }
   5080             target.createdConfig = config.getGlobalConfiguration();
   5081             target.overrideConfig = config.getOverrideConfiguration();
   5082             target.pendingConfigChanges |= configChanges;
   5083         }
   5084 
   5085         return scheduleRelaunch ? target : null;
   5086     }
   5087 
   5088     @Override
   5089     public void handleRelaunchActivity(ActivityClientRecord tmp,
   5090             PendingTransactionActions pendingActions) {
   5091         // If we are getting ready to gc after going to the background, well
   5092         // we are back active so skip it.
   5093         unscheduleGcIdler();
   5094         mSomeActivitiesChanged = true;
   5095 
   5096         Configuration changedConfig = null;
   5097         int configChanges = 0;
   5098 
   5099         // First: make sure we have the most recent configuration and most
   5100         // recent version of the activity, or skip it if some previous call
   5101         // had taken a more recent version.
   5102         synchronized (mResourcesManager) {
   5103             int N = mRelaunchingActivities.size();
   5104             IBinder token = tmp.token;
   5105             tmp = null;
   5106             for (int i=0; i<N; i++) {
   5107                 ActivityClientRecord r = mRelaunchingActivities.get(i);
   5108                 if (r.token == token) {
   5109                     tmp = r;
   5110                     configChanges |= tmp.pendingConfigChanges;
   5111                     mRelaunchingActivities.remove(i);
   5112                     i--;
   5113                     N--;
   5114                 }
   5115             }
   5116 
   5117             if (tmp == null) {
   5118                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
   5119                 return;
   5120             }
   5121 
   5122             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
   5123                     + tmp.token + " with configChanges=0x"
   5124                     + Integer.toHexString(configChanges));
   5125 
   5126             if (mPendingConfiguration != null) {
   5127                 changedConfig = mPendingConfiguration;
   5128                 mPendingConfiguration = null;
   5129             }
   5130         }
   5131 
   5132         if (tmp.createdConfig != null) {
   5133             // If the activity manager is passing us its current config,
   5134             // assume that is really what we want regardless of what we
   5135             // may have pending.
   5136             if (mConfiguration == null
   5137                     || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
   5138                             && mConfiguration.diff(tmp.createdConfig) != 0)) {
   5139                 if (changedConfig == null
   5140                         || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
   5141                     changedConfig = tmp.createdConfig;
   5142                 }
   5143             }
   5144         }
   5145 
   5146         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
   5147                 + tmp.token + ": changedConfig=" + changedConfig);
   5148 
   5149         // If there was a pending configuration change, execute it first.
   5150         if (changedConfig != null) {
   5151             mCurDefaultDisplayDpi = changedConfig.densityDpi;
   5152             updateDefaultDensity();
   5153             handleConfigurationChanged(changedConfig, null);
   5154         }
   5155 
   5156         ActivityClientRecord r = mActivities.get(tmp.token);
   5157         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
   5158         if (r == null) {
   5159             return;
   5160         }
   5161 
   5162         r.activity.mConfigChangeFlags |= configChanges;
   5163         r.mPreserveWindow = tmp.mPreserveWindow;
   5164 
   5165         r.activity.mChangingConfigurations = true;
   5166 
   5167         // If we are preserving the main window across relaunches we would also like to preserve
   5168         // the children. However the client side view system does not support preserving
   5169         // the child views so we notify the window manager to expect these windows to
   5170         // be replaced and defer requests to destroy or hide them. This way we can achieve
   5171         // visual continuity. It's important that we do this here prior to pause and destroy
   5172         // as that is when we may hide or remove the child views.
   5173         //
   5174         // There is another scenario, if we have decided locally to relaunch the app from a
   5175         // call to recreate, then none of the windows will be prepared for replacement or
   5176         // preserved by the server, so we want to notify it that we are preparing to replace
   5177         // everything
   5178         try {
   5179             if (r.mPreserveWindow) {
   5180                 WindowManagerGlobal.getWindowSession().prepareToReplaceWindows(
   5181                         r.token, true /* childrenOnly */);
   5182             }
   5183         } catch (RemoteException e) {
   5184             throw e.rethrowFromSystemServer();
   5185         }
   5186 
   5187         handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
   5188                 pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
   5189 
   5190         if (pendingActions != null) {
   5191             // Only report a successful relaunch to WindowManager.
   5192             pendingActions.setReportRelaunchToWindowManager(true);
   5193         }
   5194     }
   5195 
   5196     /**
   5197      * Post a message to relaunch the activity. We do this instead of launching it immediately,
   5198      * because this will destroy the activity from which it was called and interfere with the
   5199      * lifecycle changes it was going through before. We need to make sure that we have finished
   5200      * handling current transaction item before relaunching the activity.
   5201      */
   5202     void scheduleRelaunchActivity(IBinder token) {
   5203         mH.removeMessages(H.RELAUNCH_ACTIVITY, token);
   5204         sendMessage(H.RELAUNCH_ACTIVITY, token);
   5205     }
   5206 
   5207     /** Performs the activity relaunch locally vs. requesting from system-server. */
   5208     private void handleRelaunchActivityLocally(IBinder token) {
   5209         final ActivityClientRecord r = mActivities.get(token);
   5210         if (r == null) {
   5211             Log.w(TAG, "Activity to relaunch no longer exists");
   5212             return;
   5213         }
   5214 
   5215         final int prevState = r.getLifecycleState();
   5216 
   5217         if (prevState < ON_RESUME || prevState > ON_STOP) {
   5218             Log.w(TAG, "Activity state must be in [ON_RESUME..ON_STOP] in order to be relaunched,"
   5219                     + "current state is " + prevState);
   5220             return;
   5221         }
   5222 
   5223 
   5224         // Initialize a relaunch request.
   5225         final MergedConfiguration mergedConfiguration = new MergedConfiguration(
   5226                 r.createdConfig != null ? r.createdConfig : mConfiguration,
   5227                 r.overrideConfig);
   5228         final ActivityRelaunchItem activityRelaunchItem = ActivityRelaunchItem.obtain(
   5229                 null /* pendingResults */, null /* pendingIntents */, 0 /* configChanges */,
   5230                 mergedConfiguration, r.mPreserveWindow);
   5231         // Make sure to match the existing lifecycle state in the end of the transaction.
   5232         final ActivityLifecycleItem lifecycleRequest =
   5233                 TransactionExecutorHelper.getLifecycleRequestForCurrentState(r);
   5234         // Schedule the transaction.
   5235         final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
   5236         transaction.addCallback(activityRelaunchItem);
   5237         transaction.setLifecycleStateRequest(lifecycleRequest);
   5238         executeTransaction(transaction);
   5239     }
   5240 
   5241     private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
   5242             List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
   5243             PendingTransactionActions pendingActions, boolean startsNotResumed,
   5244             Configuration overrideConfig, String reason) {
   5245         // Preserve last used intent, it may be set from Activity#setIntent().
   5246         final Intent customIntent = r.activity.mIntent;
   5247         // Need to ensure state is saved.
   5248         if (!r.paused) {
   5249             performPauseActivity(r, false, reason, null /* pendingActions */);
   5250         }
   5251         if (!r.stopped) {
   5252             callActivityOnStop(r, true /* saveState */, reason);
   5253         }
   5254 
   5255         handleDestroyActivity(r.token, false, configChanges, true, reason);
   5256 
   5257         r.activity = null;
   5258         r.window = null;
   5259         r.hideForNow = false;
   5260         r.nextIdle = null;
   5261         // Merge any pending results and pending intents; don't just replace them
   5262         if (pendingResults != null) {
   5263             if (r.pendingResults == null) {
   5264                 r.pendingResults = pendingResults;
   5265             } else {
   5266                 r.pendingResults.addAll(pendingResults);
   5267             }
   5268         }
   5269         if (pendingIntents != null) {
   5270             if (r.pendingIntents == null) {
   5271                 r.pendingIntents = pendingIntents;
   5272             } else {
   5273                 r.pendingIntents.addAll(pendingIntents);
   5274             }
   5275         }
   5276         r.startsNotResumed = startsNotResumed;
   5277         r.overrideConfig = overrideConfig;
   5278 
   5279         handleLaunchActivity(r, pendingActions, customIntent);
   5280     }
   5281 
   5282     @Override
   5283     public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) {
   5284         try {
   5285             ActivityTaskManager.getService().activityRelaunched(token);
   5286             final ActivityClientRecord r = mActivities.get(token);
   5287             if (pendingActions.shouldReportRelaunchToWindowManager() && r != null
   5288                     && r.window != null) {
   5289                 r.window.reportActivityRelaunched();
   5290             }
   5291         } catch (RemoteException e) {
   5292             throw e.rethrowFromSystemServer();
   5293         }
   5294     }
   5295 
   5296     private void callActivityOnSaveInstanceState(ActivityClientRecord r) {
   5297         r.state = new Bundle();
   5298         r.state.setAllowFds(false);
   5299         if (r.isPersistable()) {
   5300             r.persistentState = new PersistableBundle();
   5301             mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
   5302                     r.persistentState);
   5303         } else {
   5304             mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
   5305         }
   5306     }
   5307 
   5308     ArrayList<ComponentCallbacks2> collectComponentCallbacks(
   5309             boolean allActivities, Configuration newConfig) {
   5310         ArrayList<ComponentCallbacks2> callbacks
   5311                 = new ArrayList<ComponentCallbacks2>();
   5312 
   5313         synchronized (mResourcesManager) {
   5314             final int NAPP = mAllApplications.size();
   5315             for (int i=0; i<NAPP; i++) {
   5316                 callbacks.add(mAllApplications.get(i));
   5317             }
   5318             final int NACT = mActivities.size();
   5319             for (int i=0; i<NACT; i++) {
   5320                 ActivityClientRecord ar = mActivities.valueAt(i);
   5321                 Activity a = ar.activity;
   5322                 if (a != null) {
   5323                     Configuration thisConfig = applyConfigCompatMainThread(
   5324                             mCurDefaultDisplayDpi, newConfig,
   5325                             ar.packageInfo.getCompatibilityInfo());
   5326                     if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
   5327                         // If the activity is currently resumed, its configuration
   5328                         // needs to change right now.
   5329                         callbacks.add(a);
   5330                     } else if (thisConfig != null) {
   5331                         // Otherwise, we will tell it about the change
   5332                         // the next time it is resumed or shown.  Note that
   5333                         // the activity manager may, before then, decide the
   5334                         // activity needs to be destroyed to handle its new
   5335                         // configuration.
   5336                         if (DEBUG_CONFIGURATION) {
   5337                             Slog.v(TAG, "Setting activity "
   5338                                     + ar.activityInfo.name + " newConfig=" + thisConfig);
   5339                         }
   5340                         ar.newConfig = thisConfig;
   5341                     }
   5342                 }
   5343             }
   5344             final int NSVC = mServices.size();
   5345             for (int i=0; i<NSVC; i++) {
   5346                 callbacks.add(mServices.valueAt(i));
   5347             }
   5348         }
   5349         synchronized (mProviderMap) {
   5350             final int NPRV = mLocalProviders.size();
   5351             for (int i=0; i<NPRV; i++) {
   5352                 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
   5353             }
   5354         }
   5355 
   5356         return callbacks;
   5357     }
   5358 
   5359     /**
   5360      * Updates the configuration for an Activity. The ActivityClientRecord's
   5361      * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for
   5362      * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering
   5363      * the updated Configuration.
   5364      * @param r ActivityClientRecord representing the Activity.
   5365      * @param newBaseConfig The new configuration to use. This may be augmented with
   5366      *                      {@link ActivityClientRecord#overrideConfig}.
   5367      */
   5368     private void performConfigurationChangedForActivity(ActivityClientRecord r,
   5369             Configuration newBaseConfig) {
   5370         performConfigurationChangedForActivity(r, newBaseConfig,
   5371                 r.activity.getDisplayId(), false /* movedToDifferentDisplay */);
   5372     }
   5373 
   5374     /**
   5375      * Updates the configuration for an Activity. The ActivityClientRecord's
   5376      * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for
   5377      * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering
   5378      * the updated Configuration.
   5379      * @param r ActivityClientRecord representing the Activity.
   5380      * @param newBaseConfig The new configuration to use. This may be augmented with
   5381      *                      {@link ActivityClientRecord#overrideConfig}.
   5382      * @param displayId The id of the display where the Activity currently resides.
   5383      * @param movedToDifferentDisplay Indicates if the activity was moved to different display.
   5384      * @return {@link Configuration} instance sent to client, null if not sent.
   5385      */
   5386     private Configuration performConfigurationChangedForActivity(ActivityClientRecord r,
   5387             Configuration newBaseConfig, int displayId, boolean movedToDifferentDisplay) {
   5388         r.tmpConfig.setTo(newBaseConfig);
   5389         if (r.overrideConfig != null) {
   5390             r.tmpConfig.updateFrom(r.overrideConfig);
   5391         }
   5392         final Configuration reportedConfig = performActivityConfigurationChanged(r.activity,
   5393                 r.tmpConfig, r.overrideConfig, displayId, movedToDifferentDisplay);
   5394         freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
   5395         return reportedConfig;
   5396     }
   5397 
   5398     /**
   5399      * Creates a new Configuration only if override would modify base. Otherwise returns base.
   5400      * @param base The base configuration.
   5401      * @param override The update to apply to the base configuration. Can be null.
   5402      * @return A Configuration representing base with override applied.
   5403      */
   5404     private static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base,
   5405             @Nullable Configuration override) {
   5406         if (override == null) {
   5407             return base;
   5408         }
   5409         Configuration newConfig = new Configuration(base);
   5410         newConfig.updateFrom(override);
   5411         return newConfig;
   5412     }
   5413 
   5414     /**
   5415      * Decides whether to update a component's configuration and whether to inform it.
   5416      * @param cb The component callback to notify of configuration change.
   5417      * @param newConfig The new configuration.
   5418      */
   5419     private void performConfigurationChanged(ComponentCallbacks2 cb, Configuration newConfig) {
   5420         if (!REPORT_TO_ACTIVITY) {
   5421             return;
   5422         }
   5423 
   5424         // ContextThemeWrappers may override the configuration for that context. We must check and
   5425         // apply any overrides defined.
   5426         Configuration contextThemeWrapperOverrideConfig = null;
   5427         if (cb instanceof ContextThemeWrapper) {
   5428             final ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb;
   5429             contextThemeWrapperOverrideConfig = contextThemeWrapper.getOverrideConfiguration();
   5430         }
   5431 
   5432         // Apply the ContextThemeWrapper override if necessary.
   5433         // NOTE: Make sure the configurations are not modified, as they are treated as immutable
   5434         // in many places.
   5435         final Configuration configToReport = createNewConfigAndUpdateIfNotNull(
   5436                 newConfig, contextThemeWrapperOverrideConfig);
   5437         cb.onConfigurationChanged(configToReport);
   5438     }
   5439 
   5440     /**
   5441      * Decides whether to update an Activity's configuration and whether to inform it.
   5442      * @param activity The activity to notify of configuration change.
   5443      * @param newConfig The new configuration.
   5444      * @param amOverrideConfig The override config that differentiates the Activity's configuration
   5445      *                         from the base global configuration. This is supplied by
   5446      *                         ActivityManager.
   5447      * @param displayId Id of the display where activity currently resides.
   5448      * @param movedToDifferentDisplay Indicates if the activity was moved to different display.
   5449      * @return Configuration sent to client, null if no changes and not moved to different display.
   5450      */
   5451     private Configuration performActivityConfigurationChanged(Activity activity,
   5452             Configuration newConfig, Configuration amOverrideConfig, int displayId,
   5453             boolean movedToDifferentDisplay) {
   5454         if (activity == null) {
   5455             throw new IllegalArgumentException("No activity provided.");
   5456         }
   5457         final IBinder activityToken = activity.getActivityToken();
   5458         if (activityToken == null) {
   5459             throw new IllegalArgumentException("Activity token not set. Is the activity attached?");
   5460         }
   5461 
   5462         boolean shouldChangeConfig = false;
   5463         if (activity.mCurrentConfig == null) {
   5464             shouldChangeConfig = true;
   5465         } else {
   5466             // If the new config is the same as the config this Activity is already running with and
   5467             // the override config also didn't change, then don't bother calling
   5468             // onConfigurationChanged.
   5469             final int diff = activity.mCurrentConfig.diffPublicOnly(newConfig);
   5470 
   5471             if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken,
   5472                     amOverrideConfig)) {
   5473                 // Always send the task-level config changes. For system-level configuration, if
   5474                 // this activity doesn't handle any of the config changes, then don't bother
   5475                 // calling onConfigurationChanged as we're going to destroy it.
   5476                 if (!mUpdatingSystemConfig
   5477                         || (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0
   5478                         || !REPORT_TO_ACTIVITY) {
   5479                     shouldChangeConfig = true;
   5480                 }
   5481             }
   5482         }
   5483         if (!shouldChangeConfig && !movedToDifferentDisplay) {
   5484             // Nothing significant, don't proceed with updating and reporting.
   5485             return null;
   5486         }
   5487 
   5488         // Propagate the configuration change to ResourcesManager and Activity.
   5489 
   5490         // ContextThemeWrappers may override the configuration for that context. We must check and
   5491         // apply any overrides defined.
   5492         Configuration contextThemeWrapperOverrideConfig = activity.getOverrideConfiguration();
   5493 
   5494         // We only update an Activity's configuration if this is not a global configuration change.
   5495         // This must also be done before the callback, or else we violate the contract that the new
   5496         // resources are available in ComponentCallbacks2#onConfigurationChanged(Configuration).
   5497         // Also apply the ContextThemeWrapper override if necessary.
   5498         // NOTE: Make sure the configurations are not modified, as they are treated as immutable in
   5499         // many places.
   5500         final Configuration finalOverrideConfig = createNewConfigAndUpdateIfNotNull(
   5501                 amOverrideConfig, contextThemeWrapperOverrideConfig);
   5502         mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig,
   5503                 displayId, movedToDifferentDisplay);
   5504 
   5505         activity.mConfigChangeFlags = 0;
   5506         activity.mCurrentConfig = new Configuration(newConfig);
   5507 
   5508         // Apply the ContextThemeWrapper override if necessary.
   5509         // NOTE: Make sure the configurations are not modified, as they are treated as immutable
   5510         // in many places.
   5511         final Configuration configToReport = createNewConfigAndUpdateIfNotNull(newConfig,
   5512                 contextThemeWrapperOverrideConfig);
   5513 
   5514         if (!REPORT_TO_ACTIVITY) {
   5515             // Not configured to report to activity.
   5516             return configToReport;
   5517         }
   5518 
   5519         if (movedToDifferentDisplay) {
   5520             activity.dispatchMovedToDisplay(displayId, configToReport);
   5521         }
   5522 
   5523         if (shouldChangeConfig) {
   5524             activity.mCalled = false;
   5525             activity.onConfigurationChanged(configToReport);
   5526             if (!activity.mCalled) {
   5527                 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
   5528                                 " did not call through to super.onConfigurationChanged()");
   5529             }
   5530         }
   5531 
   5532         return configToReport;
   5533     }
   5534 
   5535     public final void applyConfigurationToResources(Configuration config) {
   5536         synchronized (mResourcesManager) {
   5537             mResourcesManager.applyConfigurationToResourcesLocked(config, null);
   5538         }
   5539     }
   5540 
   5541     final Configuration applyCompatConfiguration(int displayDensity) {
   5542         Configuration config = mConfiguration;
   5543         if (mCompatConfiguration == null) {
   5544             mCompatConfiguration = new Configuration();
   5545         }
   5546         mCompatConfiguration.setTo(mConfiguration);
   5547         if (mResourcesManager.applyCompatConfigurationLocked(displayDensity,
   5548                 mCompatConfiguration)) {
   5549             config = mCompatConfiguration;
   5550         }
   5551         return config;
   5552     }
   5553 
   5554     @Override
   5555     public void handleConfigurationChanged(Configuration config) {
   5556         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
   5557         mCurDefaultDisplayDpi = config.densityDpi;
   5558         mUpdatingSystemConfig = true;
   5559         try {
   5560             handleConfigurationChanged(config, null /* compat */);
   5561         } finally {
   5562             mUpdatingSystemConfig = false;
   5563         }
   5564         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   5565     }
   5566 
   5567     private void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
   5568 
   5569         int configDiff;
   5570         boolean equivalent;
   5571 
   5572         final Theme systemTheme = getSystemContext().getTheme();
   5573         final Theme systemUiTheme = getSystemUiContext().getTheme();
   5574 
   5575         synchronized (mResourcesManager) {
   5576             if (mPendingConfiguration != null) {
   5577                 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
   5578                     config = mPendingConfiguration;
   5579                     mCurDefaultDisplayDpi = config.densityDpi;
   5580                     updateDefaultDensity();
   5581                 }
   5582                 mPendingConfiguration = null;
   5583             }
   5584 
   5585             if (config == null) {
   5586                 return;
   5587             }
   5588 
   5589             // This flag tracks whether the new configuration is fundamentally equivalent to the
   5590             // existing configuration. This is necessary to determine whether non-activity callbacks
   5591             // should receive notice when the only changes are related to non-public fields.
   5592             // We do not gate calling {@link #performActivityConfigurationChanged} based on this
   5593             // flag as that method uses the same check on the activity config override as well.
   5594             equivalent = mConfiguration != null && (0 == mConfiguration.diffPublicOnly(config));
   5595 
   5596             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
   5597                     + config);
   5598 
   5599             mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
   5600             updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
   5601                     mResourcesManager.getConfiguration().getLocales());
   5602 
   5603             if (mConfiguration == null) {
   5604                 mConfiguration = new Configuration();
   5605             }
   5606             if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
   5607                 return;
   5608             }
   5609 
   5610             configDiff = mConfiguration.updateFrom(config);
   5611             config = applyCompatConfiguration(mCurDefaultDisplayDpi);
   5612 
   5613             if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
   5614                 systemTheme.rebase();
   5615             }
   5616 
   5617             if ((systemUiTheme.getChangingConfigurations() & configDiff) != 0) {
   5618                 systemUiTheme.rebase();
   5619             }
   5620         }
   5621 
   5622         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
   5623 
   5624         freeTextLayoutCachesIfNeeded(configDiff);
   5625 
   5626         if (callbacks != null) {
   5627             final int N = callbacks.size();
   5628             for (int i=0; i<N; i++) {
   5629                 ComponentCallbacks2 cb = callbacks.get(i);
   5630                 if (cb instanceof Activity) {
   5631                     // If callback is an Activity - call corresponding method to consider override
   5632                     // config and avoid onConfigurationChanged if it hasn't changed.
   5633                     Activity a = (Activity) cb;
   5634                     performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
   5635                             config);
   5636                 } else if (!equivalent) {
   5637                     performConfigurationChanged(cb, config);
   5638                 }
   5639             }
   5640         }
   5641     }
   5642 
   5643     /**
   5644      * Updates the application info.
   5645      *
   5646      * This only works in the system process. Must be called on the main thread.
   5647      */
   5648     public void handleSystemApplicationInfoChanged(@NonNull ApplicationInfo ai) {
   5649         Preconditions.checkState(mSystemThread, "Must only be called in the system process");
   5650         handleApplicationInfoChanged(ai);
   5651     }
   5652 
   5653     @VisibleForTesting(visibility = PACKAGE)
   5654     public void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) {
   5655         // Updates triggered by package installation go through a package update
   5656         // receiver. Here we try to capture ApplicationInfo changes that are
   5657         // caused by other sources, such as overlays. That means we want to be as conservative
   5658         // about code changes as possible. Take the diff of the old ApplicationInfo and the new
   5659         // to see if anything needs to change.
   5660         LoadedApk apk;
   5661         LoadedApk resApk;
   5662         // Update all affected loaded packages with new package information
   5663         synchronized (mResourcesManager) {
   5664             WeakReference<LoadedApk> ref = mPackages.get(ai.packageName);
   5665             apk = ref != null ? ref.get() : null;
   5666             ref = mResourcePackages.get(ai.packageName);
   5667             resApk = ref != null ? ref.get() : null;
   5668         }
   5669 
   5670         final String[] oldResDirs = new String[2];
   5671 
   5672         if (apk != null) {
   5673             oldResDirs[0] = apk.getResDir();
   5674             final ArrayList<String> oldPaths = new ArrayList<>();
   5675             LoadedApk.makePaths(this, apk.getApplicationInfo(), oldPaths);
   5676             apk.updateApplicationInfo(ai, oldPaths);
   5677         }
   5678         if (resApk != null) {
   5679             oldResDirs[1] = resApk.getResDir();
   5680             final ArrayList<String> oldPaths = new ArrayList<>();
   5681             LoadedApk.makePaths(this, resApk.getApplicationInfo(), oldPaths);
   5682             resApk.updateApplicationInfo(ai, oldPaths);
   5683         }
   5684 
   5685         synchronized (mResourcesManager) {
   5686             // Update all affected Resources objects to use new ResourcesImpl
   5687             mResourcesManager.applyNewResourceDirsLocked(ai, oldResDirs);
   5688         }
   5689 
   5690         ApplicationPackageManager.configurationChanged();
   5691 
   5692         // Trigger a regular Configuration change event, only with a different assetsSeq number
   5693         // so that we actually call through to all components.
   5694         // TODO(adamlesinski): Change this to make use of ActivityManager's upcoming ability to
   5695         // store configurations per-process.
   5696         Configuration newConfig = new Configuration();
   5697         newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1;
   5698         handleConfigurationChanged(newConfig, null);
   5699 
   5700         // Preserve windows to avoid black flickers when overlays change.
   5701         relaunchAllActivities(true /* preserveWindows */);
   5702     }
   5703 
   5704     static void freeTextLayoutCachesIfNeeded(int configDiff) {
   5705         if (configDiff != 0) {
   5706             // Ask text layout engine to free its caches if there is a locale change
   5707             boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
   5708             if (hasLocaleConfigChange) {
   5709                 Canvas.freeTextLayoutCaches();
   5710                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
   5711             }
   5712         }
   5713     }
   5714 
   5715     @Override
   5716     public void updatePendingActivityConfiguration(IBinder activityToken,
   5717             Configuration overrideConfig) {
   5718         final ActivityClientRecord r;
   5719         synchronized (mResourcesManager) {
   5720             r = mActivities.get(activityToken);
   5721         }
   5722 
   5723         if (r == null) {
   5724             if (DEBUG_CONFIGURATION) {
   5725                 Slog.w(TAG, "Not found target activity to update its pending config.");
   5726             }
   5727             return;
   5728         }
   5729 
   5730         synchronized (r) {
   5731             r.mPendingOverrideConfig = overrideConfig;
   5732         }
   5733     }
   5734 
   5735     /**
   5736      * Handle new activity configuration and/or move to a different display.
   5737      * @param activityToken Target activity token.
   5738      * @param overrideConfig Activity override config.
   5739      * @param displayId Id of the display where activity was moved to, -1 if there was no move and
   5740      *                  value didn't change.
   5741      */
   5742     @Override
   5743     public void handleActivityConfigurationChanged(IBinder activityToken,
   5744             Configuration overrideConfig, int displayId) {
   5745         ActivityClientRecord r = mActivities.get(activityToken);
   5746         // Check input params.
   5747         if (r == null || r.activity == null) {
   5748             if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r);
   5749             return;
   5750         }
   5751         final boolean movedToDifferentDisplay = displayId != INVALID_DISPLAY
   5752                 && displayId != r.activity.getDisplayId();
   5753 
   5754         synchronized (r) {
   5755             if (r.mPendingOverrideConfig != null
   5756                     && !r.mPendingOverrideConfig.isOtherSeqNewer(overrideConfig)) {
   5757                 overrideConfig = r.mPendingOverrideConfig;
   5758             }
   5759             r.mPendingOverrideConfig = null;
   5760         }
   5761 
   5762         if (r.overrideConfig != null && !r.overrideConfig.isOtherSeqNewer(overrideConfig)
   5763                 && !movedToDifferentDisplay) {
   5764             if (DEBUG_CONFIGURATION) {
   5765                 Slog.v(TAG, "Activity already handled newer configuration so drop this"
   5766                         + " transaction. overrideConfig=" + overrideConfig + " r.overrideConfig="
   5767                         + r.overrideConfig);
   5768             }
   5769             return;
   5770         }
   5771 
   5772         // Perform updates.
   5773         r.overrideConfig = overrideConfig;
   5774         final ViewRootImpl viewRoot = r.activity.mDecor != null
   5775             ? r.activity.mDecor.getViewRootImpl() : null;
   5776 
   5777         if (movedToDifferentDisplay) {
   5778             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity moved to display, activity:"
   5779                     + r.activityInfo.name + ", displayId=" + displayId
   5780                     + ", config=" + overrideConfig);
   5781 
   5782             final Configuration reportedConfig = performConfigurationChangedForActivity(r,
   5783                     mCompatConfiguration, displayId, true /* movedToDifferentDisplay */);
   5784             if (viewRoot != null) {
   5785                 viewRoot.onMovedToDisplay(displayId, reportedConfig);
   5786             }
   5787         } else {
   5788             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
   5789                     + r.activityInfo.name + ", config=" + overrideConfig);
   5790             performConfigurationChangedForActivity(r, mCompatConfiguration);
   5791         }
   5792         // Notify the ViewRootImpl instance about configuration changes. It may have initiated this
   5793         // update to make sure that resources are updated before updating itself.
   5794         if (viewRoot != null) {
   5795             viewRoot.updateConfiguration(displayId);
   5796         }
   5797         mSomeActivitiesChanged = true;
   5798     }
   5799 
   5800     final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
   5801         if (start) {
   5802             try {
   5803                 switch (profileType) {
   5804                     default:
   5805                         mProfiler.setProfiler(profilerInfo);
   5806                         mProfiler.startProfiling();
   5807                         break;
   5808                 }
   5809             } catch (RuntimeException e) {
   5810                 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
   5811                         + " -- can the process access this path?");
   5812             } finally {
   5813                 profilerInfo.closeFd();
   5814             }
   5815         } else {
   5816             switch (profileType) {
   5817                 default:
   5818                     mProfiler.stopProfiling();
   5819                     break;
   5820             }
   5821         }
   5822     }
   5823 
   5824     /**
   5825      * Public entrypoint to stop profiling. This is required to end profiling when the app crashes,
   5826      * so that profiler data won't be lost.
   5827      *
   5828      * @hide
   5829      */
   5830     public void stopProfiling() {
   5831         if (mProfiler != null) {
   5832             mProfiler.stopProfiling();
   5833         }
   5834     }
   5835 
   5836     static void handleDumpHeap(DumpHeapData dhd) {
   5837         if (dhd.runGc) {
   5838             System.gc();
   5839             System.runFinalization();
   5840             System.gc();
   5841         }
   5842         try (ParcelFileDescriptor fd = dhd.fd) {
   5843             if (dhd.managed) {
   5844                 Debug.dumpHprofData(dhd.path, fd.getFileDescriptor());
   5845             } else if (dhd.mallocInfo) {
   5846                 Debug.dumpNativeMallocInfo(fd.getFileDescriptor());
   5847             } else {
   5848                 Debug.dumpNativeHeap(fd.getFileDescriptor());
   5849             }
   5850         } catch (IOException e) {
   5851             if (dhd.managed) {
   5852                 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
   5853                         + " -- can the process access this path?", e);
   5854             } else {
   5855                 Slog.w(TAG, "Failed to dump heap", e);
   5856             }
   5857         } catch (RuntimeException e) {
   5858             // This should no longer happening now that we're copying the file descriptor.
   5859             Slog.wtf(TAG, "Heap dumper threw a runtime exception", e);
   5860         }
   5861         try {
   5862             ActivityManager.getService().dumpHeapFinished(dhd.path);
   5863         } catch (RemoteException e) {
   5864             throw e.rethrowFromSystemServer();
   5865         }
   5866         if (dhd.finishCallback != null) {
   5867             dhd.finishCallback.sendResult(null);
   5868         }
   5869     }
   5870 
   5871     final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
   5872         boolean hasPkgInfo = false;
   5873         switch (cmd) {
   5874             case ApplicationThreadConstants.PACKAGE_REMOVED:
   5875             case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL:
   5876             {
   5877                 final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED;
   5878                 if (packages == null) {
   5879                     break;
   5880                 }
   5881                 synchronized (mResourcesManager) {
   5882                     for (int i = packages.length - 1; i >= 0; i--) {
   5883                         if (!hasPkgInfo) {
   5884                             WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
   5885                             if (ref != null && ref.get() != null) {
   5886                                 hasPkgInfo = true;
   5887                             } else {
   5888                                 ref = mResourcePackages.get(packages[i]);
   5889                                 if (ref != null && ref.get() != null) {
   5890                                     hasPkgInfo = true;
   5891                                 }
   5892                             }
   5893                         }
   5894                         if (killApp) {
   5895                             mPackages.remove(packages[i]);
   5896                             mResourcePackages.remove(packages[i]);
   5897                         }
   5898                     }
   5899                 }
   5900                 break;
   5901             }
   5902             case ApplicationThreadConstants.PACKAGE_REPLACED:
   5903             {
   5904                 if (packages == null) {
   5905                     break;
   5906                 }
   5907 
   5908                 List<String> packagesHandled = new ArrayList<>();
   5909 
   5910                 synchronized (mResourcesManager) {
   5911                     for (int i = packages.length - 1; i >= 0; i--) {
   5912                         String packageName = packages[i];
   5913                         WeakReference<LoadedApk> ref = mPackages.get(packageName);
   5914                         LoadedApk pkgInfo = ref != null ? ref.get() : null;
   5915                         if (pkgInfo != null) {
   5916                             hasPkgInfo = true;
   5917                         } else {
   5918                             ref = mResourcePackages.get(packageName);
   5919                             pkgInfo = ref != null ? ref.get() : null;
   5920                             if (pkgInfo != null) {
   5921                                 hasPkgInfo = true;
   5922                             }
   5923                         }
   5924                         // If the package is being replaced, yet it still has a valid
   5925                         // LoadedApk object, the package was updated with _DONT_KILL.
   5926                         // Adjust it's internal references to the application info and
   5927                         // resources.
   5928                         if (pkgInfo != null) {
   5929                             packagesHandled.add(packageName);
   5930                             try {
   5931                                 final ApplicationInfo aInfo =
   5932                                         sPackageManager.getApplicationInfo(
   5933                                                 packageName,
   5934                                                 PackageManager.GET_SHARED_LIBRARY_FILES,
   5935                                                 UserHandle.myUserId());
   5936 
   5937                                 if (mActivities.size() > 0) {
   5938                                     for (ActivityClientRecord ar : mActivities.values()) {
   5939                                         if (ar.activityInfo.applicationInfo.packageName
   5940                                                 .equals(packageName)) {
   5941                                             ar.activityInfo.applicationInfo = aInfo;
   5942                                             ar.packageInfo = pkgInfo;
   5943                                         }
   5944                                     }
   5945                                 }
   5946 
   5947                                 final String[] oldResDirs = { pkgInfo.getResDir() };
   5948 
   5949                                 final ArrayList<String> oldPaths = new ArrayList<>();
   5950                                 LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths);
   5951                                 pkgInfo.updateApplicationInfo(aInfo, oldPaths);
   5952 
   5953                                 synchronized (mResourcesManager) {
   5954                                     // Update affected Resources objects to use new ResourcesImpl
   5955                                     mResourcesManager.applyNewResourceDirsLocked(aInfo, oldResDirs);
   5956                                 }
   5957                             } catch (RemoteException e) {
   5958                             }
   5959                         }
   5960                     }
   5961                 }
   5962 
   5963                 try {
   5964                     getPackageManager().notifyPackagesReplacedReceived(
   5965                             packagesHandled.toArray(new String[0]));
   5966                 } catch (RemoteException ignored) {
   5967                 }
   5968 
   5969                 break;
   5970             }
   5971         }
   5972         ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo);
   5973     }
   5974 
   5975     final void handleLowMemory() {
   5976         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
   5977 
   5978         final int N = callbacks.size();
   5979         for (int i=0; i<N; i++) {
   5980             callbacks.get(i).onLowMemory();
   5981         }
   5982 
   5983         // Ask SQLite to free up as much memory as it can, mostly from its page caches.
   5984         if (Process.myUid() != Process.SYSTEM_UID) {
   5985             int sqliteReleased = SQLiteDatabase.releaseMemory();
   5986             EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
   5987         }
   5988 
   5989         // Ask graphics to free up as much as possible (font/image caches)
   5990         Canvas.freeCaches();
   5991 
   5992         // Ask text layout engine to free also as much as possible
   5993         Canvas.freeTextLayoutCaches();
   5994 
   5995         BinderInternal.forceGc("mem");
   5996     }
   5997 
   5998     private void handleTrimMemory(int level) {
   5999         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
   6000         if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
   6001 
   6002         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
   6003 
   6004         final int N = callbacks.size();
   6005         for (int i = 0; i < N; i++) {
   6006             callbacks.get(i).onTrimMemory(level);
   6007         }
   6008 
   6009         WindowManagerGlobal.getInstance().trimMemory(level);
   6010         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6011 
   6012         if (SystemProperties.getInt("debug.am.run_gc_trim_level", Integer.MAX_VALUE) <= level) {
   6013             unscheduleGcIdler();
   6014             doGcIfNeeded("tm");
   6015         }
   6016         if (SystemProperties.getInt("debug.am.run_mallopt_trim_level", Integer.MAX_VALUE)
   6017                 <= level) {
   6018             unschedulePurgeIdler();
   6019             purgePendingResources();
   6020         }
   6021     }
   6022 
   6023     private void setupGraphicsSupport(Context context) {
   6024         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport");
   6025 
   6026         // The system package doesn't have real data directories, so don't set up cache paths.
   6027         if (!"android".equals(context.getPackageName())) {
   6028             // This cache location probably points at credential-encrypted
   6029             // storage which may not be accessible yet; assign it anyway instead
   6030             // of pointing at device-encrypted storage.
   6031             final File cacheDir = context.getCacheDir();
   6032             if (cacheDir != null) {
   6033                 // Provide a usable directory for temporary files
   6034                 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
   6035             } else {
   6036                 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
   6037                         + "due to missing cache directory");
   6038             }
   6039 
   6040             // Setup a location to store generated/compiled graphics code.
   6041             final Context deviceContext = context.createDeviceProtectedStorageContext();
   6042             final File codeCacheDir = deviceContext.getCodeCacheDir();
   6043             if (codeCacheDir != null) {
   6044                 try {
   6045                     int uid = Process.myUid();
   6046                     String[] packages = getPackageManager().getPackagesForUid(uid);
   6047                     if (packages != null) {
   6048                         HardwareRenderer.setupDiskCache(codeCacheDir);
   6049                         RenderScriptCacheDir.setupDiskCache(codeCacheDir);
   6050                     }
   6051                 } catch (RemoteException e) {
   6052                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6053                     throw e.rethrowFromSystemServer();
   6054                 }
   6055             } else {
   6056                 Log.w(TAG, "Unable to use shader/script cache: missing code-cache directory");
   6057             }
   6058         }
   6059 
   6060         GraphicsEnvironment.getInstance().setup(context, mCoreSettings);
   6061         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6062     }
   6063 
   6064     private void updateDefaultDensity() {
   6065         final int densityDpi = mCurDefaultDisplayDpi;
   6066         if (!mDensityCompatMode
   6067                 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED
   6068                 && densityDpi != DisplayMetrics.DENSITY_DEVICE) {
   6069             DisplayMetrics.DENSITY_DEVICE = densityDpi;
   6070             Bitmap.setDefaultDensity(densityDpi);
   6071         }
   6072     }
   6073 
   6074     /**
   6075      * Returns the correct library directory for the current ABI.
   6076      * <p>
   6077      * If we're dealing with a multi-arch application that has both 32 and 64 bit shared
   6078      * libraries, we might need to choose the secondary depending on what the current
   6079      * runtime's instruction set is.
   6080      */
   6081     private String getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo) {
   6082         if (appInfo.primaryCpuAbi != null && appInfo.secondaryCpuAbi != null
   6083                 && appInfo.secondaryCpuAbi.equals(insInfo.secondaryCpuAbi)) {
   6084             // Get the instruction set supported by the secondary ABI. In the presence
   6085             // of a native bridge this might be different than the one secondary ABI used.
   6086             String secondaryIsa =
   6087                     VMRuntime.getInstructionSet(appInfo.secondaryCpuAbi);
   6088             final String secondaryDexCodeIsa =
   6089                     SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
   6090             secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
   6091 
   6092             final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
   6093             if (runtimeIsa.equals(secondaryIsa)) {
   6094                 return insInfo.secondaryNativeLibraryDir;
   6095             }
   6096         }
   6097         return insInfo.nativeLibraryDir;
   6098     }
   6099 
   6100     /**
   6101      * The LocaleList set for the app's resources may have been shuffled so that the preferred
   6102      * Locale is at position 0. We must find the index of this preferred Locale in the
   6103      * original LocaleList.
   6104      */
   6105     private void updateLocaleListFromAppContext(Context context, LocaleList newLocaleList) {
   6106         final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0);
   6107         final int newLocaleListSize = newLocaleList.size();
   6108         for (int i = 0; i < newLocaleListSize; i++) {
   6109             if (bestLocale.equals(newLocaleList.get(i))) {
   6110                 LocaleList.setDefault(newLocaleList, i);
   6111                 return;
   6112             }
   6113         }
   6114 
   6115         // The app may have overridden the LocaleList with its own Locale
   6116         // (not present in the available list). Push the chosen Locale
   6117         // to the front of the list.
   6118         LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList));
   6119     }
   6120 
   6121     @UnsupportedAppUsage
   6122     private void handleBindApplication(AppBindData data) {
   6123         // Register the UI Thread as a sensitive thread to the runtime.
   6124         VMRuntime.registerSensitiveThread();
   6125         // In the case the stack depth property exists, pass it down to the runtime.
   6126         String property = SystemProperties.get("debug.allocTracker.stackDepth");
   6127         if (property.length() != 0) {
   6128             VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property));
   6129         }
   6130         if (data.trackAllocation) {
   6131             DdmVmInternal.enableRecentAllocations(true);
   6132         }
   6133 
   6134         // Note when this process has started.
   6135         Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
   6136 
   6137         mBoundApplication = data;
   6138         mConfiguration = new Configuration(data.config);
   6139         mCompatConfiguration = new Configuration(data.config);
   6140 
   6141         mProfiler = new Profiler();
   6142         String agent = null;
   6143         if (data.initProfilerInfo != null) {
   6144             mProfiler.profileFile = data.initProfilerInfo.profileFile;
   6145             mProfiler.profileFd = data.initProfilerInfo.profileFd;
   6146             mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
   6147             mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
   6148             mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;
   6149             if (data.initProfilerInfo.attachAgentDuringBind) {
   6150                 agent = data.initProfilerInfo.agent;
   6151             }
   6152         }
   6153 
   6154         // send up app name; do this *before* waiting for debugger
   6155         Process.setArgV0(data.processName);
   6156         android.ddm.DdmHandleAppName.setAppName(data.processName,
   6157                                                 UserHandle.myUserId());
   6158         VMRuntime.setProcessPackageName(data.appInfo.packageName);
   6159 
   6160         // Pass data directory path to ART. This is used for caching information and
   6161         // should be set before any application code is loaded.
   6162         VMRuntime.setProcessDataDirectory(data.appInfo.dataDir);
   6163 
   6164         if (mProfiler.profileFd != null) {
   6165             mProfiler.startProfiling();
   6166         }
   6167 
   6168         // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
   6169         // implementation to use the pool executor.  Normally, we use the
   6170         // serialized executor as the default. This has to happen in the
   6171         // main thread so the main looper is set right.
   6172         if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
   6173             AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
   6174         }
   6175 
   6176         // Let the util.*Array classes maintain "undefined" for apps targeting Pie or earlier.
   6177         UtilConfig.setThrowExceptionForUpperArrayOutOfBounds(
   6178                 data.appInfo.targetSdkVersion >= Build.VERSION_CODES.Q);
   6179 
   6180         Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
   6181 
   6182         // Prior to P, internal calls to decode Bitmaps used BitmapFactory,
   6183         // which may scale up to account for density. In P, we switched to
   6184         // ImageDecoder, which skips the upscale to save memory. ImageDecoder
   6185         // needs to still scale up in older apps, in case they rely on the
   6186         // size of the Bitmap without considering its density.
   6187         ImageDecoder.sApiLevel = data.appInfo.targetSdkVersion;
   6188 
   6189         /*
   6190          * Before spawning a new process, reset the time zone to be the system time zone.
   6191          * This needs to be done because the system time zone could have changed after the
   6192          * the spawning of this process. Without doing this this process would have the incorrect
   6193          * system time zone.
   6194          */
   6195         TimeZone.setDefault(null);
   6196 
   6197         /*
   6198          * Set the LocaleList. This may change once we create the App Context.
   6199          */
   6200         LocaleList.setDefault(data.config.getLocales());
   6201 
   6202         synchronized (mResourcesManager) {
   6203             /*
   6204              * Update the system configuration since its preloaded and might not
   6205              * reflect configuration changes. The configuration object passed
   6206              * in AppBindData can be safely assumed to be up to date
   6207              */
   6208             mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
   6209             mCurDefaultDisplayDpi = data.config.densityDpi;
   6210 
   6211             // This calls mResourcesManager so keep it within the synchronized block.
   6212             applyCompatConfiguration(mCurDefaultDisplayDpi);
   6213         }
   6214 
   6215         data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
   6216 
   6217         if (agent != null) {
   6218             handleAttachAgent(agent, data.info);
   6219         }
   6220 
   6221         /**
   6222          * Switch this process to density compatibility mode if needed.
   6223          */
   6224         if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
   6225                 == 0) {
   6226             mDensityCompatMode = true;
   6227             Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
   6228         }
   6229         updateDefaultDensity();
   6230 
   6231         final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
   6232         Boolean is24Hr = null;
   6233         if (use24HourSetting != null) {
   6234             is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
   6235         }
   6236         // null : use locale default for 12/24 hour formatting,
   6237         // false : use 12 hour format,
   6238         // true : use 24 hour format.
   6239         DateFormat.set24HourTimePref(is24Hr);
   6240 
   6241         updateDebugViewAttributeState();
   6242 
   6243         StrictMode.initThreadDefaults(data.appInfo);
   6244         StrictMode.initVmDefaults(data.appInfo);
   6245 
   6246         if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
   6247             // XXX should have option to change the port.
   6248             Debug.changeDebugPort(8100);
   6249             if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
   6250                 Slog.w(TAG, "Application " + data.info.getPackageName()
   6251                       + " is waiting for the debugger on port 8100...");
   6252 
   6253                 IActivityManager mgr = ActivityManager.getService();
   6254                 try {
   6255                     mgr.showWaitingForDebugger(mAppThread, true);
   6256                 } catch (RemoteException ex) {
   6257                     throw ex.rethrowFromSystemServer();
   6258                 }
   6259 
   6260                 Debug.waitForDebugger();
   6261 
   6262                 try {
   6263                     mgr.showWaitingForDebugger(mAppThread, false);
   6264                 } catch (RemoteException ex) {
   6265                     throw ex.rethrowFromSystemServer();
   6266                 }
   6267 
   6268             } else {
   6269                 Slog.w(TAG, "Application " + data.info.getPackageName()
   6270                       + " can be debugged on port 8100...");
   6271             }
   6272         }
   6273 
   6274         // Allow binder tracing, and application-generated systrace messages if we're profileable.
   6275         boolean isAppProfileable = data.appInfo.isProfileableByShell();
   6276         Trace.setAppTracingAllowed(isAppProfileable);
   6277         if (isAppProfileable && data.enableBinderTracking) {
   6278             Binder.enableTracing();
   6279         }
   6280 
   6281         // Initialize heap profiling.
   6282         if (isAppProfileable || Build.IS_DEBUGGABLE) {
   6283             nInitZygoteChildHeapProfiling();
   6284         }
   6285 
   6286         // Allow renderer debugging features if we're debuggable.
   6287         boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
   6288         HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
   6289         HardwareRenderer.setPackageName(data.appInfo.packageName);
   6290 
   6291         /**
   6292          * Initialize the default http proxy in this process for the reasons we set the time zone.
   6293          */
   6294         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
   6295         final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
   6296         if (b != null) {
   6297             // In pre-boot mode (doing initial launch to collect password), not
   6298             // all system is up.  This includes the connectivity service, so don't
   6299             // crash if we can't get it.
   6300             final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
   6301             try {
   6302                 Proxy.setHttpProxySystemProperty(service.getProxyForNetwork(null));
   6303             } catch (RemoteException e) {
   6304                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6305                 throw e.rethrowFromSystemServer();
   6306             }
   6307         }
   6308         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6309 
   6310         // Instrumentation info affects the class loader, so load it before
   6311         // setting up the app context.
   6312         final InstrumentationInfo ii;
   6313         if (data.instrumentationName != null) {
   6314             try {
   6315                 ii = new ApplicationPackageManager(null, getPackageManager())
   6316                         .getInstrumentationInfo(data.instrumentationName, 0);
   6317             } catch (PackageManager.NameNotFoundException e) {
   6318                 throw new RuntimeException(
   6319                         "Unable to find instrumentation info for: " + data.instrumentationName);
   6320             }
   6321 
   6322             // Warn of potential ABI mismatches.
   6323             if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi)
   6324                     || !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) {
   6325                 Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: "
   6326                         + "package[" + data.appInfo.packageName + "]: "
   6327                         + data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi
   6328                         + " instrumentation[" + ii.packageName + "]: "
   6329                         + ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi);
   6330             }
   6331 
   6332             mInstrumentationPackageName = ii.packageName;
   6333             mInstrumentationAppDir = ii.sourceDir;
   6334             mInstrumentationSplitAppDirs = ii.splitSourceDirs;
   6335             mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
   6336             mInstrumentedAppDir = data.info.getAppDir();
   6337             mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
   6338             mInstrumentedLibDir = data.info.getLibDir();
   6339         } else {
   6340             ii = null;
   6341         }
   6342 
   6343         final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
   6344         updateLocaleListFromAppContext(appContext,
   6345                 mResourcesManager.getConfiguration().getLocales());
   6346 
   6347         if (!Process.isIsolated()) {
   6348             final int oldMask = StrictMode.allowThreadDiskWritesMask();
   6349             try {
   6350                 setupGraphicsSupport(appContext);
   6351             } finally {
   6352                 StrictMode.setThreadPolicyMask(oldMask);
   6353             }
   6354         } else {
   6355             HardwareRenderer.setIsolatedProcess(true);
   6356         }
   6357 
   6358         // Install the Network Security Config Provider. This must happen before the application
   6359         // code is loaded to prevent issues with instances of TLS objects being created before
   6360         // the provider is installed.
   6361         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install");
   6362         NetworkSecurityConfigProvider.install(appContext);
   6363         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   6364 
   6365         // Continue loading instrumentation.
   6366         if (ii != null) {
   6367             ApplicationInfo instrApp;
   6368             try {
   6369                 instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0,
   6370                         UserHandle.myUserId());
   6371             } catch (RemoteException e) {
   6372                 instrApp = null;
   6373             }
   6374             if (instrApp == null) {
   6375                 instrApp = new ApplicationInfo();
   6376             }
   6377             ii.copyTo(instrApp);
   6378             instrApp.initForUser(UserHandle.myUserId());
   6379             final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
   6380                     appContext.getClassLoader(), false, true, false);
   6381 
   6382             // The test context's op package name == the target app's op package name, because
   6383             // the app ops manager checks the op package name against the real calling UID,
   6384             // which is what the target package name is associated with.
   6385             final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
   6386                     appContext.getOpPackageName());
   6387 
   6388             try {
   6389                 final ClassLoader cl = instrContext.getClassLoader();
   6390                 mInstrumentation = (Instrumentation)
   6391                     cl.loadClass(data.instrumentationName.getClassName()).newInstance();
   6392             } catch (Exception e) {
   6393                 throw new RuntimeException(
   6394                     "Unable to instantiate instrumentation "
   6395                     + data.instrumentationName + ": " + e.toString(), e);
   6396             }
   6397 
   6398             final ComponentName component = new ComponentName(ii.packageName, ii.name);
   6399             mInstrumentation.init(this, instrContext, appContext, component,
   6400                     data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
   6401 
   6402             if (mProfiler.profileFile != null && !ii.handleProfiling
   6403                     && mProfiler.profileFd == null) {
   6404                 mProfiler.handlingProfiling = true;
   6405                 final File file = new File(mProfiler.profileFile);
   6406                 file.getParentFile().mkdirs();
   6407                 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
   6408             }
   6409         } else {
   6410             mInstrumentation = new Instrumentation();
   6411             mInstrumentation.basicInit(this);
   6412         }
   6413 
   6414         if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
   6415             dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
   6416         } else {
   6417             // Small heap, clamp to the current growth limit and let the heap release
   6418             // pages after the growth limit to the non growth limit capacity. b/18387825
   6419             dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
   6420         }
   6421 
   6422         // Allow disk access during application and provider setup. This could
   6423         // block processing ordered broadcasts, but later processing would
   6424         // probably end up doing the same disk access.
   6425         Application app;
   6426         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
   6427         final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
   6428         try {
   6429             // If the app is being launched for full backup or restore, bring it up in
   6430             // a restricted environment with the base application class.
   6431             app = data.info.makeApplication(data.restrictedBackupMode, null);
   6432 
   6433             // Propagate autofill compat state
   6434             app.setAutofillOptions(data.autofillOptions);
   6435 
   6436             // Propagate Content Capture options
   6437             app.setContentCaptureOptions(data.contentCaptureOptions);
   6438 
   6439             mInitialApplication = app;
   6440 
   6441             // don't bring up providers in restricted mode; they may depend on the
   6442             // app's custom Application class
   6443             if (!data.restrictedBackupMode) {
   6444                 if (!ArrayUtils.isEmpty(data.providers)) {
   6445                     installContentProviders(app, data.providers);
   6446                 }
   6447             }
   6448 
   6449             // Do this after providers, since instrumentation tests generally start their
   6450             // test thread at this point, and we don't want that racing.
   6451             try {
   6452                 mInstrumentation.onCreate(data.instrumentationArgs);
   6453             }
   6454             catch (Exception e) {
   6455                 throw new RuntimeException(
   6456                     "Exception thrown in onCreate() of "
   6457                     + data.instrumentationName + ": " + e.toString(), e);
   6458             }
   6459             try {
   6460                 mInstrumentation.callApplicationOnCreate(app);
   6461             } catch (Exception e) {
   6462                 if (!mInstrumentation.onException(app, e)) {
   6463                     throw new RuntimeException(
   6464                       "Unable to create application " + app.getClass().getName()
   6465                       + ": " + e.toString(), e);
   6466                 }
   6467             }
   6468         } finally {
   6469             // If the app targets < O-MR1, or doesn't change the thread policy
   6470             // during startup, clobber the policy to maintain behavior of b/36951662
   6471             if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
   6472                     || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
   6473                 StrictMode.setThreadPolicy(savedPolicy);
   6474             }
   6475         }
   6476 
   6477         // Preload fonts resources
   6478         FontsContract.setApplicationContextForResources(appContext);
   6479         if (!Process.isIsolated()) {
   6480             try {
   6481                 final ApplicationInfo info =
   6482                         getPackageManager().getApplicationInfo(
   6483                                 data.appInfo.packageName,
   6484                                 PackageManager.GET_META_DATA /*flags*/,
   6485                                 UserHandle.myUserId());
   6486                 if (info.metaData != null) {
   6487                     final int preloadedFontsResource = info.metaData.getInt(
   6488                             ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
   6489                     if (preloadedFontsResource != 0) {
   6490                         data.info.getResources().preloadFonts(preloadedFontsResource);
   6491                     }
   6492                 }
   6493             } catch (RemoteException e) {
   6494                 throw e.rethrowFromSystemServer();
   6495             }
   6496         }
   6497     }
   6498 
   6499     /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
   6500         IActivityManager am = ActivityManager.getService();
   6501         if (mProfiler.profileFile != null && mProfiler.handlingProfiling
   6502                 && mProfiler.profileFd == null) {
   6503             Debug.stopMethodTracing();
   6504         }
   6505         //Slog.i(TAG, "am: " + ActivityManager.getService()
   6506         //      + ", app thr: " + mAppThread);
   6507         try {
   6508             am.finishInstrumentation(mAppThread, resultCode, results);
   6509         } catch (RemoteException ex) {
   6510             throw ex.rethrowFromSystemServer();
   6511         }
   6512     }
   6513 
   6514     @UnsupportedAppUsage
   6515     private void installContentProviders(
   6516             Context context, List<ProviderInfo> providers) {
   6517         final ArrayList<ContentProviderHolder> results = new ArrayList<>();
   6518 
   6519         for (ProviderInfo cpi : providers) {
   6520             if (DEBUG_PROVIDER) {
   6521                 StringBuilder buf = new StringBuilder(128);
   6522                 buf.append("Pub ");
   6523                 buf.append(cpi.authority);
   6524                 buf.append(": ");
   6525                 buf.append(cpi.name);
   6526                 Log.i(TAG, buf.toString());
   6527             }
   6528             ContentProviderHolder cph = installProvider(context, null, cpi,
   6529                     false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
   6530             if (cph != null) {
   6531                 cph.noReleaseNeeded = true;
   6532                 results.add(cph);
   6533             }
   6534         }
   6535 
   6536         try {
   6537             ActivityManager.getService().publishContentProviders(
   6538                 getApplicationThread(), results);
   6539         } catch (RemoteException ex) {
   6540             throw ex.rethrowFromSystemServer();
   6541         }
   6542     }
   6543 
   6544     @UnsupportedAppUsage
   6545     public final IContentProvider acquireProvider(
   6546             Context c, String auth, int userId, boolean stable) {
   6547         final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
   6548         if (provider != null) {
   6549             return provider;
   6550         }
   6551 
   6552         // There is a possible race here.  Another thread may try to acquire
   6553         // the same provider at the same time.  When this happens, we want to ensure
   6554         // that the first one wins.
   6555         // Note that we cannot hold the lock while acquiring and installing the
   6556         // provider since it might take a long time to run and it could also potentially
   6557         // be re-entrant in the case where the provider is in the same process.
   6558         ContentProviderHolder holder = null;
   6559         try {
   6560             synchronized (getGetProviderLock(auth, userId)) {
   6561                 holder = ActivityManager.getService().getContentProvider(
   6562                         getApplicationThread(), c.getOpPackageName(), auth, userId, stable);
   6563             }
   6564         } catch (RemoteException ex) {
   6565             throw ex.rethrowFromSystemServer();
   6566         }
   6567         if (holder == null) {
   6568             Slog.e(TAG, "Failed to find provider info for " + auth);
   6569             return null;
   6570         }
   6571 
   6572         // Install provider will increment the reference count for us, and break
   6573         // any ties in the race.
   6574         holder = installProvider(c, holder, holder.info,
   6575                 true /*noisy*/, holder.noReleaseNeeded, stable);
   6576         return holder.provider;
   6577     }
   6578 
   6579     private Object getGetProviderLock(String auth, int userId) {
   6580         final ProviderKey key = new ProviderKey(auth, userId);
   6581         synchronized (mGetProviderLocks) {
   6582             Object lock = mGetProviderLocks.get(key);
   6583             if (lock == null) {
   6584                 lock = key;
   6585                 mGetProviderLocks.put(key, lock);
   6586             }
   6587             return lock;
   6588         }
   6589     }
   6590 
   6591     private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
   6592         if (stable) {
   6593             prc.stableCount += 1;
   6594             if (prc.stableCount == 1) {
   6595                 // We are acquiring a new stable reference on the provider.
   6596                 int unstableDelta;
   6597                 if (prc.removePending) {
   6598                     // We have a pending remove operation, which is holding the
   6599                     // last unstable reference.  At this point we are converting
   6600                     // that unstable reference to our new stable reference.
   6601                     unstableDelta = -1;
   6602                     // Cancel the removal of the provider.
   6603                     if (DEBUG_PROVIDER) {
   6604                         Slog.v(TAG, "incProviderRef: stable "
   6605                                 + "snatched provider from the jaws of death");
   6606                     }
   6607                     prc.removePending = false;
   6608                     // There is a race! It fails to remove the message, which
   6609                     // will be handled in completeRemoveProvider().
   6610                     mH.removeMessages(H.REMOVE_PROVIDER, prc);
   6611                 } else {
   6612                     unstableDelta = 0;
   6613                 }
   6614                 try {
   6615                     if (DEBUG_PROVIDER) {
   6616                         Slog.v(TAG, "incProviderRef Now stable - "
   6617                                 + prc.holder.info.name + ": unstableDelta="
   6618                                 + unstableDelta);
   6619                     }
   6620                     ActivityManager.getService().refContentProvider(
   6621                             prc.holder.connection, 1, unstableDelta);
   6622                 } catch (RemoteException e) {
   6623                     //do nothing content provider object is dead any way
   6624                 }
   6625             }
   6626         } else {
   6627             prc.unstableCount += 1;
   6628             if (prc.unstableCount == 1) {
   6629                 // We are acquiring a new unstable reference on the provider.
   6630                 if (prc.removePending) {
   6631                     // Oh look, we actually have a remove pending for the
   6632                     // provider, which is still holding the last unstable
   6633                     // reference.  We just need to cancel that to take new
   6634                     // ownership of the reference.
   6635                     if (DEBUG_PROVIDER) {
   6636                         Slog.v(TAG, "incProviderRef: unstable "
   6637                                 + "snatched provider from the jaws of death");
   6638                     }
   6639                     prc.removePending = false;
   6640                     mH.removeMessages(H.REMOVE_PROVIDER, prc);
   6641                 } else {
   6642                     // First unstable ref, increment our count in the
   6643                     // activity manager.
   6644                     try {
   6645                         if (DEBUG_PROVIDER) {
   6646                             Slog.v(TAG, "incProviderRef: Now unstable - "
   6647                                     + prc.holder.info.name);
   6648                         }
   6649                         ActivityManager.getService().refContentProvider(
   6650                                 prc.holder.connection, 0, 1);
   6651                     } catch (RemoteException e) {
   6652                         //do nothing content provider object is dead any way
   6653                     }
   6654                 }
   6655             }
   6656         }
   6657     }
   6658 
   6659     @UnsupportedAppUsage
   6660     public final IContentProvider acquireExistingProvider(
   6661             Context c, String auth, int userId, boolean stable) {
   6662         synchronized (mProviderMap) {
   6663             final ProviderKey key = new ProviderKey(auth, userId);
   6664             final ProviderClientRecord pr = mProviderMap.get(key);
   6665             if (pr == null) {
   6666                 return null;
   6667             }
   6668 
   6669             IContentProvider provider = pr.mProvider;
   6670             IBinder jBinder = provider.asBinder();
   6671             if (!jBinder.isBinderAlive()) {
   6672                 // The hosting process of the provider has died; we can't
   6673                 // use this one.
   6674                 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
   6675                         + ": existing object's process dead");
   6676                 handleUnstableProviderDiedLocked(jBinder, true);
   6677                 return null;
   6678             }
   6679 
   6680             // Only increment the ref count if we have one.  If we don't then the
   6681             // provider is not reference counted and never needs to be released.
   6682             ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
   6683             if (prc != null) {
   6684                 incProviderRefLocked(prc, stable);
   6685             }
   6686             return provider;
   6687         }
   6688     }
   6689 
   6690     @UnsupportedAppUsage
   6691     public final boolean releaseProvider(IContentProvider provider, boolean stable) {
   6692         if (provider == null) {
   6693             return false;
   6694         }
   6695 
   6696         IBinder jBinder = provider.asBinder();
   6697         synchronized (mProviderMap) {
   6698             ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
   6699             if (prc == null) {
   6700                 // The provider has no ref count, no release is needed.
   6701                 return false;
   6702             }
   6703 
   6704             boolean lastRef = false;
   6705             if (stable) {
   6706                 if (prc.stableCount == 0) {
   6707                     if (DEBUG_PROVIDER) Slog.v(TAG,
   6708                             "releaseProvider: stable ref count already 0, how?");
   6709                     return false;
   6710                 }
   6711                 prc.stableCount -= 1;
   6712                 if (prc.stableCount == 0) {
   6713                     // What we do at this point depends on whether there are
   6714                     // any unstable refs left: if there are, we just tell the
   6715                     // activity manager to decrement its stable count; if there
   6716                     // aren't, we need to enqueue this provider to be removed,
   6717                     // and convert to holding a single unstable ref while
   6718                     // doing so.
   6719                     lastRef = prc.unstableCount == 0;
   6720                     try {
   6721                         if (DEBUG_PROVIDER) {
   6722                             Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
   6723                                     + lastRef + " - " + prc.holder.info.name);
   6724                         }
   6725                         ActivityManager.getService().refContentProvider(
   6726                                 prc.holder.connection, -1, lastRef ? 1 : 0);
   6727                     } catch (RemoteException e) {
   6728                         //do nothing content provider object is dead any way
   6729                     }
   6730                 }
   6731             } else {
   6732                 if (prc.unstableCount == 0) {
   6733                     if (DEBUG_PROVIDER) Slog.v(TAG,
   6734                             "releaseProvider: unstable ref count already 0, how?");
   6735                     return false;
   6736                 }
   6737                 prc.unstableCount -= 1;
   6738                 if (prc.unstableCount == 0) {
   6739                     // If this is the last reference, we need to enqueue
   6740                     // this provider to be removed instead of telling the
   6741                     // activity manager to remove it at this point.
   6742                     lastRef = prc.stableCount == 0;
   6743                     if (!lastRef) {
   6744                         try {
   6745                             if (DEBUG_PROVIDER) {
   6746                                 Slog.v(TAG, "releaseProvider: No longer unstable - "
   6747                                         + prc.holder.info.name);
   6748                             }
   6749                             ActivityManager.getService().refContentProvider(
   6750                                     prc.holder.connection, 0, -1);
   6751                         } catch (RemoteException e) {
   6752                             //do nothing content provider object is dead any way
   6753                         }
   6754                     }
   6755                 }
   6756             }
   6757 
   6758             if (lastRef) {
   6759                 if (!prc.removePending) {
   6760                     // Schedule the actual remove asynchronously, since we don't know the context
   6761                     // this will be called in.
   6762                     if (DEBUG_PROVIDER) {
   6763                         Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
   6764                                 + prc.holder.info.name);
   6765                     }
   6766                     prc.removePending = true;
   6767                     Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
   6768                     mH.sendMessageDelayed(msg, CONTENT_PROVIDER_RETAIN_TIME);
   6769                 } else {
   6770                     Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
   6771                 }
   6772             }
   6773             return true;
   6774         }
   6775     }
   6776 
   6777     final void completeRemoveProvider(ProviderRefCount prc) {
   6778         synchronized (mProviderMap) {
   6779             if (!prc.removePending) {
   6780                 // There was a race!  Some other client managed to acquire
   6781                 // the provider before the removal was completed.
   6782                 // Abort the removal.  We will do it later.
   6783                 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
   6784                         + "provider still in use");
   6785                 return;
   6786             }
   6787 
   6788             // More complicated race!! Some client managed to acquire the
   6789             // provider and release it before the removal was completed.
   6790             // Continue the removal, and abort the next remove message.
   6791             prc.removePending = false;
   6792 
   6793             final IBinder jBinder = prc.holder.provider.asBinder();
   6794             ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
   6795             if (existingPrc == prc) {
   6796                 mProviderRefCountMap.remove(jBinder);
   6797             }
   6798 
   6799             for (int i=mProviderMap.size()-1; i>=0; i--) {
   6800                 ProviderClientRecord pr = mProviderMap.valueAt(i);
   6801                 IBinder myBinder = pr.mProvider.asBinder();
   6802                 if (myBinder == jBinder) {
   6803                     mProviderMap.removeAt(i);
   6804                 }
   6805             }
   6806         }
   6807 
   6808         try {
   6809             if (DEBUG_PROVIDER) {
   6810                 Slog.v(TAG, "removeProvider: Invoking ActivityManagerService."
   6811                         + "removeContentProvider(" + prc.holder.info.name + ")");
   6812             }
   6813             ActivityManager.getService().removeContentProvider(
   6814                     prc.holder.connection, false);
   6815         } catch (RemoteException e) {
   6816             //do nothing content provider object is dead any way
   6817         }
   6818     }
   6819 
   6820     @UnsupportedAppUsage
   6821     final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
   6822         synchronized (mProviderMap) {
   6823             handleUnstableProviderDiedLocked(provider, fromClient);
   6824         }
   6825     }
   6826 
   6827     final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
   6828         ProviderRefCount prc = mProviderRefCountMap.get(provider);
   6829         if (prc != null) {
   6830             if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
   6831                     + provider + " " + prc.holder.info.name);
   6832             mProviderRefCountMap.remove(provider);
   6833             for (int i=mProviderMap.size()-1; i>=0; i--) {
   6834                 ProviderClientRecord pr = mProviderMap.valueAt(i);
   6835                 if (pr != null && pr.mProvider.asBinder() == provider) {
   6836                     Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
   6837                     mProviderMap.removeAt(i);
   6838                 }
   6839             }
   6840 
   6841             if (fromClient) {
   6842                 // We found out about this due to execution in our client
   6843                 // code.  Tell the activity manager about it now, to ensure
   6844                 // that the next time we go to do anything with the provider
   6845                 // it knows it is dead (so we don't race with its death
   6846                 // notification).
   6847                 try {
   6848                     ActivityManager.getService().unstableProviderDied(
   6849                             prc.holder.connection);
   6850                 } catch (RemoteException e) {
   6851                     //do nothing content provider object is dead any way
   6852                 }
   6853             }
   6854         }
   6855     }
   6856 
   6857     final void appNotRespondingViaProvider(IBinder provider) {
   6858         synchronized (mProviderMap) {
   6859             ProviderRefCount prc = mProviderRefCountMap.get(provider);
   6860             if (prc != null) {
   6861                 try {
   6862                     ActivityManager.getService()
   6863                             .appNotRespondingViaProvider(prc.holder.connection);
   6864                 } catch (RemoteException e) {
   6865                     throw e.rethrowFromSystemServer();
   6866                 }
   6867             }
   6868         }
   6869     }
   6870 
   6871     private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
   6872             ContentProvider localProvider, ContentProviderHolder holder) {
   6873         final String auths[] = holder.info.authority.split(";");
   6874         final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
   6875 
   6876         if (provider != null) {
   6877             // If this provider is hosted by the core OS and cannot be upgraded,
   6878             // then I guess we're okay doing blocking calls to it.
   6879             for (String auth : auths) {
   6880                 switch (auth) {
   6881                     case ContactsContract.AUTHORITY:
   6882                     case CallLog.AUTHORITY:
   6883                     case CallLog.SHADOW_AUTHORITY:
   6884                     case BlockedNumberContract.AUTHORITY:
   6885                     case CalendarContract.AUTHORITY:
   6886                     case Downloads.Impl.AUTHORITY:
   6887                     case "telephony":
   6888                         Binder.allowBlocking(provider.asBinder());
   6889                 }
   6890             }
   6891         }
   6892 
   6893         final ProviderClientRecord pcr = new ProviderClientRecord(
   6894                 auths, provider, localProvider, holder);
   6895         for (String auth : auths) {
   6896             final ProviderKey key = new ProviderKey(auth, userId);
   6897             final ProviderClientRecord existing = mProviderMap.get(key);
   6898             if (existing != null) {
   6899                 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
   6900                         + " already published as " + auth);
   6901             } else {
   6902                 mProviderMap.put(key, pcr);
   6903             }
   6904         }
   6905         return pcr;
   6906     }
   6907 
   6908     /**
   6909      * Installs the provider.
   6910      *
   6911      * Providers that are local to the process or that come from the system server
   6912      * may be installed permanently which is indicated by setting noReleaseNeeded to true.
   6913      * Other remote providers are reference counted.  The initial reference count
   6914      * for all reference counted providers is one.  Providers that are not reference
   6915      * counted do not have a reference count (at all).
   6916      *
   6917      * This method detects when a provider has already been installed.  When this happens,
   6918      * it increments the reference count of the existing provider (if appropriate)
   6919      * and returns the existing provider.  This can happen due to concurrent
   6920      * attempts to acquire the same provider.
   6921      */
   6922     @UnsupportedAppUsage
   6923     private ContentProviderHolder installProvider(Context context,
   6924             ContentProviderHolder holder, ProviderInfo info,
   6925             boolean noisy, boolean noReleaseNeeded, boolean stable) {
   6926         ContentProvider localProvider = null;
   6927         IContentProvider provider;
   6928         if (holder == null || holder.provider == null) {
   6929             if (DEBUG_PROVIDER || noisy) {
   6930                 Slog.d(TAG, "Loading provider " + info.authority + ": "
   6931                         + info.name);
   6932             }
   6933             Context c = null;
   6934             ApplicationInfo ai = info.applicationInfo;
   6935             if (context.getPackageName().equals(ai.packageName)) {
   6936                 c = context;
   6937             } else if (mInitialApplication != null &&
   6938                     mInitialApplication.getPackageName().equals(ai.packageName)) {
   6939                 c = mInitialApplication;
   6940             } else {
   6941                 try {
   6942                     c = context.createPackageContext(ai.packageName,
   6943                             Context.CONTEXT_INCLUDE_CODE);
   6944                 } catch (PackageManager.NameNotFoundException e) {
   6945                     // Ignore
   6946                 }
   6947             }
   6948             if (c == null) {
   6949                 Slog.w(TAG, "Unable to get context for package " +
   6950                       ai.packageName +
   6951                       " while loading content provider " +
   6952                       info.name);
   6953                 return null;
   6954             }
   6955 
   6956             if (info.splitName != null) {
   6957                 try {
   6958                     c = c.createContextForSplit(info.splitName);
   6959                 } catch (NameNotFoundException e) {
   6960                     throw new RuntimeException(e);
   6961                 }
   6962             }
   6963 
   6964             try {
   6965                 final java.lang.ClassLoader cl = c.getClassLoader();
   6966                 LoadedApk packageInfo = peekPackageInfo(ai.packageName, true);
   6967                 if (packageInfo == null) {
   6968                     // System startup case.
   6969                     packageInfo = getSystemContext().mPackageInfo;
   6970                 }
   6971                 localProvider = packageInfo.getAppFactory()
   6972                         .instantiateProvider(cl, info.name);
   6973                 provider = localProvider.getIContentProvider();
   6974                 if (provider == null) {
   6975                     Slog.e(TAG, "Failed to instantiate class " +
   6976                           info.name + " from sourceDir " +
   6977                           info.applicationInfo.sourceDir);
   6978                     return null;
   6979                 }
   6980                 if (DEBUG_PROVIDER) Slog.v(
   6981                     TAG, "Instantiating local provider " + info.name);
   6982                 // XXX Need to create the correct context for this provider.
   6983                 localProvider.attachInfo(c, info);
   6984             } catch (java.lang.Exception e) {
   6985                 if (!mInstrumentation.onException(null, e)) {
   6986                     throw new RuntimeException(
   6987                             "Unable to get provider " + info.name
   6988                             + ": " + e.toString(), e);
   6989                 }
   6990                 return null;
   6991             }
   6992         } else {
   6993             provider = holder.provider;
   6994             if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
   6995                     + info.name);
   6996         }
   6997 
   6998         ContentProviderHolder retHolder;
   6999 
   7000         synchronized (mProviderMap) {
   7001             if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
   7002                     + " / " + info.name);
   7003             IBinder jBinder = provider.asBinder();
   7004             if (localProvider != null) {
   7005                 ComponentName cname = new ComponentName(info.packageName, info.name);
   7006                 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
   7007                 if (pr != null) {
   7008                     if (DEBUG_PROVIDER) {
   7009                         Slog.v(TAG, "installProvider: lost the race, "
   7010                                 + "using existing local provider");
   7011                     }
   7012                     provider = pr.mProvider;
   7013                 } else {
   7014                     holder = new ContentProviderHolder(info);
   7015                     holder.provider = provider;
   7016                     holder.noReleaseNeeded = true;
   7017                     pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
   7018                     mLocalProviders.put(jBinder, pr);
   7019                     mLocalProvidersByName.put(cname, pr);
   7020                 }
   7021                 retHolder = pr.mHolder;
   7022             } else {
   7023                 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
   7024                 if (prc != null) {
   7025                     if (DEBUG_PROVIDER) {
   7026                         Slog.v(TAG, "installProvider: lost the race, updating ref count");
   7027                     }
   7028                     // We need to transfer our new reference to the existing
   7029                     // ref count, releasing the old one...  but only if
   7030                     // release is needed (that is, it is not running in the
   7031                     // system process).
   7032                     if (!noReleaseNeeded) {
   7033                         incProviderRefLocked(prc, stable);
   7034                         try {
   7035                             ActivityManager.getService().removeContentProvider(
   7036                                     holder.connection, stable);
   7037                         } catch (RemoteException e) {
   7038                             //do nothing content provider object is dead any way
   7039                         }
   7040                     }
   7041                 } else {
   7042                     ProviderClientRecord client = installProviderAuthoritiesLocked(
   7043                             provider, localProvider, holder);
   7044                     if (noReleaseNeeded) {
   7045                         prc = new ProviderRefCount(holder, client, 1000, 1000);
   7046                     } else {
   7047                         prc = stable
   7048                                 ? new ProviderRefCount(holder, client, 1, 0)
   7049                                 : new ProviderRefCount(holder, client, 0, 1);
   7050                     }
   7051                     mProviderRefCountMap.put(jBinder, prc);
   7052                 }
   7053                 retHolder = prc.holder;
   7054             }
   7055         }
   7056         return retHolder;
   7057     }
   7058 
   7059     private void handleRunIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) {
   7060         try {
   7061             Method main = Class.forName(entryPoint).getMethod("main", String[].class);
   7062             main.invoke(null, new Object[]{entryPointArgs});
   7063         } catch (ReflectiveOperationException e) {
   7064             throw new AndroidRuntimeException("runIsolatedEntryPoint failed", e);
   7065         }
   7066         // The process will be empty after this method returns; exit the VM now.
   7067         System.exit(0);
   7068     }
   7069 
   7070     @UnsupportedAppUsage
   7071     private void attach(boolean system, long startSeq) {
   7072         sCurrentActivityThread = this;
   7073         mSystemThread = system;
   7074         if (!system) {
   7075             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
   7076                                                     UserHandle.myUserId());
   7077             RuntimeInit.setApplicationObject(mAppThread.asBinder());
   7078             final IActivityManager mgr = ActivityManager.getService();
   7079             try {
   7080                 mgr.attachApplication(mAppThread, startSeq);
   7081             } catch (RemoteException ex) {
   7082                 throw ex.rethrowFromSystemServer();
   7083             }
   7084             // Watch for getting close to heap limit.
   7085             BinderInternal.addGcWatcher(new Runnable() {
   7086                 @Override public void run() {
   7087                     if (!mSomeActivitiesChanged) {
   7088                         return;
   7089                     }
   7090                     Runtime runtime = Runtime.getRuntime();
   7091                     long dalvikMax = runtime.maxMemory();
   7092                     long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
   7093                     if (dalvikUsed > ((3*dalvikMax)/4)) {
   7094                         if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
   7095                                 + " total=" + (runtime.totalMemory()/1024)
   7096                                 + " used=" + (dalvikUsed/1024));
   7097                         mSomeActivitiesChanged = false;
   7098                         try {
   7099                             ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
   7100                         } catch (RemoteException e) {
   7101                             throw e.rethrowFromSystemServer();
   7102                         }
   7103                     }
   7104                 }
   7105             });
   7106         } else {
   7107             // Don't set application object here -- if the system crashes,
   7108             // we can't display an alert, we just want to die die die.
   7109             android.ddm.DdmHandleAppName.setAppName("system_process",
   7110                     UserHandle.myUserId());
   7111             try {
   7112                 mInstrumentation = new Instrumentation();
   7113                 mInstrumentation.basicInit(this);
   7114                 ContextImpl context = ContextImpl.createAppContext(
   7115                         this, getSystemContext().mPackageInfo);
   7116                 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
   7117                 mInitialApplication.onCreate();
   7118             } catch (Exception e) {
   7119                 throw new RuntimeException(
   7120                         "Unable to instantiate Application():" + e.toString(), e);
   7121             }
   7122         }
   7123 
   7124         ViewRootImpl.ConfigChangedCallback configChangedCallback
   7125                 = (Configuration globalConfig) -> {
   7126             synchronized (mResourcesManager) {
   7127                 // We need to apply this change to the resources immediately, because upon returning
   7128                 // the view hierarchy will be informed about it.
   7129                 if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
   7130                         null /* compat */)) {
   7131                     updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
   7132                             mResourcesManager.getConfiguration().getLocales());
   7133 
   7134                     // This actually changed the resources! Tell everyone about it.
   7135                     if (mPendingConfiguration == null
   7136                             || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
   7137                         mPendingConfiguration = globalConfig;
   7138                         sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
   7139                     }
   7140                 }
   7141             }
   7142         };
   7143         ViewRootImpl.addConfigCallback(configChangedCallback);
   7144     }
   7145 
   7146     @UnsupportedAppUsage
   7147     public static ActivityThread systemMain() {
   7148         // The system process on low-memory devices do not get to use hardware
   7149         // accelerated drawing, since this can add too much overhead to the
   7150         // process.
   7151         if (!ActivityManager.isHighEndGfx()) {
   7152             ThreadedRenderer.disable(true);
   7153         } else {
   7154             ThreadedRenderer.enableForegroundTrimming();
   7155         }
   7156         ActivityThread thread = new ActivityThread();
   7157         thread.attach(true, 0);
   7158         return thread;
   7159     }
   7160 
   7161     public static void updateHttpProxy(@NonNull Context context) {
   7162         final ConnectivityManager cm = ConnectivityManager.from(context);
   7163         Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
   7164     }
   7165 
   7166     @UnsupportedAppUsage
   7167     public final void installSystemProviders(List<ProviderInfo> providers) {
   7168         if (providers != null) {
   7169             installContentProviders(mInitialApplication, providers);
   7170         }
   7171     }
   7172 
   7173     public int getIntCoreSetting(String key, int defaultValue) {
   7174         synchronized (mResourcesManager) {
   7175             if (mCoreSettings != null) {
   7176                 return mCoreSettings.getInt(key, defaultValue);
   7177             }
   7178             return defaultValue;
   7179         }
   7180     }
   7181 
   7182     private static class AndroidOs extends ForwardingOs {
   7183         /**
   7184          * Install selective syscall interception. For example, this is used to
   7185          * implement special filesystem paths that will be redirected to
   7186          * {@link ContentResolver#openFileDescriptor(Uri, String)}.
   7187          */
   7188         public static void install() {
   7189             // If feature is disabled, we don't need to install
   7190             if (!DEPRECATE_DATA_COLUMNS) return;
   7191 
   7192             // Install interception and make sure it sticks!
   7193             Os def = null;
   7194             do {
   7195                 def = Os.getDefault();
   7196             } while (!Os.compareAndSetDefault(def, new AndroidOs(def)));
   7197         }
   7198 
   7199         private AndroidOs(Os os) {
   7200             super(os);
   7201         }
   7202 
   7203         private FileDescriptor openDeprecatedDataPath(String path, int mode) throws ErrnoException {
   7204             final Uri uri = ContentResolver.translateDeprecatedDataPath(path);
   7205             Log.v(TAG, "Redirecting " + path + " to " + uri);
   7206 
   7207             final ContentResolver cr = currentActivityThread().getApplication()
   7208                     .getContentResolver();
   7209             try {
   7210                 final FileDescriptor fd = new FileDescriptor();
   7211                 fd.setInt$(cr.openFileDescriptor(uri,
   7212                         FileUtils.translateModePosixToString(mode)).detachFd());
   7213                 return fd;
   7214             } catch (SecurityException e) {
   7215                 throw new ErrnoException(e.getMessage(), OsConstants.EACCES);
   7216             } catch (FileNotFoundException e) {
   7217                 throw new ErrnoException(e.getMessage(), OsConstants.ENOENT);
   7218             }
   7219         }
   7220 
   7221         private void deleteDeprecatedDataPath(String path) throws ErrnoException {
   7222             final Uri uri = ContentResolver.translateDeprecatedDataPath(path);
   7223             Log.v(TAG, "Redirecting " + path + " to " + uri);
   7224 
   7225             final ContentResolver cr = currentActivityThread().getApplication()
   7226                     .getContentResolver();
   7227             try {
   7228                 if (cr.delete(uri, null, null) == 0) {
   7229                     throw new FileNotFoundException();
   7230                 }
   7231             } catch (SecurityException e) {
   7232                 throw new ErrnoException(e.getMessage(), OsConstants.EACCES);
   7233             } catch (FileNotFoundException e) {
   7234                 throw new ErrnoException(e.getMessage(), OsConstants.ENOENT);
   7235             }
   7236         }
   7237 
   7238         @Override
   7239         public boolean access(String path, int mode) throws ErrnoException {
   7240             if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) {
   7241                 // If we opened it okay, then access check succeeded
   7242                 IoUtils.closeQuietly(
   7243                         openDeprecatedDataPath(path, FileUtils.translateModeAccessToPosix(mode)));
   7244                 return true;
   7245             } else {
   7246                 return super.access(path, mode);
   7247             }
   7248         }
   7249 
   7250         @Override
   7251         public FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
   7252             if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) {
   7253                 return openDeprecatedDataPath(path, mode);
   7254             } else {
   7255                 return super.open(path, flags, mode);
   7256             }
   7257         }
   7258 
   7259         @Override
   7260         public StructStat stat(String path) throws ErrnoException {
   7261             if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) {
   7262                 final FileDescriptor fd = openDeprecatedDataPath(path, OsConstants.O_RDONLY);
   7263                 try {
   7264                     return android.system.Os.fstat(fd);
   7265                 } finally {
   7266                     IoUtils.closeQuietly(fd);
   7267                 }
   7268             } else {
   7269                 return super.stat(path);
   7270             }
   7271         }
   7272 
   7273         @Override
   7274         public void unlink(String path) throws ErrnoException {
   7275             if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) {
   7276                 deleteDeprecatedDataPath(path);
   7277             } else {
   7278                 super.unlink(path);
   7279             }
   7280         }
   7281 
   7282         @Override
   7283         public void remove(String path) throws ErrnoException {
   7284             if (path != null && path.startsWith(DEPRECATE_DATA_PREFIX)) {
   7285                 deleteDeprecatedDataPath(path);
   7286             } else {
   7287                 super.remove(path);
   7288             }
   7289         }
   7290 
   7291         @Override
   7292         public void rename(String oldPath, String newPath) throws ErrnoException {
   7293             try {
   7294                 super.rename(oldPath, newPath);
   7295             } catch (ErrnoException e) {
   7296                 if (e.errno == OsConstants.EXDEV) {
   7297                     Log.v(TAG, "Recovering failed rename " + oldPath + " to " + newPath);
   7298                     try {
   7299                         Files.move(new File(oldPath).toPath(), new File(newPath).toPath());
   7300                     } catch (IOException e2) {
   7301                         throw e;
   7302                     }
   7303                 } else {
   7304                     throw e;
   7305                 }
   7306             }
   7307         }
   7308     }
   7309 
   7310     public static void main(String[] args) {
   7311         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
   7312 
   7313         // Install selective syscall interception
   7314         AndroidOs.install();
   7315 
   7316         // CloseGuard defaults to true and can be quite spammy.  We
   7317         // disable it here, but selectively enable it later (via
   7318         // StrictMode) on debug builds, but using DropBox, not logs.
   7319         CloseGuard.setEnabled(false);
   7320 
   7321         Environment.initForCurrentUser();
   7322 
   7323         // Make sure TrustedCertificateStore looks in the right place for CA certificates
   7324         final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
   7325         TrustedCertificateStore.setDefaultUserDirectory(configDir);
   7326 
   7327         Process.setArgV0("<pre-initialized>");
   7328 
   7329         Looper.prepareMainLooper();
   7330 
   7331         // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
   7332         // It will be in the format "seq=114"
   7333         long startSeq = 0;
   7334         if (args != null) {
   7335             for (int i = args.length - 1; i >= 0; --i) {
   7336                 if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
   7337                     startSeq = Long.parseLong(
   7338                             args[i].substring(PROC_START_SEQ_IDENT.length()));
   7339                 }
   7340             }
   7341         }
   7342         ActivityThread thread = new ActivityThread();
   7343         thread.attach(false, startSeq);
   7344 
   7345         if (sMainThreadHandler == null) {
   7346             sMainThreadHandler = thread.getHandler();
   7347         }
   7348 
   7349         if (false) {
   7350             Looper.myLooper().setMessageLogging(new
   7351                     LogPrinter(Log.DEBUG, "ActivityThread"));
   7352         }
   7353 
   7354         // End of event ActivityThreadMain.
   7355         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   7356         Looper.loop();
   7357 
   7358         throw new RuntimeException("Main thread loop unexpectedly exited");
   7359     }
   7360 
   7361     private void purgePendingResources() {
   7362         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "purgePendingResources");
   7363         nPurgePendingResources();
   7364         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
   7365     }
   7366 
   7367     // ------------------ Regular JNI ------------------------
   7368     private native void nPurgePendingResources();
   7369     private native void nDumpGraphicsInfo(FileDescriptor fd);
   7370     private native void nInitZygoteChildHeapProfiling();
   7371 }
   7372