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