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