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