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