ActivityThread.java revision 6bdd3a155fe380735d4108ddcc50b156c62406d0
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            final Theme systemTheme = getSystemContext().getTheme();
4240            if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
4241                systemTheme.rebase();
4242            }
4243        }
4244
4245        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4246
4247        freeTextLayoutCachesIfNeeded(configDiff);
4248
4249        if (callbacks != null) {
4250            final int N = callbacks.size();
4251            for (int i=0; i<N; i++) {
4252                performConfigurationChanged(callbacks.get(i), config);
4253            }
4254        }
4255    }
4256
4257    static void freeTextLayoutCachesIfNeeded(int configDiff) {
4258        if (configDiff != 0) {
4259            // Ask text layout engine to free its caches if there is a locale change
4260            boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4261            if (hasLocaleConfigChange) {
4262                Canvas.freeTextLayoutCaches();
4263                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4264            }
4265        }
4266    }
4267
4268    final void handleActivityConfigurationChanged(ActivityConfigChangeData data) {
4269        ActivityClientRecord r = mActivities.get(data.activityToken);
4270        if (r == null || r.activity == null) {
4271            return;
4272        }
4273
4274        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4275                + r.activityInfo.name);
4276
4277        r.tmpConfig.setTo(mCompatConfiguration);
4278        if (data.overrideConfig != null) {
4279            r.overrideConfig = data.overrideConfig;
4280            r.tmpConfig.updateFrom(data.overrideConfig);
4281        }
4282        performConfigurationChanged(r.activity, r.tmpConfig);
4283
4284        freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
4285
4286        mSomeActivitiesChanged = true;
4287    }
4288
4289    final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4290        if (start) {
4291            try {
4292                switch (profileType) {
4293                    default:
4294                        mProfiler.setProfiler(profilerInfo);
4295                        mProfiler.startProfiling();
4296                        break;
4297                }
4298            } catch (RuntimeException e) {
4299                Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4300                        + " -- can the process access this path?");
4301            } finally {
4302                try {
4303                    profilerInfo.profileFd.close();
4304                } catch (IOException e) {
4305                    Slog.w(TAG, "Failure closing profile fd", e);
4306                }
4307            }
4308        } else {
4309            switch (profileType) {
4310                default:
4311                    mProfiler.stopProfiling();
4312                    break;
4313            }
4314        }
4315    }
4316
4317    static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4318        if (managed) {
4319            try {
4320                Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4321            } catch (IOException e) {
4322                Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4323                        + " -- can the process access this path?");
4324            } finally {
4325                try {
4326                    dhd.fd.close();
4327                } catch (IOException e) {
4328                    Slog.w(TAG, "Failure closing profile fd", e);
4329                }
4330            }
4331        } else {
4332            Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4333        }
4334        try {
4335            ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
4336        } catch (RemoteException e) {
4337        }
4338    }
4339
4340    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4341        boolean hasPkgInfo = false;
4342        if (packages != null) {
4343            synchronized (mResourcesManager) {
4344                for (int i=packages.length-1; i>=0; i--) {
4345                    //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4346                    if (!hasPkgInfo) {
4347                        WeakReference<LoadedApk> ref;
4348                        ref = mPackages.get(packages[i]);
4349                        if (ref != null && ref.get() != null) {
4350                            hasPkgInfo = true;
4351                        } else {
4352                            ref = mResourcePackages.get(packages[i]);
4353                            if (ref != null && ref.get() != null) {
4354                                hasPkgInfo = true;
4355                            }
4356                        }
4357                    }
4358                    mPackages.remove(packages[i]);
4359                    mResourcePackages.remove(packages[i]);
4360                }
4361            }
4362        }
4363        ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4364                hasPkgInfo);
4365    }
4366
4367    final void handleLowMemory() {
4368        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4369
4370        final int N = callbacks.size();
4371        for (int i=0; i<N; i++) {
4372            callbacks.get(i).onLowMemory();
4373        }
4374
4375        // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4376        if (Process.myUid() != Process.SYSTEM_UID) {
4377            int sqliteReleased = SQLiteDatabase.releaseMemory();
4378            EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4379        }
4380
4381        // Ask graphics to free up as much as possible (font/image caches)
4382        Canvas.freeCaches();
4383
4384        // Ask text layout engine to free also as much as possible
4385        Canvas.freeTextLayoutCaches();
4386
4387        BinderInternal.forceGc("mem");
4388    }
4389
4390    final void handleTrimMemory(int level) {
4391        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4392
4393        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4394
4395        final int N = callbacks.size();
4396        for (int i = 0; i < N; i++) {
4397            callbacks.get(i).onTrimMemory(level);
4398        }
4399
4400        WindowManagerGlobal.getInstance().trimMemory(level);
4401    }
4402
4403    private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4404        if (Process.isIsolated()) {
4405            // Isolated processes aren't going to do UI.
4406            return;
4407        }
4408        try {
4409            int uid = Process.myUid();
4410            String[] packages = getPackageManager().getPackagesForUid(uid);
4411
4412            // If there are several packages in this application we won't
4413            // initialize the graphics disk caches
4414            if (packages != null && packages.length == 1) {
4415                HardwareRenderer.setupDiskCache(cacheDir);
4416                RenderScriptCacheDir.setupDiskCache(cacheDir);
4417            }
4418        } catch (RemoteException e) {
4419            // Ignore
4420        }
4421    }
4422
4423    private void updateDefaultDensity() {
4424        if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4425                && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4426                && !mDensityCompatMode) {
4427            Slog.i(TAG, "Switching default density from "
4428                    + DisplayMetrics.DENSITY_DEVICE + " to "
4429                    + mCurDefaultDisplayDpi);
4430            DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4431            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4432        }
4433    }
4434
4435    private void handleBindApplication(AppBindData data) {
4436        mBoundApplication = data;
4437        mConfiguration = new Configuration(data.config);
4438        mCompatConfiguration = new Configuration(data.config);
4439
4440        mProfiler = new Profiler();
4441        if (data.initProfilerInfo != null) {
4442            mProfiler.profileFile = data.initProfilerInfo.profileFile;
4443            mProfiler.profileFd = data.initProfilerInfo.profileFd;
4444            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
4445            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
4446        }
4447
4448        // send up app name; do this *before* waiting for debugger
4449        Process.setArgV0(data.processName);
4450        android.ddm.DdmHandleAppName.setAppName(data.processName,
4451                                                UserHandle.myUserId());
4452
4453        if (data.persistent) {
4454            // Persistent processes on low-memory devices do not get to
4455            // use hardware accelerated drawing, since this can add too much
4456            // overhead to the process.
4457            if (!ActivityManager.isHighEndGfx()) {
4458                HardwareRenderer.disable(false);
4459            }
4460        }
4461
4462        if (mProfiler.profileFd != null) {
4463            mProfiler.startProfiling();
4464        }
4465
4466        // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4467        // implementation to use the pool executor.  Normally, we use the
4468        // serialized executor as the default. This has to happen in the
4469        // main thread so the main looper is set right.
4470        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
4471            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4472        }
4473
4474        Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
4475
4476        /*
4477         * Before spawning a new process, reset the time zone to be the system time zone.
4478         * This needs to be done because the system time zone could have changed after the
4479         * the spawning of this process. Without doing this this process would have the incorrect
4480         * system time zone.
4481         */
4482        TimeZone.setDefault(null);
4483
4484        /*
4485         * Initialize the default locale in this process for the reasons we set the time zone.
4486         */
4487        Locale.setDefault(data.config.locale);
4488
4489        /*
4490         * Update the system configuration since its preloaded and might not
4491         * reflect configuration changes. The configuration object passed
4492         * in AppBindData can be safely assumed to be up to date
4493         */
4494        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
4495        mCurDefaultDisplayDpi = data.config.densityDpi;
4496        applyCompatConfiguration(mCurDefaultDisplayDpi);
4497
4498        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
4499
4500        /**
4501         * Switch this process to density compatibility mode if needed.
4502         */
4503        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4504                == 0) {
4505            mDensityCompatMode = true;
4506            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4507        }
4508        updateDefaultDensity();
4509
4510        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
4511        if (!Process.isIsolated()) {
4512            final File cacheDir = appContext.getCacheDir();
4513
4514            if (cacheDir != null) {
4515                // Provide a usable directory for temporary files
4516                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4517            } else {
4518                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property due to missing cache directory");
4519            }
4520
4521            // Use codeCacheDir to store generated/compiled graphics code
4522            final File codeCacheDir = appContext.getCodeCacheDir();
4523            if (codeCacheDir != null) {
4524                setupGraphicsSupport(data.info, codeCacheDir);
4525            } else {
4526                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
4527            }
4528        }
4529
4530
4531        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
4532        DateFormat.set24HourTimePref(is24Hr);
4533
4534        View.mDebugViewAttributes =
4535                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
4536
4537        /**
4538         * For system applications on userdebug/eng builds, log stack
4539         * traces of disk and network access to dropbox for analysis.
4540         */
4541        if ((data.appInfo.flags &
4542             (ApplicationInfo.FLAG_SYSTEM |
4543              ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4544            StrictMode.conditionallyEnableDebugLogging();
4545        }
4546
4547        /**
4548         * For apps targetting SDK Honeycomb or later, we don't allow
4549         * network usage on the main event loop / UI thread.
4550         *
4551         * Note to those grepping:  this is what ultimately throws
4552         * NetworkOnMainThreadException ...
4553         */
4554        if (data.appInfo.targetSdkVersion > 9) {
4555            StrictMode.enableDeathOnNetwork();
4556        }
4557
4558        NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted(
4559                (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0);
4560
4561        if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4562            // XXX should have option to change the port.
4563            Debug.changeDebugPort(8100);
4564            if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
4565                Slog.w(TAG, "Application " + data.info.getPackageName()
4566                      + " is waiting for the debugger on port 8100...");
4567
4568                IActivityManager mgr = ActivityManagerNative.getDefault();
4569                try {
4570                    mgr.showWaitingForDebugger(mAppThread, true);
4571                } catch (RemoteException ex) {
4572                }
4573
4574                Debug.waitForDebugger();
4575
4576                try {
4577                    mgr.showWaitingForDebugger(mAppThread, false);
4578                } catch (RemoteException ex) {
4579                }
4580
4581            } else {
4582                Slog.w(TAG, "Application " + data.info.getPackageName()
4583                      + " can be debugged on port 8100...");
4584            }
4585        }
4586
4587        // Enable OpenGL tracing if required
4588        if (data.enableOpenGlTrace) {
4589            GLUtils.setTracingLevel(1);
4590        }
4591
4592        // Allow application-generated systrace messages if we're debuggable.
4593        boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
4594        Trace.setAppTracingAllowed(appTracingAllowed);
4595
4596        /**
4597         * Initialize the default http proxy in this process for the reasons we set the time zone.
4598         */
4599        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
4600        if (b != null) {
4601            // In pre-boot mode (doing initial launch to collect password), not
4602            // all system is up.  This includes the connectivity service, so don't
4603            // crash if we can't get it.
4604            IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4605            try {
4606                final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
4607                Proxy.setHttpProxySystemProperty(proxyInfo);
4608            } catch (RemoteException e) {}
4609        }
4610
4611        if (data.instrumentationName != null) {
4612            InstrumentationInfo ii = null;
4613            try {
4614                ii = appContext.getPackageManager().
4615                    getInstrumentationInfo(data.instrumentationName, 0);
4616            } catch (PackageManager.NameNotFoundException e) {
4617            }
4618            if (ii == null) {
4619                throw new RuntimeException(
4620                    "Unable to find instrumentation info for: "
4621                    + data.instrumentationName);
4622            }
4623
4624            mInstrumentationPackageName = ii.packageName;
4625            mInstrumentationAppDir = ii.sourceDir;
4626            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
4627            mInstrumentationLibDir = ii.nativeLibraryDir;
4628            mInstrumentedAppDir = data.info.getAppDir();
4629            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
4630            mInstrumentedLibDir = data.info.getLibDir();
4631
4632            ApplicationInfo instrApp = new ApplicationInfo();
4633            instrApp.packageName = ii.packageName;
4634            instrApp.sourceDir = ii.sourceDir;
4635            instrApp.publicSourceDir = ii.publicSourceDir;
4636            instrApp.splitSourceDirs = ii.splitSourceDirs;
4637            instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
4638            instrApp.dataDir = ii.dataDir;
4639            instrApp.nativeLibraryDir = ii.nativeLibraryDir;
4640            LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
4641                    appContext.getClassLoader(), false, true, false);
4642            ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
4643
4644            try {
4645                java.lang.ClassLoader cl = instrContext.getClassLoader();
4646                mInstrumentation = (Instrumentation)
4647                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4648            } catch (Exception e) {
4649                throw new RuntimeException(
4650                    "Unable to instantiate instrumentation "
4651                    + data.instrumentationName + ": " + e.toString(), e);
4652            }
4653
4654            mInstrumentation.init(this, instrContext, appContext,
4655                   new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
4656                   data.instrumentationUiAutomationConnection);
4657
4658            if (mProfiler.profileFile != null && !ii.handleProfiling
4659                    && mProfiler.profileFd == null) {
4660                mProfiler.handlingProfiling = true;
4661                File file = new File(mProfiler.profileFile);
4662                file.getParentFile().mkdirs();
4663                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4664            }
4665
4666        } else {
4667            mInstrumentation = new Instrumentation();
4668        }
4669
4670        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
4671            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
4672        } else {
4673            // Small heap, clamp to the current growth limit and let the heap release
4674            // pages after the growth limit to the non growth limit capacity. b/18387825
4675            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
4676        }
4677
4678        // Allow disk access during application and provider setup. This could
4679        // block processing ordered broadcasts, but later processing would
4680        // probably end up doing the same disk access.
4681        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4682        try {
4683            // If the app is being launched for full backup or restore, bring it up in
4684            // a restricted environment with the base application class.
4685            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4686            mInitialApplication = app;
4687
4688            // don't bring up providers in restricted mode; they may depend on the
4689            // app's custom Application class
4690            if (!data.restrictedBackupMode) {
4691                List<ProviderInfo> providers = data.providers;
4692                if (providers != null) {
4693                    installContentProviders(app, providers);
4694                    // For process that contains content providers, we want to
4695                    // ensure that the JIT is enabled "at some point".
4696                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4697                }
4698            }
4699
4700            // Do this after providers, since instrumentation tests generally start their
4701            // test thread at this point, and we don't want that racing.
4702            try {
4703                mInstrumentation.onCreate(data.instrumentationArgs);
4704            }
4705            catch (Exception e) {
4706                throw new RuntimeException(
4707                    "Exception thrown in onCreate() of "
4708                    + data.instrumentationName + ": " + e.toString(), e);
4709            }
4710
4711            try {
4712                mInstrumentation.callApplicationOnCreate(app);
4713            } catch (Exception e) {
4714                if (!mInstrumentation.onException(app, e)) {
4715                    throw new RuntimeException(
4716                        "Unable to create application " + app.getClass().getName()
4717                        + ": " + e.toString(), e);
4718                }
4719            }
4720        } finally {
4721            StrictMode.setThreadPolicy(savedPolicy);
4722        }
4723    }
4724
4725    /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4726        IActivityManager am = ActivityManagerNative.getDefault();
4727        if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4728                && mProfiler.profileFd == null) {
4729            Debug.stopMethodTracing();
4730        }
4731        //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
4732        //      + ", app thr: " + mAppThread);
4733        try {
4734            am.finishInstrumentation(mAppThread, resultCode, results);
4735        } catch (RemoteException ex) {
4736        }
4737    }
4738
4739    private void installContentProviders(
4740            Context context, List<ProviderInfo> providers) {
4741        final ArrayList<IActivityManager.ContentProviderHolder> results =
4742            new ArrayList<IActivityManager.ContentProviderHolder>();
4743
4744        for (ProviderInfo cpi : providers) {
4745            if (DEBUG_PROVIDER) {
4746                StringBuilder buf = new StringBuilder(128);
4747                buf.append("Pub ");
4748                buf.append(cpi.authority);
4749                buf.append(": ");
4750                buf.append(cpi.name);
4751                Log.i(TAG, buf.toString());
4752            }
4753            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4754                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4755            if (cph != null) {
4756                cph.noReleaseNeeded = true;
4757                results.add(cph);
4758            }
4759        }
4760
4761        try {
4762            ActivityManagerNative.getDefault().publishContentProviders(
4763                getApplicationThread(), results);
4764        } catch (RemoteException ex) {
4765        }
4766    }
4767
4768    public final IContentProvider acquireProvider(
4769            Context c, String auth, int userId, boolean stable) {
4770        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4771        if (provider != null) {
4772            return provider;
4773        }
4774
4775        // There is a possible race here.  Another thread may try to acquire
4776        // the same provider at the same time.  When this happens, we want to ensure
4777        // that the first one wins.
4778        // Note that we cannot hold the lock while acquiring and installing the
4779        // provider since it might take a long time to run and it could also potentially
4780        // be re-entrant in the case where the provider is in the same process.
4781        IActivityManager.ContentProviderHolder holder = null;
4782        try {
4783            holder = ActivityManagerNative.getDefault().getContentProvider(
4784                    getApplicationThread(), auth, userId, stable);
4785        } catch (RemoteException ex) {
4786        }
4787        if (holder == null) {
4788            Slog.e(TAG, "Failed to find provider info for " + auth);
4789            return null;
4790        }
4791
4792        // Install provider will increment the reference count for us, and break
4793        // any ties in the race.
4794        holder = installProvider(c, holder, holder.info,
4795                true /*noisy*/, holder.noReleaseNeeded, stable);
4796        return holder.provider;
4797    }
4798
4799    private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4800        if (stable) {
4801            prc.stableCount += 1;
4802            if (prc.stableCount == 1) {
4803                // We are acquiring a new stable reference on the provider.
4804                int unstableDelta;
4805                if (prc.removePending) {
4806                    // We have a pending remove operation, which is holding the
4807                    // last unstable reference.  At this point we are converting
4808                    // that unstable reference to our new stable reference.
4809                    unstableDelta = -1;
4810                    // Cancel the removal of the provider.
4811                    if (DEBUG_PROVIDER) {
4812                        Slog.v(TAG, "incProviderRef: stable "
4813                                + "snatched provider from the jaws of death");
4814                    }
4815                    prc.removePending = false;
4816                    // There is a race! It fails to remove the message, which
4817                    // will be handled in completeRemoveProvider().
4818                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
4819                } else {
4820                    unstableDelta = 0;
4821                }
4822                try {
4823                    if (DEBUG_PROVIDER) {
4824                        Slog.v(TAG, "incProviderRef Now stable - "
4825                                + prc.holder.info.name + ": unstableDelta="
4826                                + unstableDelta);
4827                    }
4828                    ActivityManagerNative.getDefault().refContentProvider(
4829                            prc.holder.connection, 1, unstableDelta);
4830                } catch (RemoteException e) {
4831                    //do nothing content provider object is dead any way
4832                }
4833            }
4834        } else {
4835            prc.unstableCount += 1;
4836            if (prc.unstableCount == 1) {
4837                // We are acquiring a new unstable reference on the provider.
4838                if (prc.removePending) {
4839                    // Oh look, we actually have a remove pending for the
4840                    // provider, which is still holding the last unstable
4841                    // reference.  We just need to cancel that to take new
4842                    // ownership of the reference.
4843                    if (DEBUG_PROVIDER) {
4844                        Slog.v(TAG, "incProviderRef: unstable "
4845                                + "snatched provider from the jaws of death");
4846                    }
4847                    prc.removePending = false;
4848                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
4849                } else {
4850                    // First unstable ref, increment our count in the
4851                    // activity manager.
4852                    try {
4853                        if (DEBUG_PROVIDER) {
4854                            Slog.v(TAG, "incProviderRef: Now unstable - "
4855                                    + prc.holder.info.name);
4856                        }
4857                        ActivityManagerNative.getDefault().refContentProvider(
4858                                prc.holder.connection, 0, 1);
4859                    } catch (RemoteException e) {
4860                        //do nothing content provider object is dead any way
4861                    }
4862                }
4863            }
4864        }
4865    }
4866
4867    public final IContentProvider acquireExistingProvider(
4868            Context c, String auth, int userId, boolean stable) {
4869        synchronized (mProviderMap) {
4870            final ProviderKey key = new ProviderKey(auth, userId);
4871            final ProviderClientRecord pr = mProviderMap.get(key);
4872            if (pr == null) {
4873                return null;
4874            }
4875
4876            IContentProvider provider = pr.mProvider;
4877            IBinder jBinder = provider.asBinder();
4878            if (!jBinder.isBinderAlive()) {
4879                // The hosting process of the provider has died; we can't
4880                // use this one.
4881                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4882                        + ": existing object's process dead");
4883                handleUnstableProviderDiedLocked(jBinder, true);
4884                return null;
4885            }
4886
4887            // Only increment the ref count if we have one.  If we don't then the
4888            // provider is not reference counted and never needs to be released.
4889            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4890            if (prc != null) {
4891                incProviderRefLocked(prc, stable);
4892            }
4893            return provider;
4894        }
4895    }
4896
4897    public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4898        if (provider == null) {
4899            return false;
4900        }
4901
4902        IBinder jBinder = provider.asBinder();
4903        synchronized (mProviderMap) {
4904            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4905            if (prc == null) {
4906                // The provider has no ref count, no release is needed.
4907                return false;
4908            }
4909
4910            boolean lastRef = false;
4911            if (stable) {
4912                if (prc.stableCount == 0) {
4913                    if (DEBUG_PROVIDER) Slog.v(TAG,
4914                            "releaseProvider: stable ref count already 0, how?");
4915                    return false;
4916                }
4917                prc.stableCount -= 1;
4918                if (prc.stableCount == 0) {
4919                    // What we do at this point depends on whether there are
4920                    // any unstable refs left: if there are, we just tell the
4921                    // activity manager to decrement its stable count; if there
4922                    // aren't, we need to enqueue this provider to be removed,
4923                    // and convert to holding a single unstable ref while
4924                    // doing so.
4925                    lastRef = prc.unstableCount == 0;
4926                    try {
4927                        if (DEBUG_PROVIDER) {
4928                            Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4929                                    + lastRef + " - " + prc.holder.info.name);
4930                        }
4931                        ActivityManagerNative.getDefault().refContentProvider(
4932                                prc.holder.connection, -1, lastRef ? 1 : 0);
4933                    } catch (RemoteException e) {
4934                        //do nothing content provider object is dead any way
4935                    }
4936                }
4937            } else {
4938                if (prc.unstableCount == 0) {
4939                    if (DEBUG_PROVIDER) Slog.v(TAG,
4940                            "releaseProvider: unstable ref count already 0, how?");
4941                    return false;
4942                }
4943                prc.unstableCount -= 1;
4944                if (prc.unstableCount == 0) {
4945                    // If this is the last reference, we need to enqueue
4946                    // this provider to be removed instead of telling the
4947                    // activity manager to remove it at this point.
4948                    lastRef = prc.stableCount == 0;
4949                    if (!lastRef) {
4950                        try {
4951                            if (DEBUG_PROVIDER) {
4952                                Slog.v(TAG, "releaseProvider: No longer unstable - "
4953                                        + prc.holder.info.name);
4954                            }
4955                            ActivityManagerNative.getDefault().refContentProvider(
4956                                    prc.holder.connection, 0, -1);
4957                        } catch (RemoteException e) {
4958                            //do nothing content provider object is dead any way
4959                        }
4960                    }
4961                }
4962            }
4963
4964            if (lastRef) {
4965                if (!prc.removePending) {
4966                    // Schedule the actual remove asynchronously, since we don't know the context
4967                    // this will be called in.
4968                    // TODO: it would be nice to post a delayed message, so
4969                    // if we come back and need the same provider quickly
4970                    // we will still have it available.
4971                    if (DEBUG_PROVIDER) {
4972                        Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4973                                + prc.holder.info.name);
4974                    }
4975                    prc.removePending = true;
4976                    Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4977                    mH.sendMessage(msg);
4978                } else {
4979                    Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4980                }
4981            }
4982            return true;
4983        }
4984    }
4985
4986    final void completeRemoveProvider(ProviderRefCount prc) {
4987        synchronized (mProviderMap) {
4988            if (!prc.removePending) {
4989                // There was a race!  Some other client managed to acquire
4990                // the provider before the removal was completed.
4991                // Abort the removal.  We will do it later.
4992                if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
4993                        + "provider still in use");
4994                return;
4995            }
4996
4997            // More complicated race!! Some client managed to acquire the
4998            // provider and release it before the removal was completed.
4999            // Continue the removal, and abort the next remove message.
5000            prc.removePending = false;
5001
5002            final IBinder jBinder = prc.holder.provider.asBinder();
5003            ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
5004            if (existingPrc == prc) {
5005                mProviderRefCountMap.remove(jBinder);
5006            }
5007
5008            for (int i=mProviderMap.size()-1; i>=0; i--) {
5009                ProviderClientRecord pr = mProviderMap.valueAt(i);
5010                IBinder myBinder = pr.mProvider.asBinder();
5011                if (myBinder == jBinder) {
5012                    mProviderMap.removeAt(i);
5013                }
5014            }
5015        }
5016
5017        try {
5018            if (DEBUG_PROVIDER) {
5019                Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
5020                        + "removeContentProvider(" + prc.holder.info.name + ")");
5021            }
5022            ActivityManagerNative.getDefault().removeContentProvider(
5023                    prc.holder.connection, false);
5024        } catch (RemoteException e) {
5025            //do nothing content provider object is dead any way
5026        }
5027    }
5028
5029    final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
5030        synchronized (mProviderMap) {
5031            handleUnstableProviderDiedLocked(provider, fromClient);
5032        }
5033    }
5034
5035    final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
5036        ProviderRefCount prc = mProviderRefCountMap.get(provider);
5037        if (prc != null) {
5038            if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
5039                    + provider + " " + prc.holder.info.name);
5040            mProviderRefCountMap.remove(provider);
5041            for (int i=mProviderMap.size()-1; i>=0; i--) {
5042                ProviderClientRecord pr = mProviderMap.valueAt(i);
5043                if (pr != null && pr.mProvider.asBinder() == provider) {
5044                    Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
5045                    mProviderMap.removeAt(i);
5046                }
5047            }
5048
5049            if (fromClient) {
5050                // We found out about this due to execution in our client
5051                // code.  Tell the activity manager about it now, to ensure
5052                // that the next time we go to do anything with the provider
5053                // it knows it is dead (so we don't race with its death
5054                // notification).
5055                try {
5056                    ActivityManagerNative.getDefault().unstableProviderDied(
5057                            prc.holder.connection);
5058                } catch (RemoteException e) {
5059                    //do nothing content provider object is dead any way
5060                }
5061            }
5062        }
5063    }
5064
5065    final void appNotRespondingViaProvider(IBinder provider) {
5066        synchronized (mProviderMap) {
5067            ProviderRefCount prc = mProviderRefCountMap.get(provider);
5068            if (prc != null) {
5069                try {
5070                    ActivityManagerNative.getDefault()
5071                            .appNotRespondingViaProvider(prc.holder.connection);
5072                } catch (RemoteException e) {
5073                }
5074            }
5075        }
5076    }
5077
5078    private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
5079            ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
5080        final String auths[] = holder.info.authority.split(";");
5081        final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
5082
5083        final ProviderClientRecord pcr = new ProviderClientRecord(
5084                auths, provider, localProvider, holder);
5085        for (String auth : auths) {
5086            final ProviderKey key = new ProviderKey(auth, userId);
5087            final ProviderClientRecord existing = mProviderMap.get(key);
5088            if (existing != null) {
5089                Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
5090                        + " already published as " + auth);
5091            } else {
5092                mProviderMap.put(key, pcr);
5093            }
5094        }
5095        return pcr;
5096    }
5097
5098    /**
5099     * Installs the provider.
5100     *
5101     * Providers that are local to the process or that come from the system server
5102     * may be installed permanently which is indicated by setting noReleaseNeeded to true.
5103     * Other remote providers are reference counted.  The initial reference count
5104     * for all reference counted providers is one.  Providers that are not reference
5105     * counted do not have a reference count (at all).
5106     *
5107     * This method detects when a provider has already been installed.  When this happens,
5108     * it increments the reference count of the existing provider (if appropriate)
5109     * and returns the existing provider.  This can happen due to concurrent
5110     * attempts to acquire the same provider.
5111     */
5112    private IActivityManager.ContentProviderHolder installProvider(Context context,
5113            IActivityManager.ContentProviderHolder holder, ProviderInfo info,
5114            boolean noisy, boolean noReleaseNeeded, boolean stable) {
5115        ContentProvider localProvider = null;
5116        IContentProvider provider;
5117        if (holder == null || holder.provider == null) {
5118            if (DEBUG_PROVIDER || noisy) {
5119                Slog.d(TAG, "Loading provider " + info.authority + ": "
5120                        + info.name);
5121            }
5122            Context c = null;
5123            ApplicationInfo ai = info.applicationInfo;
5124            if (context.getPackageName().equals(ai.packageName)) {
5125                c = context;
5126            } else if (mInitialApplication != null &&
5127                    mInitialApplication.getPackageName().equals(ai.packageName)) {
5128                c = mInitialApplication;
5129            } else {
5130                try {
5131                    c = context.createPackageContext(ai.packageName,
5132                            Context.CONTEXT_INCLUDE_CODE);
5133                } catch (PackageManager.NameNotFoundException e) {
5134                    // Ignore
5135                }
5136            }
5137            if (c == null) {
5138                Slog.w(TAG, "Unable to get context for package " +
5139                      ai.packageName +
5140                      " while loading content provider " +
5141                      info.name);
5142                return null;
5143            }
5144            try {
5145                final java.lang.ClassLoader cl = c.getClassLoader();
5146                localProvider = (ContentProvider)cl.
5147                    loadClass(info.name).newInstance();
5148                provider = localProvider.getIContentProvider();
5149                if (provider == null) {
5150                    Slog.e(TAG, "Failed to instantiate class " +
5151                          info.name + " from sourceDir " +
5152                          info.applicationInfo.sourceDir);
5153                    return null;
5154                }
5155                if (DEBUG_PROVIDER) Slog.v(
5156                    TAG, "Instantiating local provider " + info.name);
5157                // XXX Need to create the correct context for this provider.
5158                localProvider.attachInfo(c, info);
5159            } catch (java.lang.Exception e) {
5160                if (!mInstrumentation.onException(null, e)) {
5161                    throw new RuntimeException(
5162                            "Unable to get provider " + info.name
5163                            + ": " + e.toString(), e);
5164                }
5165                return null;
5166            }
5167        } else {
5168            provider = holder.provider;
5169            if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
5170                    + info.name);
5171        }
5172
5173        IActivityManager.ContentProviderHolder retHolder;
5174
5175        synchronized (mProviderMap) {
5176            if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
5177                    + " / " + info.name);
5178            IBinder jBinder = provider.asBinder();
5179            if (localProvider != null) {
5180                ComponentName cname = new ComponentName(info.packageName, info.name);
5181                ProviderClientRecord pr = mLocalProvidersByName.get(cname);
5182                if (pr != null) {
5183                    if (DEBUG_PROVIDER) {
5184                        Slog.v(TAG, "installProvider: lost the race, "
5185                                + "using existing local provider");
5186                    }
5187                    provider = pr.mProvider;
5188                } else {
5189                    holder = new IActivityManager.ContentProviderHolder(info);
5190                    holder.provider = provider;
5191                    holder.noReleaseNeeded = true;
5192                    pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
5193                    mLocalProviders.put(jBinder, pr);
5194                    mLocalProvidersByName.put(cname, pr);
5195                }
5196                retHolder = pr.mHolder;
5197            } else {
5198                ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5199                if (prc != null) {
5200                    if (DEBUG_PROVIDER) {
5201                        Slog.v(TAG, "installProvider: lost the race, updating ref count");
5202                    }
5203                    // We need to transfer our new reference to the existing
5204                    // ref count, releasing the old one...  but only if
5205                    // release is needed (that is, it is not running in the
5206                    // system process).
5207                    if (!noReleaseNeeded) {
5208                        incProviderRefLocked(prc, stable);
5209                        try {
5210                            ActivityManagerNative.getDefault().removeContentProvider(
5211                                    holder.connection, stable);
5212                        } catch (RemoteException e) {
5213                            //do nothing content provider object is dead any way
5214                        }
5215                    }
5216                } else {
5217                    ProviderClientRecord client = installProviderAuthoritiesLocked(
5218                            provider, localProvider, holder);
5219                    if (noReleaseNeeded) {
5220                        prc = new ProviderRefCount(holder, client, 1000, 1000);
5221                    } else {
5222                        prc = stable
5223                                ? new ProviderRefCount(holder, client, 1, 0)
5224                                : new ProviderRefCount(holder, client, 0, 1);
5225                    }
5226                    mProviderRefCountMap.put(jBinder, prc);
5227                }
5228                retHolder = prc.holder;
5229            }
5230        }
5231
5232        return retHolder;
5233    }
5234
5235    private void attach(boolean system) {
5236        sCurrentActivityThread = this;
5237        mSystemThread = system;
5238        if (!system) {
5239            ViewRootImpl.addFirstDrawHandler(new Runnable() {
5240                @Override
5241                public void run() {
5242                    ensureJitEnabled();
5243                }
5244            });
5245            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5246                                                    UserHandle.myUserId());
5247            RuntimeInit.setApplicationObject(mAppThread.asBinder());
5248            final IActivityManager mgr = ActivityManagerNative.getDefault();
5249            try {
5250                mgr.attachApplication(mAppThread);
5251            } catch (RemoteException ex) {
5252                // Ignore
5253            }
5254            // Watch for getting close to heap limit.
5255            BinderInternal.addGcWatcher(new Runnable() {
5256                @Override public void run() {
5257                    if (!mSomeActivitiesChanged) {
5258                        return;
5259                    }
5260                    Runtime runtime = Runtime.getRuntime();
5261                    long dalvikMax = runtime.maxMemory();
5262                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
5263                    if (dalvikUsed > ((3*dalvikMax)/4)) {
5264                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
5265                                + " total=" + (runtime.totalMemory()/1024)
5266                                + " used=" + (dalvikUsed/1024));
5267                        mSomeActivitiesChanged = false;
5268                        try {
5269                            mgr.releaseSomeActivities(mAppThread);
5270                        } catch (RemoteException e) {
5271                        }
5272                    }
5273                }
5274            });
5275        } else {
5276            // Don't set application object here -- if the system crashes,
5277            // we can't display an alert, we just want to die die die.
5278            android.ddm.DdmHandleAppName.setAppName("system_process",
5279                    UserHandle.myUserId());
5280            try {
5281                mInstrumentation = new Instrumentation();
5282                ContextImpl context = ContextImpl.createAppContext(
5283                        this, getSystemContext().mPackageInfo);
5284                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
5285                mInitialApplication.onCreate();
5286            } catch (Exception e) {
5287                throw new RuntimeException(
5288                        "Unable to instantiate Application():" + e.toString(), e);
5289            }
5290        }
5291
5292        // add dropbox logging to libcore
5293        DropBox.setReporter(new DropBoxReporter());
5294
5295        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5296            @Override
5297            public void onConfigurationChanged(Configuration newConfig) {
5298                synchronized (mResourcesManager) {
5299                    // We need to apply this change to the resources
5300                    // immediately, because upon returning the view
5301                    // hierarchy will be informed about it.
5302                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
5303                        // This actually changed the resources!  Tell
5304                        // everyone about it.
5305                        if (mPendingConfiguration == null ||
5306                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5307                            mPendingConfiguration = newConfig;
5308
5309                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5310                        }
5311                    }
5312                }
5313            }
5314            @Override
5315            public void onLowMemory() {
5316            }
5317            @Override
5318            public void onTrimMemory(int level) {
5319            }
5320        });
5321    }
5322
5323    public static ActivityThread systemMain() {
5324        // The system process on low-memory devices do not get to use hardware
5325        // accelerated drawing, since this can add too much overhead to the
5326        // process.
5327        if (!ActivityManager.isHighEndGfx()) {
5328            HardwareRenderer.disable(true);
5329        } else {
5330            HardwareRenderer.enableForegroundTrimming();
5331        }
5332        ActivityThread thread = new ActivityThread();
5333        thread.attach(true);
5334        return thread;
5335    }
5336
5337    public final void installSystemProviders(List<ProviderInfo> providers) {
5338        if (providers != null) {
5339            installContentProviders(mInitialApplication, providers);
5340        }
5341    }
5342
5343    public int getIntCoreSetting(String key, int defaultValue) {
5344        synchronized (mResourcesManager) {
5345            if (mCoreSettings != null) {
5346                return mCoreSettings.getInt(key, defaultValue);
5347            }
5348            return defaultValue;
5349        }
5350    }
5351
5352    private static class EventLoggingReporter implements EventLogger.Reporter {
5353        @Override
5354        public void report (int code, Object... list) {
5355            EventLog.writeEvent(code, list);
5356        }
5357    }
5358
5359    private class DropBoxReporter implements DropBox.Reporter {
5360
5361        private DropBoxManager dropBox;
5362
5363        public DropBoxReporter() {}
5364
5365        @Override
5366        public void addData(String tag, byte[] data, int flags) {
5367            ensureInitialized();
5368            dropBox.addData(tag, data, flags);
5369        }
5370
5371        @Override
5372        public void addText(String tag, String data) {
5373            ensureInitialized();
5374            dropBox.addText(tag, data);
5375        }
5376
5377        private synchronized void ensureInitialized() {
5378            if (dropBox == null) {
5379                dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
5380            }
5381        }
5382    }
5383
5384    public static void main(String[] args) {
5385        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
5386        SamplingProfilerIntegration.start();
5387
5388        // CloseGuard defaults to true and can be quite spammy.  We
5389        // disable it here, but selectively enable it later (via
5390        // StrictMode) on debug builds, but using DropBox, not logs.
5391        CloseGuard.setEnabled(false);
5392
5393        Environment.initForCurrentUser();
5394
5395        // Set the reporter for event logging in libcore
5396        EventLogger.setReporter(new EventLoggingReporter());
5397
5398        AndroidKeyStoreProvider.install();
5399
5400        // Make sure TrustedCertificateStore looks in the right place for CA certificates
5401        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
5402        TrustedCertificateStore.setDefaultUserDirectory(configDir);
5403
5404        Process.setArgV0("<pre-initialized>");
5405
5406        Looper.prepareMainLooper();
5407
5408        ActivityThread thread = new ActivityThread();
5409        thread.attach(false);
5410
5411        if (sMainThreadHandler == null) {
5412            sMainThreadHandler = thread.getHandler();
5413        }
5414
5415        if (false) {
5416            Looper.myLooper().setMessageLogging(new
5417                    LogPrinter(Log.DEBUG, "ActivityThread"));
5418        }
5419
5420        // End of event ActivityThreadMain.
5421        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5422        Looper.loop();
5423
5424        throw new RuntimeException("Main thread loop unexpectedly exited");
5425    }
5426}
5427