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