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