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