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