OSDN Git Service

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