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