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