OSDN Git Service

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