OSDN Git Service

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