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