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