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