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