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