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