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