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