ActivityThread.java revision 3480ab45c82681399ac45d54105513baa9c041f6
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            // The code package for "android" in the system server needs
1815            // to be the system context's package.
1816            mPackages.put("android", new WeakReference<LoadedApk>(getSystemContext().mPackageInfo));
1817
1818            // give ourselves a default profiler
1819            mProfiler = new Profiler();
1820        }
1821    }
1822
1823    void ensureJitEnabled() {
1824        if (!mJitEnabled) {
1825            mJitEnabled = true;
1826            dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1827        }
1828    }
1829
1830    void scheduleGcIdler() {
1831        if (!mGcIdlerScheduled) {
1832            mGcIdlerScheduled = true;
1833            Looper.myQueue().addIdleHandler(mGcIdler);
1834        }
1835        mH.removeMessages(H.GC_WHEN_IDLE);
1836    }
1837
1838    void unscheduleGcIdler() {
1839        if (mGcIdlerScheduled) {
1840            mGcIdlerScheduled = false;
1841            Looper.myQueue().removeIdleHandler(mGcIdler);
1842        }
1843        mH.removeMessages(H.GC_WHEN_IDLE);
1844    }
1845
1846    void doGcIfNeeded() {
1847        mGcIdlerScheduled = false;
1848        final long now = SystemClock.uptimeMillis();
1849        //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
1850        //        + "m now=" + now);
1851        if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
1852            //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
1853            BinderInternal.forceGc("bg");
1854        }
1855    }
1856
1857    private static final String HEAP_FULL_COLUMN
1858            = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
1859    private static final String HEAP_COLUMN
1860            = "%13s %8s %8s %8s %8s %8s %8s %8s";
1861
1862    // Formatting for checkin service - update version if row format changes
1863    private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
1864
1865    static void printRow(PrintWriter pw, String format, Object...objs) {
1866        pw.println(String.format(format, objs));
1867    }
1868
1869    public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
1870            boolean dumpFullInfo, boolean dumpDalvik, int pid, String processName,
1871            long nativeMax, long nativeAllocated, long nativeFree,
1872            long dalvikMax, long dalvikAllocated, long dalvikFree) {
1873
1874        // For checkin, we print one long comma-separated list of values
1875        if (checkin) {
1876            // NOTE: if you change anything significant below, also consider changing
1877            // ACTIVITY_THREAD_CHECKIN_VERSION.
1878
1879            // Header
1880            pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
1881            pw.print(pid); pw.print(',');
1882            pw.print(processName); pw.print(',');
1883
1884            // Heap info - max
1885            pw.print(nativeMax); pw.print(',');
1886            pw.print(dalvikMax); pw.print(',');
1887            pw.print("N/A,");
1888            pw.print(nativeMax + dalvikMax); pw.print(',');
1889
1890            // Heap info - allocated
1891            pw.print(nativeAllocated); pw.print(',');
1892            pw.print(dalvikAllocated); pw.print(',');
1893            pw.print("N/A,");
1894            pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
1895
1896            // Heap info - free
1897            pw.print(nativeFree); pw.print(',');
1898            pw.print(dalvikFree); pw.print(',');
1899            pw.print("N/A,");
1900            pw.print(nativeFree + dalvikFree); pw.print(',');
1901
1902            // Heap info - proportional set size
1903            pw.print(memInfo.nativePss); pw.print(',');
1904            pw.print(memInfo.dalvikPss); pw.print(',');
1905            pw.print(memInfo.otherPss); pw.print(',');
1906            pw.print(memInfo.getTotalPss()); pw.print(',');
1907
1908            // Heap info - swappable set size
1909            pw.print(memInfo.nativeSwappablePss); pw.print(',');
1910            pw.print(memInfo.dalvikSwappablePss); pw.print(',');
1911            pw.print(memInfo.otherSwappablePss); pw.print(',');
1912            pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
1913
1914            // Heap info - shared dirty
1915            pw.print(memInfo.nativeSharedDirty); pw.print(',');
1916            pw.print(memInfo.dalvikSharedDirty); pw.print(',');
1917            pw.print(memInfo.otherSharedDirty); pw.print(',');
1918            pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
1919
1920            // Heap info - shared clean
1921            pw.print(memInfo.nativeSharedClean); pw.print(',');
1922            pw.print(memInfo.dalvikSharedClean); pw.print(',');
1923            pw.print(memInfo.otherSharedClean); pw.print(',');
1924            pw.print(memInfo.getTotalSharedClean()); pw.print(',');
1925
1926            // Heap info - private Dirty
1927            pw.print(memInfo.nativePrivateDirty); pw.print(',');
1928            pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
1929            pw.print(memInfo.otherPrivateDirty); pw.print(',');
1930            pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
1931
1932            // Heap info - private Clean
1933            pw.print(memInfo.nativePrivateClean); pw.print(',');
1934            pw.print(memInfo.dalvikPrivateClean); pw.print(',');
1935            pw.print(memInfo.otherPrivateClean); pw.print(',');
1936            pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
1937
1938            // Heap info - other areas
1939            for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1940                pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
1941                pw.print(memInfo.getOtherPss(i)); pw.print(',');
1942                pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
1943                pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
1944                pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
1945                pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
1946                pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
1947            }
1948            return;
1949        }
1950
1951        // otherwise, show human-readable format
1952        if (dumpFullInfo) {
1953            printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
1954                    "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
1955            printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
1956                    "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
1957            printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
1958                    "------", "------", "------", "------", "------", "------");
1959            printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
1960                    memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
1961                    memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
1962                    memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1963                    nativeMax, nativeAllocated, nativeFree);
1964            printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1965                    memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
1966                    memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
1967                    memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
1968                    dalvikMax, dalvikAllocated, dalvikFree);
1969        } else {
1970            printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
1971                    "Private", "Swapped", "Heap", "Heap", "Heap");
1972            printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
1973                    "Clean", "Dirty", "Size", "Alloc", "Free");
1974            printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
1975                    "------", "------", "------", "------", "------");
1976            printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
1977                    memInfo.nativePrivateDirty,
1978                    memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1979                    nativeMax, nativeAllocated, nativeFree);
1980            printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1981                    memInfo.dalvikPrivateDirty,
1982                    memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
1983                    dalvikMax, dalvikAllocated, dalvikFree);
1984        }
1985
1986        int otherPss = memInfo.otherPss;
1987        int otherSwappablePss = memInfo.otherSwappablePss;
1988        int otherSharedDirty = memInfo.otherSharedDirty;
1989        int otherPrivateDirty = memInfo.otherPrivateDirty;
1990        int otherSharedClean = memInfo.otherSharedClean;
1991        int otherPrivateClean = memInfo.otherPrivateClean;
1992        int otherSwappedOut = memInfo.otherSwappedOut;
1993
1994        for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1995            final int myPss = memInfo.getOtherPss(i);
1996            final int mySwappablePss = memInfo.getOtherSwappablePss(i);
1997            final int mySharedDirty = memInfo.getOtherSharedDirty(i);
1998            final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
1999            final int mySharedClean = memInfo.getOtherSharedClean(i);
2000            final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2001            final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2002            if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2003                    || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) {
2004                if (dumpFullInfo) {
2005                    printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2006                            myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2007                            mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
2008                } else {
2009                    printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2010                            myPss, myPrivateDirty,
2011                            myPrivateClean, mySwappedOut, "", "", "");
2012                }
2013                otherPss -= myPss;
2014                otherSwappablePss -= mySwappablePss;
2015                otherSharedDirty -= mySharedDirty;
2016                otherPrivateDirty -= myPrivateDirty;
2017                otherSharedClean -= mySharedClean;
2018                otherPrivateClean -= myPrivateClean;
2019                otherSwappedOut -= mySwappedOut;
2020            }
2021        }
2022
2023        if (dumpFullInfo) {
2024            printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
2025                    otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
2026                    otherSwappedOut, "", "", "");
2027            printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
2028                    memInfo.getTotalSwappablePss(),
2029                    memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
2030                    memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
2031                    memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
2032                    nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2033        } else {
2034            printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
2035                    otherPrivateDirty, otherPrivateClean, otherSwappedOut,
2036                    "", "", "");
2037            printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
2038                    memInfo.getTotalPrivateDirty(),
2039                    memInfo.getTotalPrivateClean(),
2040                    memInfo.getTotalSwappedOut(),
2041                    nativeMax+dalvikMax,
2042                    nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2043        }
2044
2045        if (dumpDalvik) {
2046            pw.println(" ");
2047            pw.println(" Dalvik Details");
2048
2049            for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
2050                 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
2051                final int myPss = memInfo.getOtherPss(i);
2052                final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2053                final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2054                final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2055                final int mySharedClean = memInfo.getOtherSharedClean(i);
2056                final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2057                final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2058                if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2059                        || mySharedClean != 0 || myPrivateClean != 0) {
2060                    if (dumpFullInfo) {
2061                        printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2062                                myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2063                                mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
2064                    } else {
2065                        printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2066                                myPss, myPrivateDirty,
2067                                myPrivateClean, mySwappedOut, "", "", "");
2068                    }
2069                }
2070            }
2071        }
2072    }
2073
2074    public void registerOnActivityPausedListener(Activity activity,
2075            OnActivityPausedListener listener) {
2076        synchronized (mOnPauseListeners) {
2077            ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2078            if (list == null) {
2079                list = new ArrayList<OnActivityPausedListener>();
2080                mOnPauseListeners.put(activity, list);
2081            }
2082            list.add(listener);
2083        }
2084    }
2085
2086    public void unregisterOnActivityPausedListener(Activity activity,
2087            OnActivityPausedListener listener) {
2088        synchronized (mOnPauseListeners) {
2089            ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2090            if (list != null) {
2091                list.remove(listener);
2092            }
2093        }
2094    }
2095
2096    public final ActivityInfo resolveActivityInfo(Intent intent) {
2097        ActivityInfo aInfo = intent.resolveActivityInfo(
2098                mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
2099        if (aInfo == null) {
2100            // Throw an exception.
2101            Instrumentation.checkStartActivityResult(
2102                    ActivityManager.START_CLASS_NOT_FOUND, intent);
2103        }
2104        return aInfo;
2105    }
2106
2107    public final Activity startActivityNow(Activity parent, String id,
2108        Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2109        Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2110        ActivityClientRecord r = new ActivityClientRecord();
2111            r.token = token;
2112            r.ident = 0;
2113            r.intent = intent;
2114            r.state = state;
2115            r.parent = parent;
2116            r.embeddedID = id;
2117            r.activityInfo = activityInfo;
2118            r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2119        if (localLOGV) {
2120            ComponentName compname = intent.getComponent();
2121            String name;
2122            if (compname != null) {
2123                name = compname.toShortString();
2124            } else {
2125                name = "(Intent " + intent + ").getComponent() returned null";
2126            }
2127            Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2128                    + ", comp=" + name
2129                    + ", token=" + token);
2130        }
2131        return performLaunchActivity(r, null);
2132    }
2133
2134    public final Activity getActivity(IBinder token) {
2135        return mActivities.get(token).activity;
2136    }
2137
2138    public final void sendActivityResult(
2139            IBinder token, String id, int requestCode,
2140            int resultCode, Intent data) {
2141        if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2142                + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2143        ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2144        list.add(new ResultInfo(id, requestCode, resultCode, data));
2145        mAppThread.scheduleSendResult(token, list);
2146    }
2147
2148    private void sendMessage(int what, Object obj) {
2149        sendMessage(what, obj, 0, 0, false);
2150    }
2151
2152    private void sendMessage(int what, Object obj, int arg1) {
2153        sendMessage(what, obj, arg1, 0, false);
2154    }
2155
2156    private void sendMessage(int what, Object obj, int arg1, int arg2) {
2157        sendMessage(what, obj, arg1, arg2, false);
2158    }
2159
2160    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2161        if (DEBUG_MESSAGES) Slog.v(
2162            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2163            + ": " + arg1 + " / " + obj);
2164        Message msg = Message.obtain();
2165        msg.what = what;
2166        msg.obj = obj;
2167        msg.arg1 = arg1;
2168        msg.arg2 = arg2;
2169        if (async) {
2170            msg.setAsynchronous(true);
2171        }
2172        mH.sendMessage(msg);
2173    }
2174
2175    final void scheduleContextCleanup(ContextImpl context, String who,
2176            String what) {
2177        ContextCleanupInfo cci = new ContextCleanupInfo();
2178        cci.context = context;
2179        cci.who = who;
2180        cci.what = what;
2181        sendMessage(H.CLEAN_UP_CONTEXT, cci);
2182    }
2183
2184    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2185        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2186
2187        ActivityInfo aInfo = r.activityInfo;
2188        if (r.packageInfo == null) {
2189            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2190                    Context.CONTEXT_INCLUDE_CODE);
2191        }
2192
2193        ComponentName component = r.intent.getComponent();
2194        if (component == null) {
2195            component = r.intent.resolveActivity(
2196                mInitialApplication.getPackageManager());
2197            r.intent.setComponent(component);
2198        }
2199
2200        if (r.activityInfo.targetActivity != null) {
2201            component = new ComponentName(r.activityInfo.packageName,
2202                    r.activityInfo.targetActivity);
2203        }
2204
2205        Activity activity = null;
2206        try {
2207            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2208            activity = mInstrumentation.newActivity(
2209                    cl, component.getClassName(), r.intent);
2210            StrictMode.incrementExpectedActivityCount(activity.getClass());
2211            r.intent.setExtrasClassLoader(cl);
2212            r.intent.prepareToEnterProcess();
2213            if (r.state != null) {
2214                r.state.setClassLoader(cl);
2215            }
2216        } catch (Exception e) {
2217            if (!mInstrumentation.onException(activity, e)) {
2218                throw new RuntimeException(
2219                    "Unable to instantiate activity " + component
2220                    + ": " + e.toString(), e);
2221            }
2222        }
2223
2224        try {
2225            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2226
2227            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2228            if (localLOGV) Slog.v(
2229                    TAG, r + ": app=" + app
2230                    + ", appName=" + app.getPackageName()
2231                    + ", pkg=" + r.packageInfo.getPackageName()
2232                    + ", comp=" + r.intent.getComponent().toShortString()
2233                    + ", dir=" + r.packageInfo.getAppDir());
2234
2235            if (activity != null) {
2236                Context appContext = createBaseContextForActivity(r, activity);
2237                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2238                Configuration config = new Configuration(mCompatConfiguration);
2239                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2240                        + r.activityInfo.name + " with config " + config);
2241                activity.attach(appContext, this, getInstrumentation(), r.token,
2242                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
2243                        r.embeddedID, r.lastNonConfigurationInstances, config,
2244                        r.voiceInteractor);
2245
2246                if (customIntent != null) {
2247                    activity.mIntent = customIntent;
2248                }
2249                r.lastNonConfigurationInstances = null;
2250                activity.mStartedActivity = false;
2251                int theme = r.activityInfo.getThemeResource();
2252                if (theme != 0) {
2253                    activity.setTheme(theme);
2254                }
2255
2256                activity.mCalled = false;
2257                if (r.isPersistable()) {
2258                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2259                } else {
2260                    mInstrumentation.callActivityOnCreate(activity, r.state);
2261                }
2262                if (!activity.mCalled) {
2263                    throw new SuperNotCalledException(
2264                        "Activity " + r.intent.getComponent().toShortString() +
2265                        " did not call through to super.onCreate()");
2266                }
2267                r.activity = activity;
2268                r.stopped = true;
2269                if (!r.activity.mFinished) {
2270                    activity.performStart();
2271                    r.stopped = false;
2272                }
2273                if (!r.activity.mFinished) {
2274                    if (r.isPersistable()) {
2275                        if (r.state != null || r.persistentState != null) {
2276                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2277                                    r.persistentState);
2278                        }
2279                    } else if (r.state != null) {
2280                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2281                    }
2282                }
2283                if (!r.activity.mFinished) {
2284                    activity.mCalled = false;
2285                    if (r.isPersistable()) {
2286                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
2287                                r.persistentState);
2288                    } else {
2289                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
2290                    }
2291                    if (!activity.mCalled) {
2292                        throw new SuperNotCalledException(
2293                            "Activity " + r.intent.getComponent().toShortString() +
2294                            " did not call through to super.onPostCreate()");
2295                    }
2296                }
2297            }
2298            r.paused = true;
2299
2300            mActivities.put(r.token, r);
2301
2302        } catch (SuperNotCalledException e) {
2303            throw e;
2304
2305        } catch (Exception e) {
2306            if (!mInstrumentation.onException(activity, e)) {
2307                throw new RuntimeException(
2308                    "Unable to start activity " + component
2309                    + ": " + e.toString(), e);
2310            }
2311        }
2312
2313        return activity;
2314    }
2315
2316    private Context createBaseContextForActivity(ActivityClientRecord r,
2317            final Activity activity) {
2318        ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
2319        appContext.setOuterContext(activity);
2320        Context baseContext = appContext;
2321
2322        final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2323        try {
2324            IActivityContainer container =
2325                    ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token);
2326            final int displayId =
2327                    container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId();
2328            if (displayId > Display.DEFAULT_DISPLAY) {
2329                Display display = dm.getRealDisplay(displayId, r.token);
2330                baseContext = appContext.createDisplayContext(display);
2331            }
2332        } catch (RemoteException e) {
2333        }
2334
2335        // For debugging purposes, if the activity's package name contains the value of
2336        // the "debug.use-second-display" system property as a substring, then show
2337        // its content on a secondary display if there is one.
2338        String pkgName = SystemProperties.get("debug.second-display.pkg");
2339        if (pkgName != null && !pkgName.isEmpty()
2340                && r.packageInfo.mPackageName.contains(pkgName)) {
2341            for (int displayId : dm.getDisplayIds()) {
2342                if (displayId != Display.DEFAULT_DISPLAY) {
2343                    Display display = dm.getRealDisplay(displayId, r.token);
2344                    baseContext = appContext.createDisplayContext(display);
2345                    break;
2346                }
2347            }
2348        }
2349        return baseContext;
2350    }
2351
2352    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2353        // If we are getting ready to gc after going to the background, well
2354        // we are back active so skip it.
2355        unscheduleGcIdler();
2356
2357        if (r.profileFd != null) {
2358            mProfiler.setProfiler(r.profileFile, r.profileFd);
2359            mProfiler.startProfiling();
2360            mProfiler.autoStopProfiler = r.autoStopProfiler;
2361        }
2362
2363        // Make sure we are running with the most recent config.
2364        handleConfigurationChanged(null, null);
2365
2366        if (localLOGV) Slog.v(
2367            TAG, "Handling launch of " + r);
2368
2369        Activity a = performLaunchActivity(r, customIntent);
2370
2371        if (a != null) {
2372            r.createdConfig = new Configuration(mConfiguration);
2373            Bundle oldState = r.state;
2374            handleResumeActivity(r.token, false, r.isForward,
2375                    !r.activity.mFinished && !r.startsNotResumed);
2376
2377            if (!r.activity.mFinished && r.startsNotResumed) {
2378                // The activity manager actually wants this one to start out
2379                // paused, because it needs to be visible but isn't in the
2380                // foreground.  We accomplish this by going through the
2381                // normal startup (because activities expect to go through
2382                // onResume() the first time they run, before their window
2383                // is displayed), and then pausing it.  However, in this case
2384                // we do -not- need to do the full pause cycle (of freezing
2385                // and such) because the activity manager assumes it can just
2386                // retain the current state it has.
2387                try {
2388                    r.activity.mCalled = false;
2389                    mInstrumentation.callActivityOnPause(r.activity);
2390                    // We need to keep around the original state, in case
2391                    // we need to be created again.  But we only do this
2392                    // for pre-Honeycomb apps, which always save their state
2393                    // when pausing, so we can not have them save their state
2394                    // when restarting from a paused state.  For HC and later,
2395                    // we want to (and can) let the state be saved as the normal
2396                    // part of stopping the activity.
2397                    if (r.isPreHoneycomb()) {
2398                        r.state = oldState;
2399                    }
2400                    if (!r.activity.mCalled) {
2401                        throw new SuperNotCalledException(
2402                            "Activity " + r.intent.getComponent().toShortString() +
2403                            " did not call through to super.onPause()");
2404                    }
2405
2406                } catch (SuperNotCalledException e) {
2407                    throw e;
2408
2409                } catch (Exception e) {
2410                    if (!mInstrumentation.onException(r.activity, e)) {
2411                        throw new RuntimeException(
2412                                "Unable to pause activity "
2413                                + r.intent.getComponent().toShortString()
2414                                + ": " + e.toString(), e);
2415                    }
2416                }
2417                r.paused = true;
2418            }
2419        } else {
2420            // If there was an error, for any reason, tell the activity
2421            // manager to stop us.
2422            try {
2423                ActivityManagerNative.getDefault()
2424                    .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
2425            } catch (RemoteException ex) {
2426                // Ignore
2427            }
2428        }
2429    }
2430
2431    private void deliverNewIntents(ActivityClientRecord r,
2432            List<Intent> intents) {
2433        final int N = intents.size();
2434        for (int i=0; i<N; i++) {
2435            Intent intent = intents.get(i);
2436            intent.setExtrasClassLoader(r.activity.getClassLoader());
2437            intent.prepareToEnterProcess();
2438            r.activity.mFragments.noteStateNotSaved();
2439            mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2440        }
2441    }
2442
2443    public final void performNewIntents(IBinder token,
2444            List<Intent> intents) {
2445        ActivityClientRecord r = mActivities.get(token);
2446        if (r != null) {
2447            final boolean resumed = !r.paused;
2448            if (resumed) {
2449                r.activity.mTemporaryPause = true;
2450                mInstrumentation.callActivityOnPause(r.activity);
2451            }
2452            deliverNewIntents(r, intents);
2453            if (resumed) {
2454                r.activity.performResume();
2455                r.activity.mTemporaryPause = false;
2456            }
2457        }
2458    }
2459
2460    private void handleNewIntent(NewIntentData data) {
2461        performNewIntents(data.token, data.intents);
2462    }
2463
2464    public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
2465        Bundle data = new Bundle();
2466        ActivityClientRecord r = mActivities.get(cmd.activityToken);
2467        if (r != null) {
2468            r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2469            r.activity.onProvideAssistData(data);
2470        }
2471        if (data.isEmpty()) {
2472            data = null;
2473        }
2474        IActivityManager mgr = ActivityManagerNative.getDefault();
2475        try {
2476            mgr.reportAssistContextExtras(cmd.requestToken, data);
2477        } catch (RemoteException e) {
2478        }
2479    }
2480
2481    public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2482        ActivityClientRecord r = mActivities.get(token);
2483        if (r != null) {
2484            r.activity.onTranslucentConversionComplete(drawComplete);
2485        }
2486    }
2487
2488    public void onNewActivityOptions(IBinder token, ActivityOptions options) {
2489        ActivityClientRecord r = mActivities.get(token);
2490        if (r != null) {
2491            r.activity.onNewActivityOptions(options);
2492        }
2493    }
2494
2495    public void handleCancelVisibleBehind(IBinder token) {
2496        ActivityClientRecord r = mActivities.get(token);
2497        if (r != null) {
2498            final Activity activity = r.activity;
2499            if (activity.mVisibleBehind) {
2500                activity.mCalled = false;
2501                activity.onVisibleBehindCancelled();
2502                // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
2503                if (!activity.mCalled) {
2504                    throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
2505                            " did not call through to super.onVisibleBehindCancelled()");
2506                }
2507                activity.mVisibleBehind = false;
2508            }
2509        }
2510        try {
2511            ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
2512        } catch (RemoteException e) {
2513        }
2514    }
2515
2516    public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
2517        ActivityClientRecord r = mActivities.get(token);
2518        if (r != null) {
2519            r.activity.onBackgroundVisibleBehindChanged(visible);
2520        }
2521    }
2522
2523    public void handleInstallProvider(ProviderInfo info) {
2524        installContentProviders(mInitialApplication, Lists.newArrayList(info));
2525    }
2526
2527    private void handleEnterAnimationComplete(IBinder token) {
2528        ActivityClientRecord r = mActivities.get(token);
2529        if (r != null) {
2530            r.activity.onEnterAnimationComplete();
2531        }
2532    }
2533
2534    private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2535
2536    /**
2537     * Return the Intent that's currently being handled by a
2538     * BroadcastReceiver on this thread, or null if none.
2539     * @hide
2540     */
2541    public static Intent getIntentBeingBroadcast() {
2542        return sCurrentBroadcastIntent.get();
2543    }
2544
2545    private void handleReceiver(ReceiverData data) {
2546        // If we are getting ready to gc after going to the background, well
2547        // we are back active so skip it.
2548        unscheduleGcIdler();
2549
2550        String component = data.intent.getComponent().getClassName();
2551
2552        LoadedApk packageInfo = getPackageInfoNoCheck(
2553                data.info.applicationInfo, data.compatInfo);
2554
2555        IActivityManager mgr = ActivityManagerNative.getDefault();
2556
2557        BroadcastReceiver receiver;
2558        try {
2559            java.lang.ClassLoader cl = packageInfo.getClassLoader();
2560            data.intent.setExtrasClassLoader(cl);
2561            data.intent.prepareToEnterProcess();
2562            data.setExtrasClassLoader(cl);
2563            receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2564        } catch (Exception e) {
2565            if (DEBUG_BROADCAST) Slog.i(TAG,
2566                    "Finishing failed broadcast to " + data.intent.getComponent());
2567            data.sendFinished(mgr);
2568            throw new RuntimeException(
2569                "Unable to instantiate receiver " + component
2570                + ": " + e.toString(), e);
2571        }
2572
2573        try {
2574            Application app = packageInfo.makeApplication(false, mInstrumentation);
2575
2576            if (localLOGV) Slog.v(
2577                TAG, "Performing receive of " + data.intent
2578                + ": app=" + app
2579                + ", appName=" + app.getPackageName()
2580                + ", pkg=" + packageInfo.getPackageName()
2581                + ", comp=" + data.intent.getComponent().toShortString()
2582                + ", dir=" + packageInfo.getAppDir());
2583
2584            ContextImpl context = (ContextImpl)app.getBaseContext();
2585            sCurrentBroadcastIntent.set(data.intent);
2586            receiver.setPendingResult(data);
2587            receiver.onReceive(context.getReceiverRestrictedContext(),
2588                    data.intent);
2589        } catch (Exception e) {
2590            if (DEBUG_BROADCAST) Slog.i(TAG,
2591                    "Finishing failed broadcast to " + data.intent.getComponent());
2592            data.sendFinished(mgr);
2593            if (!mInstrumentation.onException(receiver, e)) {
2594                throw new RuntimeException(
2595                    "Unable to start receiver " + component
2596                    + ": " + e.toString(), e);
2597            }
2598        } finally {
2599            sCurrentBroadcastIntent.set(null);
2600        }
2601
2602        if (receiver.getPendingResult() != null) {
2603            data.finish();
2604        }
2605    }
2606
2607    // Instantiate a BackupAgent and tell it that it's alive
2608    private void handleCreateBackupAgent(CreateBackupAgentData data) {
2609        if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
2610
2611        // Sanity check the requested target package's uid against ours
2612        try {
2613            PackageInfo requestedPackage = getPackageManager().getPackageInfo(
2614                    data.appInfo.packageName, 0, UserHandle.myUserId());
2615            if (requestedPackage.applicationInfo.uid != Process.myUid()) {
2616                Slog.w(TAG, "Asked to instantiate non-matching package "
2617                        + data.appInfo.packageName);
2618                return;
2619            }
2620        } catch (RemoteException e) {
2621            Slog.e(TAG, "Can't reach package manager", e);
2622            return;
2623        }
2624
2625        // no longer idle; we have backup work to do
2626        unscheduleGcIdler();
2627
2628        // instantiate the BackupAgent class named in the manifest
2629        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2630        String packageName = packageInfo.mPackageName;
2631        if (packageName == null) {
2632            Slog.d(TAG, "Asked to create backup agent for nonexistent package");
2633            return;
2634        }
2635
2636        String classname = data.appInfo.backupAgentName;
2637        // full backup operation but no app-supplied agent?  use the default implementation
2638        if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2639                || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
2640            classname = "android.app.backup.FullBackupAgent";
2641        }
2642
2643        try {
2644            IBinder binder = null;
2645            BackupAgent agent = mBackupAgents.get(packageName);
2646            if (agent != null) {
2647                // reusing the existing instance
2648                if (DEBUG_BACKUP) {
2649                    Slog.v(TAG, "Reusing existing agent instance");
2650                }
2651                binder = agent.onBind();
2652            } else {
2653                try {
2654                    if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2655
2656                    java.lang.ClassLoader cl = packageInfo.getClassLoader();
2657                    agent = (BackupAgent) cl.loadClass(classname).newInstance();
2658
2659                    // set up the agent's context
2660                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2661                    context.setOuterContext(agent);
2662                    agent.attach(context);
2663
2664                    agent.onCreate();
2665                    binder = agent.onBind();
2666                    mBackupAgents.put(packageName, agent);
2667                } catch (Exception e) {
2668                    // If this is during restore, fail silently; otherwise go
2669                    // ahead and let the user see the crash.
2670                    Slog.e(TAG, "Agent threw during creation: " + e);
2671                    if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2672                            && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
2673                        throw e;
2674                    }
2675                    // falling through with 'binder' still null
2676                }
2677            }
2678
2679            // tell the OS that we're live now
2680            try {
2681                ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2682            } catch (RemoteException e) {
2683                // nothing to do.
2684            }
2685        } catch (Exception e) {
2686            throw new RuntimeException("Unable to create BackupAgent "
2687                    + classname + ": " + e.toString(), e);
2688        }
2689    }
2690
2691    // Tear down a BackupAgent
2692    private void handleDestroyBackupAgent(CreateBackupAgentData data) {
2693        if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
2694
2695        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2696        String packageName = packageInfo.mPackageName;
2697        BackupAgent agent = mBackupAgents.get(packageName);
2698        if (agent != null) {
2699            try {
2700                agent.onDestroy();
2701            } catch (Exception e) {
2702                Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
2703                e.printStackTrace();
2704            }
2705            mBackupAgents.remove(packageName);
2706        } else {
2707            Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
2708        }
2709    }
2710
2711    private void handleCreateService(CreateServiceData data) {
2712        // If we are getting ready to gc after going to the background, well
2713        // we are back active so skip it.
2714        unscheduleGcIdler();
2715
2716        LoadedApk packageInfo = getPackageInfoNoCheck(
2717                data.info.applicationInfo, data.compatInfo);
2718        Service service = null;
2719        try {
2720            java.lang.ClassLoader cl = packageInfo.getClassLoader();
2721            service = (Service) cl.loadClass(data.info.name).newInstance();
2722        } catch (Exception e) {
2723            if (!mInstrumentation.onException(service, e)) {
2724                throw new RuntimeException(
2725                    "Unable to instantiate service " + data.info.name
2726                    + ": " + e.toString(), e);
2727            }
2728        }
2729
2730        try {
2731            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
2732
2733            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2734            context.setOuterContext(service);
2735
2736            Application app = packageInfo.makeApplication(false, mInstrumentation);
2737            service.attach(context, this, data.info.name, data.token, app,
2738                    ActivityManagerNative.getDefault());
2739            service.onCreate();
2740            mServices.put(data.token, service);
2741            try {
2742                ActivityManagerNative.getDefault().serviceDoneExecuting(
2743                        data.token, 0, 0, 0);
2744            } catch (RemoteException e) {
2745                // nothing to do.
2746            }
2747        } catch (Exception e) {
2748            if (!mInstrumentation.onException(service, e)) {
2749                throw new RuntimeException(
2750                    "Unable to create service " + data.info.name
2751                    + ": " + e.toString(), e);
2752            }
2753        }
2754    }
2755
2756    private void handleBindService(BindServiceData data) {
2757        Service s = mServices.get(data.token);
2758        if (DEBUG_SERVICE)
2759            Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
2760        if (s != null) {
2761            try {
2762                data.intent.setExtrasClassLoader(s.getClassLoader());
2763                data.intent.prepareToEnterProcess();
2764                try {
2765                    if (!data.rebind) {
2766                        IBinder binder = s.onBind(data.intent);
2767                        ActivityManagerNative.getDefault().publishService(
2768                                data.token, data.intent, binder);
2769                    } else {
2770                        s.onRebind(data.intent);
2771                        ActivityManagerNative.getDefault().serviceDoneExecuting(
2772                                data.token, 0, 0, 0);
2773                    }
2774                    ensureJitEnabled();
2775                } catch (RemoteException ex) {
2776                }
2777            } catch (Exception e) {
2778                if (!mInstrumentation.onException(s, e)) {
2779                    throw new RuntimeException(
2780                            "Unable to bind to service " + s
2781                            + " with " + data.intent + ": " + e.toString(), e);
2782                }
2783            }
2784        }
2785    }
2786
2787    private void handleUnbindService(BindServiceData data) {
2788        Service s = mServices.get(data.token);
2789        if (s != null) {
2790            try {
2791                data.intent.setExtrasClassLoader(s.getClassLoader());
2792                data.intent.prepareToEnterProcess();
2793                boolean doRebind = s.onUnbind(data.intent);
2794                try {
2795                    if (doRebind) {
2796                        ActivityManagerNative.getDefault().unbindFinished(
2797                                data.token, data.intent, doRebind);
2798                    } else {
2799                        ActivityManagerNative.getDefault().serviceDoneExecuting(
2800                                data.token, 0, 0, 0);
2801                    }
2802                } catch (RemoteException ex) {
2803                }
2804            } catch (Exception e) {
2805                if (!mInstrumentation.onException(s, e)) {
2806                    throw new RuntimeException(
2807                            "Unable to unbind to service " + s
2808                            + " with " + data.intent + ": " + e.toString(), e);
2809                }
2810            }
2811        }
2812    }
2813
2814    private void handleDumpService(DumpComponentInfo info) {
2815        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2816        try {
2817            Service s = mServices.get(info.token);
2818            if (s != null) {
2819                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2820                        info.fd.getFileDescriptor()));
2821                s.dump(info.fd.getFileDescriptor(), pw, info.args);
2822                pw.flush();
2823            }
2824        } finally {
2825            IoUtils.closeQuietly(info.fd);
2826            StrictMode.setThreadPolicy(oldPolicy);
2827        }
2828    }
2829
2830    private void handleDumpActivity(DumpComponentInfo info) {
2831        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2832        try {
2833            ActivityClientRecord r = mActivities.get(info.token);
2834            if (r != null && r.activity != null) {
2835                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2836                        info.fd.getFileDescriptor()));
2837                r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2838                pw.flush();
2839            }
2840        } finally {
2841            IoUtils.closeQuietly(info.fd);
2842            StrictMode.setThreadPolicy(oldPolicy);
2843        }
2844    }
2845
2846    private void handleDumpProvider(DumpComponentInfo info) {
2847        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2848        try {
2849            ProviderClientRecord r = mLocalProviders.get(info.token);
2850            if (r != null && r.mLocalProvider != null) {
2851                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2852                        info.fd.getFileDescriptor()));
2853                r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2854                pw.flush();
2855            }
2856        } finally {
2857            IoUtils.closeQuietly(info.fd);
2858            StrictMode.setThreadPolicy(oldPolicy);
2859        }
2860    }
2861
2862    private void handleServiceArgs(ServiceArgsData data) {
2863        Service s = mServices.get(data.token);
2864        if (s != null) {
2865            try {
2866                if (data.args != null) {
2867                    data.args.setExtrasClassLoader(s.getClassLoader());
2868                    data.args.prepareToEnterProcess();
2869                }
2870                int res;
2871                if (!data.taskRemoved) {
2872                    res = s.onStartCommand(data.args, data.flags, data.startId);
2873                } else {
2874                    s.onTaskRemoved(data.args);
2875                    res = Service.START_TASK_REMOVED_COMPLETE;
2876                }
2877
2878                QueuedWork.waitToFinish();
2879
2880                try {
2881                    ActivityManagerNative.getDefault().serviceDoneExecuting(
2882                            data.token, 1, data.startId, res);
2883                } catch (RemoteException e) {
2884                    // nothing to do.
2885                }
2886                ensureJitEnabled();
2887            } catch (Exception e) {
2888                if (!mInstrumentation.onException(s, e)) {
2889                    throw new RuntimeException(
2890                            "Unable to start service " + s
2891                            + " with " + data.args + ": " + e.toString(), e);
2892                }
2893            }
2894        }
2895    }
2896
2897    private void handleStopService(IBinder token) {
2898        Service s = mServices.remove(token);
2899        if (s != null) {
2900            try {
2901                if (localLOGV) Slog.v(TAG, "Destroying service " + s);
2902                s.onDestroy();
2903                Context context = s.getBaseContext();
2904                if (context instanceof ContextImpl) {
2905                    final String who = s.getClassName();
2906                    ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
2907                }
2908
2909                QueuedWork.waitToFinish();
2910
2911                try {
2912                    ActivityManagerNative.getDefault().serviceDoneExecuting(
2913                            token, 0, 0, 0);
2914                } catch (RemoteException e) {
2915                    // nothing to do.
2916                }
2917            } catch (Exception e) {
2918                if (!mInstrumentation.onException(s, e)) {
2919                    throw new RuntimeException(
2920                            "Unable to stop service " + s
2921                            + ": " + e.toString(), e);
2922                }
2923            }
2924        }
2925        //Slog.i(TAG, "Running services: " + mServices);
2926    }
2927
2928    public final ActivityClientRecord performResumeActivity(IBinder token,
2929            boolean clearHide) {
2930        ActivityClientRecord r = mActivities.get(token);
2931        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
2932                + " finished=" + r.activity.mFinished);
2933        if (r != null && !r.activity.mFinished) {
2934            if (clearHide) {
2935                r.hideForNow = false;
2936                r.activity.mStartedActivity = false;
2937            }
2938            try {
2939                r.activity.mFragments.noteStateNotSaved();
2940                if (r.pendingIntents != null) {
2941                    deliverNewIntents(r, r.pendingIntents);
2942                    r.pendingIntents = null;
2943                }
2944                if (r.pendingResults != null) {
2945                    deliverResults(r, r.pendingResults);
2946                    r.pendingResults = null;
2947                }
2948                r.activity.performResume();
2949
2950                EventLog.writeEvent(LOG_ON_RESUME_CALLED,
2951                        UserHandle.myUserId(), r.activity.getComponentName().getClassName());
2952
2953                r.paused = false;
2954                r.stopped = false;
2955                r.state = null;
2956                r.persistentState = null;
2957            } catch (Exception e) {
2958                if (!mInstrumentation.onException(r.activity, e)) {
2959                    throw new RuntimeException(
2960                        "Unable to resume activity "
2961                        + r.intent.getComponent().toShortString()
2962                        + ": " + e.toString(), e);
2963                }
2964            }
2965        }
2966        return r;
2967    }
2968
2969    static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
2970        if (r.mPendingRemoveWindow != null) {
2971            r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2972            IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2973            if (wtoken != null) {
2974                WindowManagerGlobal.getInstance().closeAll(wtoken,
2975                        r.activity.getClass().getName(), "Activity");
2976            }
2977        }
2978        r.mPendingRemoveWindow = null;
2979        r.mPendingRemoveWindowManager = null;
2980    }
2981
2982    final void handleResumeActivity(IBinder token,
2983            boolean clearHide, boolean isForward, boolean reallyResume) {
2984        // If we are getting ready to gc after going to the background, well
2985        // we are back active so skip it.
2986        unscheduleGcIdler();
2987
2988        // TODO Push resumeArgs into the activity for consideration
2989        ActivityClientRecord r = performResumeActivity(token, clearHide);
2990
2991        if (r != null) {
2992            final Activity a = r.activity;
2993
2994            if (localLOGV) Slog.v(
2995                TAG, "Resume " + r + " started activity: " +
2996                a.mStartedActivity + ", hideForNow: " + r.hideForNow
2997                + ", finished: " + a.mFinished);
2998
2999            final int forwardBit = isForward ?
3000                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
3001
3002            // If the window hasn't yet been added to the window manager,
3003            // and this guy didn't finish itself or start another activity,
3004            // then go ahead and add the window.
3005            boolean willBeVisible = !a.mStartedActivity;
3006            if (!willBeVisible) {
3007                try {
3008                    willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
3009                            a.getActivityToken());
3010                } catch (RemoteException e) {
3011                }
3012            }
3013            if (r.window == null && !a.mFinished && willBeVisible) {
3014                r.window = r.activity.getWindow();
3015                View decor = r.window.getDecorView();
3016                decor.setVisibility(View.INVISIBLE);
3017                ViewManager wm = a.getWindowManager();
3018                WindowManager.LayoutParams l = r.window.getAttributes();
3019                a.mDecor = decor;
3020                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
3021                l.softInputMode |= forwardBit;
3022                if (a.mVisibleFromClient) {
3023                    a.mWindowAdded = true;
3024                    wm.addView(decor, l);
3025                }
3026
3027            // If the window has already been added, but during resume
3028            // we started another activity, then don't yet make the
3029            // window visible.
3030            } else if (!willBeVisible) {
3031                if (localLOGV) Slog.v(
3032                    TAG, "Launch " + r + " mStartedActivity set");
3033                r.hideForNow = true;
3034            }
3035
3036            // Get rid of anything left hanging around.
3037            cleanUpPendingRemoveWindows(r);
3038
3039            // The window is now visible if it has been added, we are not
3040            // simply finishing, and we are not starting another activity.
3041            if (!r.activity.mFinished && willBeVisible
3042                    && r.activity.mDecor != null && !r.hideForNow) {
3043                if (r.newConfig != null) {
3044                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
3045                            + r.activityInfo.name + " with newConfig " + r.newConfig);
3046                    performConfigurationChanged(r.activity, r.newConfig);
3047                    freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3048                    r.newConfig = null;
3049                }
3050                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3051                        + isForward);
3052                WindowManager.LayoutParams l = r.window.getAttributes();
3053                if ((l.softInputMode
3054                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3055                        != forwardBit) {
3056                    l.softInputMode = (l.softInputMode
3057                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3058                            | forwardBit;
3059                    if (r.activity.mVisibleFromClient) {
3060                        ViewManager wm = a.getWindowManager();
3061                        View decor = r.window.getDecorView();
3062                        wm.updateViewLayout(decor, l);
3063                    }
3064                }
3065                r.activity.mVisibleFromServer = true;
3066                mNumVisibleActivities++;
3067                if (r.activity.mVisibleFromClient) {
3068                    r.activity.makeVisible();
3069                }
3070            }
3071
3072            if (!r.onlyLocalRequest) {
3073                r.nextIdle = mNewActivities;
3074                mNewActivities = r;
3075                if (localLOGV) Slog.v(
3076                    TAG, "Scheduling idle handler for " + r);
3077                Looper.myQueue().addIdleHandler(new Idler());
3078            }
3079            r.onlyLocalRequest = false;
3080
3081            // Tell the activity manager we have resumed.
3082            if (reallyResume) {
3083                try {
3084                    ActivityManagerNative.getDefault().activityResumed(token);
3085                } catch (RemoteException ex) {
3086                }
3087            }
3088
3089        } else {
3090            // If an exception was thrown when trying to resume, then
3091            // just end this activity.
3092            try {
3093                ActivityManagerNative.getDefault()
3094                    .finishActivity(token, Activity.RESULT_CANCELED, null, false);
3095            } catch (RemoteException ex) {
3096            }
3097        }
3098    }
3099
3100    private int mThumbnailWidth = -1;
3101    private int mThumbnailHeight = -1;
3102    private Bitmap mAvailThumbnailBitmap = null;
3103    private Canvas mThumbnailCanvas = null;
3104
3105    private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3106        Bitmap thumbnail = mAvailThumbnailBitmap;
3107        try {
3108            if (thumbnail == null) {
3109                int w = mThumbnailWidth;
3110                int h;
3111                if (w < 0) {
3112                    Resources res = r.activity.getResources();
3113                    int wId = com.android.internal.R.dimen.thumbnail_width;
3114                    int hId = com.android.internal.R.dimen.thumbnail_height;
3115                    mThumbnailWidth = w = res.getDimensionPixelSize(wId);
3116                    mThumbnailHeight = h = res.getDimensionPixelSize(hId);
3117                } else {
3118                    h = mThumbnailHeight;
3119                }
3120
3121                // On platforms where we don't want thumbnails, set dims to (0,0)
3122                if ((w > 0) && (h > 0)) {
3123                    thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
3124                            w, h, THUMBNAIL_FORMAT);
3125                    thumbnail.eraseColor(0);
3126                }
3127            }
3128
3129            if (thumbnail != null) {
3130                Canvas cv = mThumbnailCanvas;
3131                if (cv == null) {
3132                    mThumbnailCanvas = cv = new Canvas();
3133                }
3134
3135                cv.setBitmap(thumbnail);
3136                if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3137                    mAvailThumbnailBitmap = thumbnail;
3138                    thumbnail = null;
3139                }
3140                cv.setBitmap(null);
3141            }
3142
3143        } catch (Exception e) {
3144            if (!mInstrumentation.onException(r.activity, e)) {
3145                throw new RuntimeException(
3146                        "Unable to create thumbnail of "
3147                        + r.intent.getComponent().toShortString()
3148                        + ": " + e.toString(), e);
3149            }
3150            thumbnail = null;
3151        }
3152
3153        return thumbnail;
3154    }
3155
3156    private void handlePauseActivity(IBinder token, boolean finished,
3157            boolean userLeaving, int configChanges) {
3158        ActivityClientRecord r = mActivities.get(token);
3159        if (r != null) {
3160            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3161            if (userLeaving) {
3162                performUserLeavingActivity(r);
3163            }
3164
3165            r.activity.mConfigChangeFlags |= configChanges;
3166            performPauseActivity(token, finished, r.isPreHoneycomb());
3167
3168            // Make sure any pending writes are now committed.
3169            if (r.isPreHoneycomb()) {
3170                QueuedWork.waitToFinish();
3171            }
3172
3173            // Tell the activity manager we have paused.
3174            try {
3175                ActivityManagerNative.getDefault().activityPaused(token, r.persistentState);
3176            } catch (RemoteException ex) {
3177            }
3178        }
3179    }
3180
3181    final void performUserLeavingActivity(ActivityClientRecord r) {
3182        mInstrumentation.callActivityOnUserLeaving(r.activity);
3183    }
3184
3185    final Bundle performPauseActivity(IBinder token, boolean finished,
3186            boolean saveState) {
3187        ActivityClientRecord r = mActivities.get(token);
3188        return r != null ? performPauseActivity(r, finished, saveState) : null;
3189    }
3190
3191    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3192            boolean saveState) {
3193        if (r.paused) {
3194            if (r.activity.mFinished) {
3195                // If we are finishing, we won't call onResume() in certain cases.
3196                // So here we likewise don't want to call onPause() if the activity
3197                // isn't resumed.
3198                return null;
3199            }
3200            RuntimeException e = new RuntimeException(
3201                    "Performing pause of activity that is not resumed: "
3202                    + r.intent.getComponent().toShortString());
3203            Slog.e(TAG, e.getMessage(), e);
3204        }
3205        if (finished) {
3206            r.activity.mFinished = true;
3207        }
3208        try {
3209            // Next have the activity save its current state and managed dialogs...
3210            if (!r.activity.mFinished && saveState) {
3211                callCallActivityOnSaveInstanceState(r);
3212            }
3213            // Now we are idle.
3214            r.activity.mCalled = false;
3215            mInstrumentation.callActivityOnPause(r.activity);
3216            EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3217                    r.activity.getComponentName().getClassName());
3218            if (!r.activity.mCalled) {
3219                throw new SuperNotCalledException(
3220                    "Activity " + r.intent.getComponent().toShortString() +
3221                    " did not call through to super.onPause()");
3222            }
3223
3224        } catch (SuperNotCalledException e) {
3225            throw e;
3226
3227        } catch (Exception e) {
3228            if (!mInstrumentation.onException(r.activity, e)) {
3229                throw new RuntimeException(
3230                        "Unable to pause activity "
3231                        + r.intent.getComponent().toShortString()
3232                        + ": " + e.toString(), e);
3233            }
3234        }
3235        r.paused = true;
3236
3237        // Notify any outstanding on paused listeners
3238        ArrayList<OnActivityPausedListener> listeners;
3239        synchronized (mOnPauseListeners) {
3240            listeners = mOnPauseListeners.remove(r.activity);
3241        }
3242        int size = (listeners != null ? listeners.size() : 0);
3243        for (int i = 0; i < size; i++) {
3244            listeners.get(i).onPaused(r.activity);
3245        }
3246
3247        return !r.activity.mFinished && saveState ? r.state : null;
3248    }
3249
3250    final void performStopActivity(IBinder token, boolean saveState) {
3251        ActivityClientRecord r = mActivities.get(token);
3252        performStopActivityInner(r, null, false, saveState);
3253    }
3254
3255    private static class StopInfo implements Runnable {
3256        ActivityClientRecord activity;
3257        Bundle state;
3258        PersistableBundle persistentState;
3259        CharSequence description;
3260
3261        @Override public void run() {
3262            // Tell activity manager we have been stopped.
3263            try {
3264                if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3265                ActivityManagerNative.getDefault().activityStopped(
3266                    activity.token, state, persistentState, description);
3267            } catch (RemoteException ex) {
3268            }
3269        }
3270    }
3271
3272    private static final class ProviderRefCount {
3273        public final IActivityManager.ContentProviderHolder holder;
3274        public final ProviderClientRecord client;
3275        public int stableCount;
3276        public int unstableCount;
3277
3278        // When this is set, the stable and unstable ref counts are 0 and
3279        // we have a pending operation scheduled to remove the ref count
3280        // from the activity manager.  On the activity manager we are still
3281        // holding an unstable ref, though it is not reflected in the counts
3282        // here.
3283        public boolean removePending;
3284
3285        ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3286                ProviderClientRecord inClient, int sCount, int uCount) {
3287            holder = inHolder;
3288            client = inClient;
3289            stableCount = sCount;
3290            unstableCount = uCount;
3291        }
3292    }
3293
3294    /**
3295     * Core implementation of stopping an activity.  Note this is a little
3296     * tricky because the server's meaning of stop is slightly different
3297     * than our client -- for the server, stop means to save state and give
3298     * it the result when it is done, but the window may still be visible.
3299     * For the client, we want to call onStop()/onStart() to indicate when
3300     * the activity's UI visibillity changes.
3301     */
3302    private void performStopActivityInner(ActivityClientRecord r,
3303            StopInfo info, boolean keepShown, boolean saveState) {
3304        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3305        if (r != null) {
3306            if (!keepShown && r.stopped) {
3307                if (r.activity.mFinished) {
3308                    // If we are finishing, we won't call onResume() in certain
3309                    // cases.  So here we likewise don't want to call onStop()
3310                    // if the activity isn't resumed.
3311                    return;
3312                }
3313                RuntimeException e = new RuntimeException(
3314                        "Performing stop of activity that is not resumed: "
3315                        + r.intent.getComponent().toShortString());
3316                Slog.e(TAG, e.getMessage(), e);
3317            }
3318
3319            if (info != null) {
3320                try {
3321                    // First create a thumbnail for the activity...
3322                    // For now, don't create the thumbnail here; we are
3323                    // doing that by doing a screen snapshot.
3324                    info.description = r.activity.onCreateDescription();
3325                } catch (Exception e) {
3326                    if (!mInstrumentation.onException(r.activity, e)) {
3327                        throw new RuntimeException(
3328                                "Unable to save state of activity "
3329                                + r.intent.getComponent().toShortString()
3330                                + ": " + e.toString(), e);
3331                    }
3332                }
3333            }
3334
3335            // Next have the activity save its current state and managed dialogs...
3336            if (!r.activity.mFinished && saveState) {
3337                if (r.state == null) {
3338                    callCallActivityOnSaveInstanceState(r);
3339                }
3340            }
3341
3342            if (!keepShown) {
3343                try {
3344                    // Now we are idle.
3345                    r.activity.performStop();
3346                } catch (Exception e) {
3347                    if (!mInstrumentation.onException(r.activity, e)) {
3348                        throw new RuntimeException(
3349                                "Unable to stop activity "
3350                                + r.intent.getComponent().toShortString()
3351                                + ": " + e.toString(), e);
3352                    }
3353                }
3354                r.stopped = true;
3355            }
3356
3357            r.paused = true;
3358        }
3359    }
3360
3361    private void updateVisibility(ActivityClientRecord r, boolean show) {
3362        View v = r.activity.mDecor;
3363        if (v != null) {
3364            if (show) {
3365                if (!r.activity.mVisibleFromServer) {
3366                    r.activity.mVisibleFromServer = true;
3367                    mNumVisibleActivities++;
3368                    if (r.activity.mVisibleFromClient) {
3369                        r.activity.makeVisible();
3370                    }
3371                }
3372                if (r.newConfig != null) {
3373                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3374                            + r.activityInfo.name + " with new config " + r.newConfig);
3375                    performConfigurationChanged(r.activity, r.newConfig);
3376                    freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3377                    r.newConfig = null;
3378                }
3379            } else {
3380                if (r.activity.mVisibleFromServer) {
3381                    r.activity.mVisibleFromServer = false;
3382                    mNumVisibleActivities--;
3383                    v.setVisibility(View.INVISIBLE);
3384                }
3385            }
3386        }
3387    }
3388
3389    private void handleStopActivity(IBinder token, boolean show, int configChanges) {
3390        ActivityClientRecord r = mActivities.get(token);
3391        r.activity.mConfigChangeFlags |= configChanges;
3392
3393        StopInfo info = new StopInfo();
3394        performStopActivityInner(r, info, show, true);
3395
3396        if (localLOGV) Slog.v(
3397            TAG, "Finishing stop of " + r + ": show=" + show
3398            + " win=" + r.window);
3399
3400        updateVisibility(r, show);
3401
3402        // Make sure any pending writes are now committed.
3403        if (!r.isPreHoneycomb()) {
3404            QueuedWork.waitToFinish();
3405        }
3406
3407        // Schedule the call to tell the activity manager we have
3408        // stopped.  We don't do this immediately, because we want to
3409        // have a chance for any other pending work (in particular memory
3410        // trim requests) to complete before you tell the activity
3411        // manager to proceed and allow us to go fully into the background.
3412        info.activity = r;
3413        info.state = r.state;
3414        info.persistentState = r.persistentState;
3415        mH.post(info);
3416    }
3417
3418    final void performRestartActivity(IBinder token) {
3419        ActivityClientRecord r = mActivities.get(token);
3420        if (r.stopped) {
3421            r.activity.performRestart();
3422            r.stopped = false;
3423        }
3424    }
3425
3426    private void handleWindowVisibility(IBinder token, boolean show) {
3427        ActivityClientRecord r = mActivities.get(token);
3428
3429        if (r == null) {
3430            Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3431            return;
3432        }
3433
3434        if (!show && !r.stopped) {
3435            performStopActivityInner(r, null, show, false);
3436        } else if (show && r.stopped) {
3437            // If we are getting ready to gc after going to the background, well
3438            // we are back active so skip it.
3439            unscheduleGcIdler();
3440
3441            r.activity.performRestart();
3442            r.stopped = false;
3443        }
3444        if (r.activity.mDecor != null) {
3445            if (false) Slog.v(
3446                TAG, "Handle window " + r + " visibility: " + show);
3447            updateVisibility(r, show);
3448        }
3449    }
3450
3451    private void handleSleeping(IBinder token, boolean sleeping) {
3452        ActivityClientRecord r = mActivities.get(token);
3453
3454        if (r == null) {
3455            Log.w(TAG, "handleSleeping: no activity for token " + token);
3456            return;
3457        }
3458
3459        if (sleeping) {
3460            if (!r.stopped && !r.isPreHoneycomb()) {
3461                try {
3462                    // Now we are idle.
3463                    r.activity.performStop();
3464                } catch (Exception e) {
3465                    if (!mInstrumentation.onException(r.activity, e)) {
3466                        throw new RuntimeException(
3467                                "Unable to stop activity "
3468                                + r.intent.getComponent().toShortString()
3469                                + ": " + e.toString(), e);
3470                    }
3471                }
3472                r.stopped = true;
3473            }
3474
3475            // Make sure any pending writes are now committed.
3476            if (!r.isPreHoneycomb()) {
3477                QueuedWork.waitToFinish();
3478            }
3479
3480            // Tell activity manager we slept.
3481            try {
3482                ActivityManagerNative.getDefault().activitySlept(r.token);
3483            } catch (RemoteException ex) {
3484            }
3485        } else {
3486            if (r.stopped && r.activity.mVisibleFromServer) {
3487                r.activity.performRestart();
3488                r.stopped = false;
3489            }
3490        }
3491    }
3492
3493    private void handleSetCoreSettings(Bundle coreSettings) {
3494        synchronized (mResourcesManager) {
3495            mCoreSettings = coreSettings;
3496        }
3497    }
3498
3499    private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3500        LoadedApk apk = peekPackageInfo(data.pkg, false);
3501        if (apk != null) {
3502            apk.setCompatibilityInfo(data.info);
3503        }
3504        apk = peekPackageInfo(data.pkg, true);
3505        if (apk != null) {
3506            apk.setCompatibilityInfo(data.info);
3507        }
3508        handleConfigurationChanged(mConfiguration, data.info);
3509        WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
3510    }
3511
3512    private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
3513        final int N = results.size();
3514        for (int i=0; i<N; i++) {
3515            ResultInfo ri = results.get(i);
3516            try {
3517                if (ri.mData != null) {
3518                    ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3519                    ri.mData.prepareToEnterProcess();
3520                }
3521                if (DEBUG_RESULTS) Slog.v(TAG,
3522                        "Delivering result to activity " + r + " : " + ri);
3523                r.activity.dispatchActivityResult(ri.mResultWho,
3524                        ri.mRequestCode, ri.mResultCode, ri.mData);
3525            } catch (Exception e) {
3526                if (!mInstrumentation.onException(r.activity, e)) {
3527                    throw new RuntimeException(
3528                            "Failure delivering result " + ri + " to activity "
3529                            + r.intent.getComponent().toShortString()
3530                            + ": " + e.toString(), e);
3531                }
3532            }
3533        }
3534    }
3535
3536    private void handleSendResult(ResultData res) {
3537        ActivityClientRecord r = mActivities.get(res.token);
3538        if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
3539        if (r != null) {
3540            final boolean resumed = !r.paused;
3541            if (!r.activity.mFinished && r.activity.mDecor != null
3542                    && r.hideForNow && resumed) {
3543                // We had hidden the activity because it started another
3544                // one...  we have gotten a result back and we are not
3545                // paused, so make sure our window is visible.
3546                updateVisibility(r, true);
3547            }
3548            if (resumed) {
3549                try {
3550                    // Now we are idle.
3551                    r.activity.mCalled = false;
3552                    r.activity.mTemporaryPause = true;
3553                    mInstrumentation.callActivityOnPause(r.activity);
3554                    if (!r.activity.mCalled) {
3555                        throw new SuperNotCalledException(
3556                            "Activity " + r.intent.getComponent().toShortString()
3557                            + " did not call through to super.onPause()");
3558                    }
3559                } catch (SuperNotCalledException e) {
3560                    throw e;
3561                } catch (Exception e) {
3562                    if (!mInstrumentation.onException(r.activity, e)) {
3563                        throw new RuntimeException(
3564                                "Unable to pause activity "
3565                                + r.intent.getComponent().toShortString()
3566                                + ": " + e.toString(), e);
3567                    }
3568                }
3569            }
3570            deliverResults(r, res.results);
3571            if (resumed) {
3572                r.activity.performResume();
3573                r.activity.mTemporaryPause = false;
3574            }
3575        }
3576    }
3577
3578    public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
3579        return performDestroyActivity(token, finishing, 0, false);
3580    }
3581
3582    private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
3583            int configChanges, boolean getNonConfigInstance) {
3584        ActivityClientRecord r = mActivities.get(token);
3585        Class<? extends Activity> activityClass = null;
3586        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
3587        if (r != null) {
3588            activityClass = r.activity.getClass();
3589            r.activity.mConfigChangeFlags |= configChanges;
3590            if (finishing) {
3591                r.activity.mFinished = true;
3592            }
3593            if (!r.paused) {
3594                try {
3595                    r.activity.mCalled = false;
3596                    mInstrumentation.callActivityOnPause(r.activity);
3597                    EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3598                            r.activity.getComponentName().getClassName());
3599                    if (!r.activity.mCalled) {
3600                        throw new SuperNotCalledException(
3601                            "Activity " + safeToComponentShortString(r.intent)
3602                            + " did not call through to super.onPause()");
3603                    }
3604                } catch (SuperNotCalledException e) {
3605                    throw e;
3606                } catch (Exception e) {
3607                    if (!mInstrumentation.onException(r.activity, e)) {
3608                        throw new RuntimeException(
3609                                "Unable to pause activity "
3610                                + safeToComponentShortString(r.intent)
3611                                + ": " + e.toString(), e);
3612                    }
3613                }
3614                r.paused = true;
3615            }
3616            if (!r.stopped) {
3617                try {
3618                    r.activity.performStop();
3619                } catch (SuperNotCalledException e) {
3620                    throw e;
3621                } catch (Exception e) {
3622                    if (!mInstrumentation.onException(r.activity, e)) {
3623                        throw new RuntimeException(
3624                                "Unable to stop activity "
3625                                + safeToComponentShortString(r.intent)
3626                                + ": " + e.toString(), e);
3627                    }
3628                }
3629                r.stopped = true;
3630            }
3631            if (getNonConfigInstance) {
3632                try {
3633                    r.lastNonConfigurationInstances
3634                            = r.activity.retainNonConfigurationInstances();
3635                } catch (Exception e) {
3636                    if (!mInstrumentation.onException(r.activity, e)) {
3637                        throw new RuntimeException(
3638                                "Unable to retain activity "
3639                                + r.intent.getComponent().toShortString()
3640                                + ": " + e.toString(), e);
3641                    }
3642                }
3643            }
3644            try {
3645                r.activity.mCalled = false;
3646                mInstrumentation.callActivityOnDestroy(r.activity);
3647                if (!r.activity.mCalled) {
3648                    throw new SuperNotCalledException(
3649                        "Activity " + safeToComponentShortString(r.intent) +
3650                        " did not call through to super.onDestroy()");
3651                }
3652                if (r.window != null) {
3653                    r.window.closeAllPanels();
3654                }
3655            } catch (SuperNotCalledException e) {
3656                throw e;
3657            } catch (Exception e) {
3658                if (!mInstrumentation.onException(r.activity, e)) {
3659                    throw new RuntimeException(
3660                            "Unable to destroy activity " + safeToComponentShortString(r.intent)
3661                            + ": " + e.toString(), e);
3662                }
3663            }
3664        }
3665        mActivities.remove(token);
3666        StrictMode.decrementExpectedActivityCount(activityClass);
3667        return r;
3668    }
3669
3670    private static String safeToComponentShortString(Intent intent) {
3671        ComponentName component = intent.getComponent();
3672        return component == null ? "[Unknown]" : component.toShortString();
3673    }
3674
3675    private void handleDestroyActivity(IBinder token, boolean finishing,
3676            int configChanges, boolean getNonConfigInstance) {
3677        ActivityClientRecord r = performDestroyActivity(token, finishing,
3678                configChanges, getNonConfigInstance);
3679        if (r != null) {
3680            cleanUpPendingRemoveWindows(r);
3681            WindowManager wm = r.activity.getWindowManager();
3682            View v = r.activity.mDecor;
3683            if (v != null) {
3684                if (r.activity.mVisibleFromServer) {
3685                    mNumVisibleActivities--;
3686                }
3687                IBinder wtoken = v.getWindowToken();
3688                if (r.activity.mWindowAdded) {
3689                    if (r.onlyLocalRequest) {
3690                        // Hold off on removing this until the new activity's
3691                        // window is being added.
3692                        r.mPendingRemoveWindow = v;
3693                        r.mPendingRemoveWindowManager = wm;
3694                    } else {
3695                        wm.removeViewImmediate(v);
3696                    }
3697                }
3698                if (wtoken != null && r.mPendingRemoveWindow == null) {
3699                    WindowManagerGlobal.getInstance().closeAll(wtoken,
3700                            r.activity.getClass().getName(), "Activity");
3701                }
3702                r.activity.mDecor = null;
3703            }
3704            if (r.mPendingRemoveWindow == null) {
3705                // If we are delaying the removal of the activity window, then
3706                // we can't clean up all windows here.  Note that we can't do
3707                // so later either, which means any windows that aren't closed
3708                // by the app will leak.  Well we try to warning them a lot
3709                // about leaking windows, because that is a bug, so if they are
3710                // using this recreate facility then they get to live with leaks.
3711                WindowManagerGlobal.getInstance().closeAll(token,
3712                        r.activity.getClass().getName(), "Activity");
3713            }
3714
3715            // Mocked out contexts won't be participating in the normal
3716            // process lifecycle, but if we're running with a proper
3717            // ApplicationContext we need to have it tear down things
3718            // cleanly.
3719            Context c = r.activity.getBaseContext();
3720            if (c instanceof ContextImpl) {
3721                ((ContextImpl) c).scheduleFinalCleanup(
3722                        r.activity.getClass().getName(), "Activity");
3723            }
3724        }
3725        if (finishing) {
3726            try {
3727                ActivityManagerNative.getDefault().activityDestroyed(token);
3728            } catch (RemoteException ex) {
3729                // If the system process has died, it's game over for everyone.
3730            }
3731        }
3732    }
3733
3734    public final void requestRelaunchActivity(IBinder token,
3735            List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3736            int configChanges, boolean notResumed, Configuration config,
3737            boolean fromServer) {
3738        ActivityClientRecord target = null;
3739
3740        synchronized (mResourcesManager) {
3741            for (int i=0; i<mRelaunchingActivities.size(); i++) {
3742                ActivityClientRecord r = mRelaunchingActivities.get(i);
3743                if (r.token == token) {
3744                    target = r;
3745                    if (pendingResults != null) {
3746                        if (r.pendingResults != null) {
3747                            r.pendingResults.addAll(pendingResults);
3748                        } else {
3749                            r.pendingResults = pendingResults;
3750                        }
3751                    }
3752                    if (pendingNewIntents != null) {
3753                        if (r.pendingIntents != null) {
3754                            r.pendingIntents.addAll(pendingNewIntents);
3755                        } else {
3756                            r.pendingIntents = pendingNewIntents;
3757                        }
3758                    }
3759                    break;
3760                }
3761            }
3762
3763            if (target == null) {
3764                target = new ActivityClientRecord();
3765                target.token = token;
3766                target.pendingResults = pendingResults;
3767                target.pendingIntents = pendingNewIntents;
3768                if (!fromServer) {
3769                    ActivityClientRecord existing = mActivities.get(token);
3770                    if (existing != null) {
3771                        target.startsNotResumed = existing.paused;
3772                    }
3773                    target.onlyLocalRequest = true;
3774                }
3775                mRelaunchingActivities.add(target);
3776                sendMessage(H.RELAUNCH_ACTIVITY, target);
3777            }
3778
3779            if (fromServer) {
3780                target.startsNotResumed = notResumed;
3781                target.onlyLocalRequest = false;
3782            }
3783            if (config != null) {
3784                target.createdConfig = config;
3785            }
3786            target.pendingConfigChanges |= configChanges;
3787        }
3788    }
3789
3790    private void handleRelaunchActivity(ActivityClientRecord tmp) {
3791        // If we are getting ready to gc after going to the background, well
3792        // we are back active so skip it.
3793        unscheduleGcIdler();
3794
3795        Configuration changedConfig = null;
3796        int configChanges = 0;
3797
3798        // First: make sure we have the most recent configuration and most
3799        // recent version of the activity, or skip it if some previous call
3800        // had taken a more recent version.
3801        synchronized (mResourcesManager) {
3802            int N = mRelaunchingActivities.size();
3803            IBinder token = tmp.token;
3804            tmp = null;
3805            for (int i=0; i<N; i++) {
3806                ActivityClientRecord r = mRelaunchingActivities.get(i);
3807                if (r.token == token) {
3808                    tmp = r;
3809                    configChanges |= tmp.pendingConfigChanges;
3810                    mRelaunchingActivities.remove(i);
3811                    i--;
3812                    N--;
3813                }
3814            }
3815
3816            if (tmp == null) {
3817                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
3818                return;
3819            }
3820
3821            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3822                    + tmp.token + " with configChanges=0x"
3823                    + Integer.toHexString(configChanges));
3824
3825            if (mPendingConfiguration != null) {
3826                changedConfig = mPendingConfiguration;
3827                mPendingConfiguration = null;
3828            }
3829        }
3830
3831        if (tmp.createdConfig != null) {
3832            // If the activity manager is passing us its current config,
3833            // assume that is really what we want regardless of what we
3834            // may have pending.
3835            if (mConfiguration == null
3836                    || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3837                            && mConfiguration.diff(tmp.createdConfig) != 0)) {
3838                if (changedConfig == null
3839                        || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3840                    changedConfig = tmp.createdConfig;
3841                }
3842            }
3843        }
3844
3845        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3846                + tmp.token + ": changedConfig=" + changedConfig);
3847
3848        // If there was a pending configuration change, execute it first.
3849        if (changedConfig != null) {
3850            mCurDefaultDisplayDpi = changedConfig.densityDpi;
3851            updateDefaultDensity();
3852            handleConfigurationChanged(changedConfig, null);
3853        }
3854
3855        ActivityClientRecord r = mActivities.get(tmp.token);
3856        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
3857        if (r == null) {
3858            return;
3859        }
3860
3861        r.activity.mConfigChangeFlags |= configChanges;
3862        r.onlyLocalRequest = tmp.onlyLocalRequest;
3863        Intent currentIntent = r.activity.mIntent;
3864
3865        r.activity.mChangingConfigurations = true;
3866
3867        // Need to ensure state is saved.
3868        if (!r.paused) {
3869            performPauseActivity(r.token, false, r.isPreHoneycomb());
3870        }
3871        if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3872            callCallActivityOnSaveInstanceState(r);
3873        }
3874
3875        handleDestroyActivity(r.token, false, configChanges, true);
3876
3877        r.activity = null;
3878        r.window = null;
3879        r.hideForNow = false;
3880        r.nextIdle = null;
3881        // Merge any pending results and pending intents; don't just replace them
3882        if (tmp.pendingResults != null) {
3883            if (r.pendingResults == null) {
3884                r.pendingResults = tmp.pendingResults;
3885            } else {
3886                r.pendingResults.addAll(tmp.pendingResults);
3887            }
3888        }
3889        if (tmp.pendingIntents != null) {
3890            if (r.pendingIntents == null) {
3891                r.pendingIntents = tmp.pendingIntents;
3892            } else {
3893                r.pendingIntents.addAll(tmp.pendingIntents);
3894            }
3895        }
3896        r.startsNotResumed = tmp.startsNotResumed;
3897
3898        handleLaunchActivity(r, currentIntent);
3899    }
3900
3901    private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
3902        r.state = new Bundle();
3903        r.state.setAllowFds(false);
3904        if (r.isPersistable()) {
3905            r.persistentState = new PersistableBundle();
3906            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
3907                    r.persistentState);
3908        } else {
3909            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
3910        }
3911    }
3912
3913    ArrayList<ComponentCallbacks2> collectComponentCallbacks(
3914            boolean allActivities, Configuration newConfig) {
3915        ArrayList<ComponentCallbacks2> callbacks
3916                = new ArrayList<ComponentCallbacks2>();
3917
3918        synchronized (mResourcesManager) {
3919            final int NAPP = mAllApplications.size();
3920            for (int i=0; i<NAPP; i++) {
3921                callbacks.add(mAllApplications.get(i));
3922            }
3923            final int NACT = mActivities.size();
3924            for (int i=0; i<NACT; i++) {
3925                ActivityClientRecord ar = mActivities.valueAt(i);
3926                Activity a = ar.activity;
3927                if (a != null) {
3928                    Configuration thisConfig = applyConfigCompatMainThread(
3929                            mCurDefaultDisplayDpi, newConfig,
3930                            ar.packageInfo.getCompatibilityInfo());
3931                    if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3932                        // If the activity is currently resumed, its configuration
3933                        // needs to change right now.
3934                        callbacks.add(a);
3935                    } else if (thisConfig != null) {
3936                        // Otherwise, we will tell it about the change
3937                        // the next time it is resumed or shown.  Note that
3938                        // the activity manager may, before then, decide the
3939                        // activity needs to be destroyed to handle its new
3940                        // configuration.
3941                        if (DEBUG_CONFIGURATION) {
3942                            Slog.v(TAG, "Setting activity "
3943                                    + ar.activityInfo.name + " newConfig=" + thisConfig);
3944                        }
3945                        ar.newConfig = thisConfig;
3946                    }
3947                }
3948            }
3949            final int NSVC = mServices.size();
3950            for (int i=0; i<NSVC; i++) {
3951                callbacks.add(mServices.valueAt(i));
3952            }
3953        }
3954        synchronized (mProviderMap) {
3955            final int NPRV = mLocalProviders.size();
3956            for (int i=0; i<NPRV; i++) {
3957                callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
3958            }
3959        }
3960
3961        return callbacks;
3962    }
3963
3964    private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
3965        // Only for Activity objects, check that they actually call up to their
3966        // superclass implementation.  ComponentCallbacks2 is an interface, so
3967        // we check the runtime type and act accordingly.
3968        Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3969        if (activity != null) {
3970            activity.mCalled = false;
3971        }
3972
3973        boolean shouldChangeConfig = false;
3974        if ((activity == null) || (activity.mCurrentConfig == null)) {
3975            shouldChangeConfig = true;
3976        } else {
3977
3978            // If the new config is the same as the config this Activity
3979            // is already running with then don't bother calling
3980            // onConfigurationChanged
3981            int diff = activity.mCurrentConfig.diff(config);
3982            if (diff != 0) {
3983                // If this activity doesn't handle any of the config changes
3984                // then don't bother calling onConfigurationChanged as we're
3985                // going to destroy it.
3986                if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
3987                    shouldChangeConfig = true;
3988                }
3989            }
3990        }
3991
3992        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
3993                + ": shouldChangeConfig=" + shouldChangeConfig);
3994        if (shouldChangeConfig) {
3995            cb.onConfigurationChanged(config);
3996
3997            if (activity != null) {
3998                if (!activity.mCalled) {
3999                    throw new SuperNotCalledException(
4000                            "Activity " + activity.getLocalClassName() +
4001                        " did not call through to super.onConfigurationChanged()");
4002                }
4003                activity.mConfigChangeFlags = 0;
4004                activity.mCurrentConfig = new Configuration(config);
4005            }
4006        }
4007    }
4008
4009    public final void applyConfigurationToResources(Configuration config) {
4010        synchronized (mResourcesManager) {
4011            mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4012        }
4013    }
4014
4015    final Configuration applyCompatConfiguration(int displayDensity) {
4016        Configuration config = mConfiguration;
4017        if (mCompatConfiguration == null) {
4018            mCompatConfiguration = new Configuration();
4019        }
4020        mCompatConfiguration.setTo(mConfiguration);
4021        if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
4022            config = mCompatConfiguration;
4023        }
4024        return config;
4025    }
4026
4027    final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4028
4029        int configDiff = 0;
4030
4031        synchronized (mResourcesManager) {
4032            if (mPendingConfiguration != null) {
4033                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4034                    config = mPendingConfiguration;
4035                    mCurDefaultDisplayDpi = config.densityDpi;
4036                    updateDefaultDensity();
4037                }
4038                mPendingConfiguration = null;
4039            }
4040
4041            if (config == null) {
4042                return;
4043            }
4044
4045            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4046                    + config);
4047
4048            mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4049
4050            if (mConfiguration == null) {
4051                mConfiguration = new Configuration();
4052            }
4053            if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4054                return;
4055            }
4056            configDiff = mConfiguration.diff(config);
4057            mConfiguration.updateFrom(config);
4058            config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4059        }
4060
4061        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4062
4063        freeTextLayoutCachesIfNeeded(configDiff);
4064
4065        if (callbacks != null) {
4066            final int N = callbacks.size();
4067            for (int i=0; i<N; i++) {
4068                performConfigurationChanged(callbacks.get(i), config);
4069            }
4070        }
4071    }
4072
4073    static void freeTextLayoutCachesIfNeeded(int configDiff) {
4074        if (configDiff != 0) {
4075            // Ask text layout engine to free its caches if there is a locale change
4076            boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4077            if (hasLocaleConfigChange) {
4078                Canvas.freeTextLayoutCaches();
4079                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4080            }
4081        }
4082    }
4083
4084    final void handleActivityConfigurationChanged(IBinder token) {
4085        ActivityClientRecord r = mActivities.get(token);
4086        if (r == null || r.activity == null) {
4087            return;
4088        }
4089
4090        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4091                + r.activityInfo.name);
4092
4093        performConfigurationChanged(r.activity, mCompatConfiguration);
4094
4095        freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
4096    }
4097
4098    final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
4099        if (start) {
4100            try {
4101                switch (profileType) {
4102                    default:
4103                        mProfiler.setProfiler(pcd.path, pcd.fd);
4104                        mProfiler.autoStopProfiler = false;
4105                        mProfiler.startProfiling();
4106                        break;
4107                }
4108            } catch (RuntimeException e) {
4109                Slog.w(TAG, "Profiling failed on path " + pcd.path
4110                        + " -- can the process access this path?");
4111            } finally {
4112                try {
4113                    pcd.fd.close();
4114                } catch (IOException e) {
4115                    Slog.w(TAG, "Failure closing profile fd", e);
4116                }
4117            }
4118        } else {
4119            switch (profileType) {
4120                default:
4121                    mProfiler.stopProfiling();
4122                    break;
4123            }
4124        }
4125    }
4126
4127    static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4128        if (managed) {
4129            try {
4130                Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4131            } catch (IOException e) {
4132                Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4133                        + " -- can the process access this path?");
4134            } finally {
4135                try {
4136                    dhd.fd.close();
4137                } catch (IOException e) {
4138                    Slog.w(TAG, "Failure closing profile fd", e);
4139                }
4140            }
4141        } else {
4142            Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4143        }
4144    }
4145
4146    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4147        boolean hasPkgInfo = false;
4148        if (packages != null) {
4149            for (int i=packages.length-1; i>=0; i--) {
4150                //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4151                if (!hasPkgInfo) {
4152                    WeakReference<LoadedApk> ref;
4153                    ref = mPackages.get(packages[i]);
4154                    if (ref != null && ref.get() != null) {
4155                        hasPkgInfo = true;
4156                    } else {
4157                        ref = mResourcePackages.get(packages[i]);
4158                        if (ref != null && ref.get() != null) {
4159                            hasPkgInfo = true;
4160                        }
4161                    }
4162                }
4163                mPackages.remove(packages[i]);
4164                mResourcePackages.remove(packages[i]);
4165            }
4166        }
4167        ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4168                hasPkgInfo);
4169    }
4170
4171    final void handleLowMemory() {
4172        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4173
4174        final int N = callbacks.size();
4175        for (int i=0; i<N; i++) {
4176            callbacks.get(i).onLowMemory();
4177        }
4178
4179        // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4180        if (Process.myUid() != Process.SYSTEM_UID) {
4181            int sqliteReleased = SQLiteDatabase.releaseMemory();
4182            EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4183        }
4184
4185        // Ask graphics to free up as much as possible (font/image caches)
4186        Canvas.freeCaches();
4187
4188        // Ask text layout engine to free also as much as possible
4189        Canvas.freeTextLayoutCaches();
4190
4191        BinderInternal.forceGc("mem");
4192    }
4193
4194    final void handleTrimMemory(int level) {
4195        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4196
4197        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4198
4199        final int N = callbacks.size();
4200        for (int i = 0; i < N; i++) {
4201            callbacks.get(i).onTrimMemory(level);
4202        }
4203
4204        WindowManagerGlobal.getInstance().trimMemory(level);
4205    }
4206
4207    private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4208        if (Process.isIsolated()) {
4209            // Isolated processes aren't going to do UI.
4210            return;
4211        }
4212        try {
4213            int uid = Process.myUid();
4214            String[] packages = getPackageManager().getPackagesForUid(uid);
4215
4216            // If there are several packages in this application we won't
4217            // initialize the graphics disk caches
4218            if (packages != null && packages.length == 1) {
4219                HardwareRenderer.setupDiskCache(cacheDir);
4220                RenderScript.setupDiskCache(cacheDir);
4221            }
4222        } catch (RemoteException e) {
4223            // Ignore
4224        }
4225    }
4226
4227    private void updateDefaultDensity() {
4228        if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4229                && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4230                && !mDensityCompatMode) {
4231            Slog.i(TAG, "Switching default density from "
4232                    + DisplayMetrics.DENSITY_DEVICE + " to "
4233                    + mCurDefaultDisplayDpi);
4234            DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4235            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4236        }
4237    }
4238
4239    private void handleBindApplication(AppBindData data) {
4240        mBoundApplication = data;
4241        mConfiguration = new Configuration(data.config);
4242        mCompatConfiguration = new Configuration(data.config);
4243
4244        mProfiler = new Profiler();
4245        mProfiler.profileFile = data.initProfileFile;
4246        mProfiler.profileFd = data.initProfileFd;
4247        mProfiler.autoStopProfiler = data.initAutoStopProfiler;
4248
4249        // send up app name; do this *before* waiting for debugger
4250        Process.setArgV0(data.processName);
4251        android.ddm.DdmHandleAppName.setAppName(data.processName,
4252                                                UserHandle.myUserId());
4253
4254        if (data.persistent) {
4255            // Persistent processes on low-memory devices do not get to
4256            // use hardware accelerated drawing, since this can add too much
4257            // overhead to the process.
4258            if (!ActivityManager.isHighEndGfx()) {
4259                HardwareRenderer.disable(false);
4260            }
4261        }
4262
4263        if (mProfiler.profileFd != null) {
4264            mProfiler.startProfiling();
4265        }
4266
4267        // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4268        // implementation to use the pool executor.  Normally, we use the
4269        // serialized executor as the default. This has to happen in the
4270        // main thread so the main looper is set right.
4271        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
4272            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4273        }
4274
4275        /*
4276         * Before spawning a new process, reset the time zone to be the system time zone.
4277         * This needs to be done because the system time zone could have changed after the
4278         * the spawning of this process. Without doing this this process would have the incorrect
4279         * system time zone.
4280         */
4281        TimeZone.setDefault(null);
4282
4283        /*
4284         * Initialize the default locale in this process for the reasons we set the time zone.
4285         */
4286        Locale.setDefault(data.config.locale);
4287
4288        /*
4289         * Update the system configuration since its preloaded and might not
4290         * reflect configuration changes. The configuration object passed
4291         * in AppBindData can be safely assumed to be up to date
4292         */
4293        mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
4294        mCurDefaultDisplayDpi = data.config.densityDpi;
4295        applyCompatConfiguration(mCurDefaultDisplayDpi);
4296
4297        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
4298
4299        /**
4300         * Switch this process to density compatibility mode if needed.
4301         */
4302        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4303                == 0) {
4304            mDensityCompatMode = true;
4305            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4306        }
4307        updateDefaultDensity();
4308
4309        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
4310        if (!Process.isIsolated()) {
4311            final File cacheDir = appContext.getCacheDir();
4312
4313            if (cacheDir != null) {
4314                // Provide a usable directory for temporary files
4315                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4316
4317                setupGraphicsSupport(data.info, cacheDir);
4318            } else {
4319                Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4320            }
4321        }
4322
4323
4324        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
4325        DateFormat.set24HourTimePref(is24Hr);
4326
4327        /**
4328         * For system applications on userdebug/eng builds, log stack
4329         * traces of disk and network access to dropbox for analysis.
4330         */
4331        if ((data.appInfo.flags &
4332             (ApplicationInfo.FLAG_SYSTEM |
4333              ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4334            StrictMode.conditionallyEnableDebugLogging();
4335        }
4336
4337        /**
4338         * For apps targetting SDK Honeycomb or later, we don't allow
4339         * network usage on the main event loop / UI thread.
4340         *
4341         * Note to those grepping:  this is what ultimately throws
4342         * NetworkOnMainThreadException ...
4343         */
4344        if (data.appInfo.targetSdkVersion > 9) {
4345            StrictMode.enableDeathOnNetwork();
4346        }
4347
4348        if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4349            // XXX should have option to change the port.
4350            Debug.changeDebugPort(8100);
4351            if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
4352                Slog.w(TAG, "Application " + data.info.getPackageName()
4353                      + " is waiting for the debugger on port 8100...");
4354
4355                IActivityManager mgr = ActivityManagerNative.getDefault();
4356                try {
4357                    mgr.showWaitingForDebugger(mAppThread, true);
4358                } catch (RemoteException ex) {
4359                }
4360
4361                Debug.waitForDebugger();
4362
4363                try {
4364                    mgr.showWaitingForDebugger(mAppThread, false);
4365                } catch (RemoteException ex) {
4366                }
4367
4368            } else {
4369                Slog.w(TAG, "Application " + data.info.getPackageName()
4370                      + " can be debugged on port 8100...");
4371            }
4372        }
4373
4374        // Enable OpenGL tracing if required
4375        if (data.enableOpenGlTrace) {
4376            GLUtils.setTracingLevel(1);
4377        }
4378
4379        // Allow application-generated systrace messages if we're debuggable.
4380        boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
4381        Trace.setAppTracingAllowed(appTracingAllowed);
4382
4383        /**
4384         * Initialize the default http proxy in this process for the reasons we set the time zone.
4385         */
4386        IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
4387        if (b != null) {
4388            // In pre-boot mode (doing initial launch to collect password), not
4389            // all system is up.  This includes the connectivity service, so don't
4390            // crash if we can't get it.
4391            IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4392            try {
4393                ProxyInfo proxyInfo = service.getProxy();
4394                Proxy.setHttpProxySystemProperty(proxyInfo);
4395            } catch (RemoteException e) {}
4396        }
4397
4398        if (data.instrumentationName != null) {
4399            InstrumentationInfo ii = null;
4400            try {
4401                ii = appContext.getPackageManager().
4402                    getInstrumentationInfo(data.instrumentationName, 0);
4403            } catch (PackageManager.NameNotFoundException e) {
4404            }
4405            if (ii == null) {
4406                throw new RuntimeException(
4407                    "Unable to find instrumentation info for: "
4408                    + data.instrumentationName);
4409            }
4410
4411            mInstrumentationPackageName = ii.packageName;
4412            mInstrumentationAppDir = ii.sourceDir;
4413            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
4414            mInstrumentationLibDir = ii.nativeLibraryDir;
4415            mInstrumentedAppDir = data.info.getAppDir();
4416            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
4417            mInstrumentedLibDir = data.info.getLibDir();
4418
4419            ApplicationInfo instrApp = new ApplicationInfo();
4420            instrApp.packageName = ii.packageName;
4421            instrApp.sourceDir = ii.sourceDir;
4422            instrApp.publicSourceDir = ii.publicSourceDir;
4423            instrApp.splitSourceDirs = ii.splitSourceDirs;
4424            instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
4425            instrApp.dataDir = ii.dataDir;
4426            instrApp.nativeLibraryDir = ii.nativeLibraryDir;
4427            LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
4428                    appContext.getClassLoader(), false, true, false);
4429            ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
4430
4431            try {
4432                java.lang.ClassLoader cl = instrContext.getClassLoader();
4433                mInstrumentation = (Instrumentation)
4434                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4435            } catch (Exception e) {
4436                throw new RuntimeException(
4437                    "Unable to instantiate instrumentation "
4438                    + data.instrumentationName + ": " + e.toString(), e);
4439            }
4440
4441            mInstrumentation.init(this, instrContext, appContext,
4442                   new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
4443                   data.instrumentationUiAutomationConnection);
4444
4445            if (mProfiler.profileFile != null && !ii.handleProfiling
4446                    && mProfiler.profileFd == null) {
4447                mProfiler.handlingProfiling = true;
4448                File file = new File(mProfiler.profileFile);
4449                file.getParentFile().mkdirs();
4450                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4451            }
4452
4453        } else {
4454            mInstrumentation = new Instrumentation();
4455        }
4456
4457        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
4458            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
4459        }
4460
4461        // Allow disk access during application and provider setup. This could
4462        // block processing ordered broadcasts, but later processing would
4463        // probably end up doing the same disk access.
4464        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4465        try {
4466            // If the app is being launched for full backup or restore, bring it up in
4467            // a restricted environment with the base application class.
4468            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4469            mInitialApplication = app;
4470
4471            // don't bring up providers in restricted mode; they may depend on the
4472            // app's custom Application class
4473            if (!data.restrictedBackupMode) {
4474                List<ProviderInfo> providers = data.providers;
4475                if (providers != null) {
4476                    installContentProviders(app, providers);
4477                    // For process that contains content providers, we want to
4478                    // ensure that the JIT is enabled "at some point".
4479                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4480                }
4481            }
4482
4483            // Do this after providers, since instrumentation tests generally start their
4484            // test thread at this point, and we don't want that racing.
4485            try {
4486                mInstrumentation.onCreate(data.instrumentationArgs);
4487            }
4488            catch (Exception e) {
4489                throw new RuntimeException(
4490                    "Exception thrown in onCreate() of "
4491                    + data.instrumentationName + ": " + e.toString(), e);
4492            }
4493
4494            try {
4495                mInstrumentation.callApplicationOnCreate(app);
4496            } catch (Exception e) {
4497                if (!mInstrumentation.onException(app, e)) {
4498                    throw new RuntimeException(
4499                        "Unable to create application " + app.getClass().getName()
4500                        + ": " + e.toString(), e);
4501                }
4502            }
4503        } finally {
4504            StrictMode.setThreadPolicy(savedPolicy);
4505        }
4506    }
4507
4508    /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4509        IActivityManager am = ActivityManagerNative.getDefault();
4510        if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4511                && mProfiler.profileFd == null) {
4512            Debug.stopMethodTracing();
4513        }
4514        //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
4515        //      + ", app thr: " + mAppThread);
4516        try {
4517            am.finishInstrumentation(mAppThread, resultCode, results);
4518        } catch (RemoteException ex) {
4519        }
4520    }
4521
4522    private void installContentProviders(
4523            Context context, List<ProviderInfo> providers) {
4524        final ArrayList<IActivityManager.ContentProviderHolder> results =
4525            new ArrayList<IActivityManager.ContentProviderHolder>();
4526
4527        for (ProviderInfo cpi : providers) {
4528            if (DEBUG_PROVIDER) {
4529                StringBuilder buf = new StringBuilder(128);
4530                buf.append("Pub ");
4531                buf.append(cpi.authority);
4532                buf.append(": ");
4533                buf.append(cpi.name);
4534                Log.i(TAG, buf.toString());
4535            }
4536            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4537                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4538            if (cph != null) {
4539                cph.noReleaseNeeded = true;
4540                results.add(cph);
4541            }
4542        }
4543
4544        try {
4545            ActivityManagerNative.getDefault().publishContentProviders(
4546                getApplicationThread(), results);
4547        } catch (RemoteException ex) {
4548        }
4549    }
4550
4551    public final IContentProvider acquireProvider(
4552            Context c, String auth, int userId, boolean stable) {
4553        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4554        if (provider != null) {
4555            return provider;
4556        }
4557
4558        // There is a possible race here.  Another thread may try to acquire
4559        // the same provider at the same time.  When this happens, we want to ensure
4560        // that the first one wins.
4561        // Note that we cannot hold the lock while acquiring and installing the
4562        // provider since it might take a long time to run and it could also potentially
4563        // be re-entrant in the case where the provider is in the same process.
4564        IActivityManager.ContentProviderHolder holder = null;
4565        try {
4566            holder = ActivityManagerNative.getDefault().getContentProvider(
4567                    getApplicationThread(), auth, userId, stable);
4568        } catch (RemoteException ex) {
4569        }
4570        if (holder == null) {
4571            Slog.e(TAG, "Failed to find provider info for " + auth);
4572            return null;
4573        }
4574
4575        // Install provider will increment the reference count for us, and break
4576        // any ties in the race.
4577        holder = installProvider(c, holder, holder.info,
4578                true /*noisy*/, holder.noReleaseNeeded, stable);
4579        return holder.provider;
4580    }
4581
4582    private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4583        if (stable) {
4584            prc.stableCount += 1;
4585            if (prc.stableCount == 1) {
4586                // We are acquiring a new stable reference on the provider.
4587                int unstableDelta;
4588                if (prc.removePending) {
4589                    // We have a pending remove operation, which is holding the
4590                    // last unstable reference.  At this point we are converting
4591                    // that unstable reference to our new stable reference.
4592                    unstableDelta = -1;
4593                    // Cancel the removal of the provider.
4594                    if (DEBUG_PROVIDER) {
4595                        Slog.v(TAG, "incProviderRef: stable "
4596                                + "snatched provider from the jaws of death");
4597                    }
4598                    prc.removePending = false;
4599                    // There is a race! It fails to remove the message, which
4600                    // will be handled in completeRemoveProvider().
4601                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
4602                } else {
4603                    unstableDelta = 0;
4604                }
4605                try {
4606                    if (DEBUG_PROVIDER) {
4607                        Slog.v(TAG, "incProviderRef Now stable - "
4608                                + prc.holder.info.name + ": unstableDelta="
4609                                + unstableDelta);
4610                    }
4611                    ActivityManagerNative.getDefault().refContentProvider(
4612                            prc.holder.connection, 1, unstableDelta);
4613                } catch (RemoteException e) {
4614                    //do nothing content provider object is dead any way
4615                }
4616            }
4617        } else {
4618            prc.unstableCount += 1;
4619            if (prc.unstableCount == 1) {
4620                // We are acquiring a new unstable reference on the provider.
4621                if (prc.removePending) {
4622                    // Oh look, we actually have a remove pending for the
4623                    // provider, which is still holding the last unstable
4624                    // reference.  We just need to cancel that to take new
4625                    // ownership of the reference.
4626                    if (DEBUG_PROVIDER) {
4627                        Slog.v(TAG, "incProviderRef: unstable "
4628                                + "snatched provider from the jaws of death");
4629                    }
4630                    prc.removePending = false;
4631                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
4632                } else {
4633                    // First unstable ref, increment our count in the
4634                    // activity manager.
4635                    try {
4636                        if (DEBUG_PROVIDER) {
4637                            Slog.v(TAG, "incProviderRef: Now unstable - "
4638                                    + prc.holder.info.name);
4639                        }
4640                        ActivityManagerNative.getDefault().refContentProvider(
4641                                prc.holder.connection, 0, 1);
4642                    } catch (RemoteException e) {
4643                        //do nothing content provider object is dead any way
4644                    }
4645                }
4646            }
4647        }
4648    }
4649
4650    public final IContentProvider acquireExistingProvider(
4651            Context c, String auth, int userId, boolean stable) {
4652        synchronized (mProviderMap) {
4653            final ProviderKey key = new ProviderKey(auth, userId);
4654            final ProviderClientRecord pr = mProviderMap.get(key);
4655            if (pr == null) {
4656                return null;
4657            }
4658
4659            IContentProvider provider = pr.mProvider;
4660            IBinder jBinder = provider.asBinder();
4661            if (!jBinder.isBinderAlive()) {
4662                // The hosting process of the provider has died; we can't
4663                // use this one.
4664                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4665                        + ": existing object's process dead");
4666                handleUnstableProviderDiedLocked(jBinder, true);
4667                return null;
4668            }
4669
4670            // Only increment the ref count if we have one.  If we don't then the
4671            // provider is not reference counted and never needs to be released.
4672            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4673            if (prc != null) {
4674                incProviderRefLocked(prc, stable);
4675            }
4676            return provider;
4677        }
4678    }
4679
4680    public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4681        if (provider == null) {
4682            return false;
4683        }
4684
4685        IBinder jBinder = provider.asBinder();
4686        synchronized (mProviderMap) {
4687            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4688            if (prc == null) {
4689                // The provider has no ref count, no release is needed.
4690                return false;
4691            }
4692
4693            boolean lastRef = false;
4694            if (stable) {
4695                if (prc.stableCount == 0) {
4696                    if (DEBUG_PROVIDER) Slog.v(TAG,
4697                            "releaseProvider: stable ref count already 0, how?");
4698                    return false;
4699                }
4700                prc.stableCount -= 1;
4701                if (prc.stableCount == 0) {
4702                    // What we do at this point depends on whether there are
4703                    // any unstable refs left: if there are, we just tell the
4704                    // activity manager to decrement its stable count; if there
4705                    // aren't, we need to enqueue this provider to be removed,
4706                    // and convert to holding a single unstable ref while
4707                    // doing so.
4708                    lastRef = prc.unstableCount == 0;
4709                    try {
4710                        if (DEBUG_PROVIDER) {
4711                            Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4712                                    + lastRef + " - " + prc.holder.info.name);
4713                        }
4714                        ActivityManagerNative.getDefault().refContentProvider(
4715                                prc.holder.connection, -1, lastRef ? 1 : 0);
4716                    } catch (RemoteException e) {
4717                        //do nothing content provider object is dead any way
4718                    }
4719                }
4720            } else {
4721                if (prc.unstableCount == 0) {
4722                    if (DEBUG_PROVIDER) Slog.v(TAG,
4723                            "releaseProvider: unstable ref count already 0, how?");
4724                    return false;
4725                }
4726                prc.unstableCount -= 1;
4727                if (prc.unstableCount == 0) {
4728                    // If this is the last reference, we need to enqueue
4729                    // this provider to be removed instead of telling the
4730                    // activity manager to remove it at this point.
4731                    lastRef = prc.stableCount == 0;
4732                    if (!lastRef) {
4733                        try {
4734                            if (DEBUG_PROVIDER) {
4735                                Slog.v(TAG, "releaseProvider: No longer unstable - "
4736                                        + prc.holder.info.name);
4737                            }
4738                            ActivityManagerNative.getDefault().refContentProvider(
4739                                    prc.holder.connection, 0, -1);
4740                        } catch (RemoteException e) {
4741                            //do nothing content provider object is dead any way
4742                        }
4743                    }
4744                }
4745            }
4746
4747            if (lastRef) {
4748                if (!prc.removePending) {
4749                    // Schedule the actual remove asynchronously, since we don't know the context
4750                    // this will be called in.
4751                    // TODO: it would be nice to post a delayed message, so
4752                    // if we come back and need the same provider quickly
4753                    // we will still have it available.
4754                    if (DEBUG_PROVIDER) {
4755                        Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4756                                + prc.holder.info.name);
4757                    }
4758                    prc.removePending = true;
4759                    Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4760                    mH.sendMessage(msg);
4761                } else {
4762                    Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4763                }
4764            }
4765            return true;
4766        }
4767    }
4768
4769    final void completeRemoveProvider(ProviderRefCount prc) {
4770        synchronized (mProviderMap) {
4771            if (!prc.removePending) {
4772                // There was a race!  Some other client managed to acquire
4773                // the provider before the removal was completed.
4774                // Abort the removal.  We will do it later.
4775                if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
4776                        + "provider still in use");
4777                return;
4778            }
4779
4780            // More complicated race!! Some client managed to acquire the
4781            // provider and release it before the removal was completed.
4782            // Continue the removal, and abort the next remove message.
4783            prc.removePending = false;
4784
4785            final IBinder jBinder = prc.holder.provider.asBinder();
4786            ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4787            if (existingPrc == prc) {
4788                mProviderRefCountMap.remove(jBinder);
4789            }
4790
4791            for (int i=mProviderMap.size()-1; i>=0; i--) {
4792                ProviderClientRecord pr = mProviderMap.valueAt(i);
4793                IBinder myBinder = pr.mProvider.asBinder();
4794                if (myBinder == jBinder) {
4795                    mProviderMap.removeAt(i);
4796                }
4797            }
4798        }
4799
4800        try {
4801            if (DEBUG_PROVIDER) {
4802                Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4803                        + "removeContentProvider(" + prc.holder.info.name + ")");
4804            }
4805            ActivityManagerNative.getDefault().removeContentProvider(
4806                    prc.holder.connection, false);
4807        } catch (RemoteException e) {
4808            //do nothing content provider object is dead any way
4809        }
4810    }
4811
4812    final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4813        synchronized (mProviderMap) {
4814            handleUnstableProviderDiedLocked(provider, fromClient);
4815        }
4816    }
4817
4818    final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
4819        ProviderRefCount prc = mProviderRefCountMap.get(provider);
4820        if (prc != null) {
4821            if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4822                    + provider + " " + prc.holder.info.name);
4823            mProviderRefCountMap.remove(provider);
4824            for (int i=mProviderMap.size()-1; i>=0; i--) {
4825                ProviderClientRecord pr = mProviderMap.valueAt(i);
4826                if (pr != null && pr.mProvider.asBinder() == provider) {
4827                    Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
4828                    mProviderMap.removeAt(i);
4829                }
4830            }
4831
4832            if (fromClient) {
4833                // We found out about this due to execution in our client
4834                // code.  Tell the activity manager about it now, to ensure
4835                // that the next time we go to do anything with the provider
4836                // it knows it is dead (so we don't race with its death
4837                // notification).
4838                try {
4839                    ActivityManagerNative.getDefault().unstableProviderDied(
4840                            prc.holder.connection);
4841                } catch (RemoteException e) {
4842                    //do nothing content provider object is dead any way
4843                }
4844            }
4845        }
4846    }
4847
4848    final void appNotRespondingViaProvider(IBinder provider) {
4849        synchronized (mProviderMap) {
4850            ProviderRefCount prc = mProviderRefCountMap.get(provider);
4851            if (prc != null) {
4852                try {
4853                    ActivityManagerNative.getDefault()
4854                            .appNotRespondingViaProvider(prc.holder.connection);
4855                } catch (RemoteException e) {
4856                }
4857            }
4858        }
4859    }
4860
4861    private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4862            ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4863        final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4864        final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4865
4866        final ProviderClientRecord pcr = new ProviderClientRecord(
4867                auths, provider, localProvider, holder);
4868        for (String auth : auths) {
4869            final ProviderKey key = new ProviderKey(auth, userId);
4870            final ProviderClientRecord existing = mProviderMap.get(key);
4871            if (existing != null) {
4872                Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
4873                        + " already published as " + auth);
4874            } else {
4875                mProviderMap.put(key, pcr);
4876            }
4877        }
4878        return pcr;
4879    }
4880
4881    /**
4882     * Installs the provider.
4883     *
4884     * Providers that are local to the process or that come from the system server
4885     * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4886     * Other remote providers are reference counted.  The initial reference count
4887     * for all reference counted providers is one.  Providers that are not reference
4888     * counted do not have a reference count (at all).
4889     *
4890     * This method detects when a provider has already been installed.  When this happens,
4891     * it increments the reference count of the existing provider (if appropriate)
4892     * and returns the existing provider.  This can happen due to concurrent
4893     * attempts to acquire the same provider.
4894     */
4895    private IActivityManager.ContentProviderHolder installProvider(Context context,
4896            IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4897            boolean noisy, boolean noReleaseNeeded, boolean stable) {
4898        ContentProvider localProvider = null;
4899        IContentProvider provider;
4900        if (holder == null || holder.provider == null) {
4901            if (DEBUG_PROVIDER || noisy) {
4902                Slog.d(TAG, "Loading provider " + info.authority + ": "
4903                        + info.name);
4904            }
4905            Context c = null;
4906            ApplicationInfo ai = info.applicationInfo;
4907            if (context.getPackageName().equals(ai.packageName)) {
4908                c = context;
4909            } else if (mInitialApplication != null &&
4910                    mInitialApplication.getPackageName().equals(ai.packageName)) {
4911                c = mInitialApplication;
4912            } else {
4913                try {
4914                    c = context.createPackageContext(ai.packageName,
4915                            Context.CONTEXT_INCLUDE_CODE);
4916                } catch (PackageManager.NameNotFoundException e) {
4917                    // Ignore
4918                }
4919            }
4920            if (c == null) {
4921                Slog.w(TAG, "Unable to get context for package " +
4922                      ai.packageName +
4923                      " while loading content provider " +
4924                      info.name);
4925                return null;
4926            }
4927            try {
4928                final java.lang.ClassLoader cl = c.getClassLoader();
4929                localProvider = (ContentProvider)cl.
4930                    loadClass(info.name).newInstance();
4931                provider = localProvider.getIContentProvider();
4932                if (provider == null) {
4933                    Slog.e(TAG, "Failed to instantiate class " +
4934                          info.name + " from sourceDir " +
4935                          info.applicationInfo.sourceDir);
4936                    return null;
4937                }
4938                if (DEBUG_PROVIDER) Slog.v(
4939                    TAG, "Instantiating local provider " + info.name);
4940                // XXX Need to create the correct context for this provider.
4941                localProvider.attachInfo(c, info);
4942            } catch (java.lang.Exception e) {
4943                if (!mInstrumentation.onException(null, e)) {
4944                    throw new RuntimeException(
4945                            "Unable to get provider " + info.name
4946                            + ": " + e.toString(), e);
4947                }
4948                return null;
4949            }
4950        } else {
4951            provider = holder.provider;
4952            if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
4953                    + info.name);
4954        }
4955
4956        IActivityManager.ContentProviderHolder retHolder;
4957
4958        synchronized (mProviderMap) {
4959            if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4960                    + " / " + info.name);
4961            IBinder jBinder = provider.asBinder();
4962            if (localProvider != null) {
4963                ComponentName cname = new ComponentName(info.packageName, info.name);
4964                ProviderClientRecord pr = mLocalProvidersByName.get(cname);
4965                if (pr != null) {
4966                    if (DEBUG_PROVIDER) {
4967                        Slog.v(TAG, "installProvider: lost the race, "
4968                                + "using existing local provider");
4969                    }
4970                    provider = pr.mProvider;
4971                } else {
4972                    holder = new IActivityManager.ContentProviderHolder(info);
4973                    holder.provider = provider;
4974                    holder.noReleaseNeeded = true;
4975                    pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
4976                    mLocalProviders.put(jBinder, pr);
4977                    mLocalProvidersByName.put(cname, pr);
4978                }
4979                retHolder = pr.mHolder;
4980            } else {
4981                ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4982                if (prc != null) {
4983                    if (DEBUG_PROVIDER) {
4984                        Slog.v(TAG, "installProvider: lost the race, updating ref count");
4985                    }
4986                    // We need to transfer our new reference to the existing
4987                    // ref count, releasing the old one...  but only if
4988                    // release is needed (that is, it is not running in the
4989                    // system process).
4990                    if (!noReleaseNeeded) {
4991                        incProviderRefLocked(prc, stable);
4992                        try {
4993                            ActivityManagerNative.getDefault().removeContentProvider(
4994                                    holder.connection, stable);
4995                        } catch (RemoteException e) {
4996                            //do nothing content provider object is dead any way
4997                        }
4998                    }
4999                } else {
5000                    ProviderClientRecord client = installProviderAuthoritiesLocked(
5001                            provider, localProvider, holder);
5002                    if (noReleaseNeeded) {
5003                        prc = new ProviderRefCount(holder, client, 1000, 1000);
5004                    } else {
5005                        prc = stable
5006                                ? new ProviderRefCount(holder, client, 1, 0)
5007                                : new ProviderRefCount(holder, client, 0, 1);
5008                    }
5009                    mProviderRefCountMap.put(jBinder, prc);
5010                }
5011                retHolder = prc.holder;
5012            }
5013        }
5014
5015        return retHolder;
5016    }
5017
5018    private void attach(boolean system) {
5019        sCurrentActivityThread = this;
5020        mSystemThread = system;
5021        if (!system) {
5022            ViewRootImpl.addFirstDrawHandler(new Runnable() {
5023                @Override
5024                public void run() {
5025                    ensureJitEnabled();
5026                }
5027            });
5028            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5029                                                    UserHandle.myUserId());
5030            RuntimeInit.setApplicationObject(mAppThread.asBinder());
5031            IActivityManager mgr = ActivityManagerNative.getDefault();
5032            try {
5033                mgr.attachApplication(mAppThread);
5034            } catch (RemoteException ex) {
5035                // Ignore
5036            }
5037        } else {
5038            // Don't set application object here -- if the system crashes,
5039            // we can't display an alert, we just want to die die die.
5040            android.ddm.DdmHandleAppName.setAppName("system_process",
5041                                                    UserHandle.myUserId());
5042            try {
5043                mInstrumentation = new Instrumentation();
5044                ContextImpl context = ContextImpl.createAppContext(
5045                        this, getSystemContext().mPackageInfo);
5046                Application app = Instrumentation.newApplication(Application.class, context);
5047                mAllApplications.add(app);
5048                mInitialApplication = app;
5049                app.onCreate();
5050            } catch (Exception e) {
5051                throw new RuntimeException(
5052                        "Unable to instantiate Application():" + e.toString(), e);
5053            }
5054        }
5055
5056        // add dropbox logging to libcore
5057        DropBox.setReporter(new DropBoxReporter());
5058
5059        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5060            @Override
5061            public void onConfigurationChanged(Configuration newConfig) {
5062                synchronized (mResourcesManager) {
5063                    // We need to apply this change to the resources
5064                    // immediately, because upon returning the view
5065                    // hierarchy will be informed about it.
5066                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
5067                        // This actually changed the resources!  Tell
5068                        // everyone about it.
5069                        if (mPendingConfiguration == null ||
5070                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5071                            mPendingConfiguration = newConfig;
5072
5073                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5074                        }
5075                    }
5076                }
5077            }
5078            @Override
5079            public void onLowMemory() {
5080            }
5081            @Override
5082            public void onTrimMemory(int level) {
5083            }
5084        });
5085    }
5086
5087    public static ActivityThread systemMain() {
5088        // The system process on low-memory devices do not get to use hardware
5089        // accelerated drawing, since this can add too much overhead to the
5090        // process.
5091        if (!ActivityManager.isHighEndGfx()) {
5092            HardwareRenderer.disable(true);
5093        }
5094        ActivityThread thread = new ActivityThread();
5095        thread.attach(true);
5096        return thread;
5097    }
5098
5099    public final void installSystemProviders(List<ProviderInfo> providers) {
5100        if (providers != null) {
5101            installContentProviders(mInitialApplication, providers);
5102        }
5103    }
5104
5105    public int getIntCoreSetting(String key, int defaultValue) {
5106        synchronized (mResourcesManager) {
5107            if (mCoreSettings != null) {
5108                return mCoreSettings.getInt(key, defaultValue);
5109            }
5110            return defaultValue;
5111        }
5112    }
5113
5114    private static class EventLoggingReporter implements EventLogger.Reporter {
5115        @Override
5116        public void report (int code, Object... list) {
5117            EventLog.writeEvent(code, list);
5118        }
5119    }
5120
5121    private class DropBoxReporter implements DropBox.Reporter {
5122
5123        private DropBoxManager dropBox;
5124
5125        public DropBoxReporter() {
5126            dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
5127        }
5128
5129        @Override
5130        public void addData(String tag, byte[] data, int flags) {
5131            dropBox.addData(tag, data, flags);
5132        }
5133
5134        @Override
5135        public void addText(String tag, String data) {
5136            dropBox.addText(tag, data);
5137        }
5138    }
5139
5140    public static void main(String[] args) {
5141        SamplingProfilerIntegration.start();
5142
5143        // CloseGuard defaults to true and can be quite spammy.  We
5144        // disable it here, but selectively enable it later (via
5145        // StrictMode) on debug builds, but using DropBox, not logs.
5146        CloseGuard.setEnabled(false);
5147
5148        Environment.initForCurrentUser();
5149
5150        // Set the reporter for event logging in libcore
5151        EventLogger.setReporter(new EventLoggingReporter());
5152
5153        Security.addProvider(new AndroidKeyStoreProvider());
5154
5155        // Make sure TrustedCertificateStore looks in the right place for CA certificates
5156        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
5157        TrustedCertificateStore.setDefaultUserDirectory(configDir);
5158
5159        Process.setArgV0("<pre-initialized>");
5160
5161        Looper.prepareMainLooper();
5162
5163        ActivityThread thread = new ActivityThread();
5164        thread.attach(false);
5165
5166        if (sMainThreadHandler == null) {
5167            sMainThreadHandler = thread.getHandler();
5168        }
5169
5170        AsyncTask.init();
5171
5172        if (false) {
5173            Looper.myLooper().setMessageLogging(new
5174                    LogPrinter(Log.DEBUG, "ActivityThread"));
5175        }
5176
5177        Looper.loop();
5178
5179        throw new RuntimeException("Main thread loop unexpectedly exited");
5180    }
5181}
5182