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