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