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