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