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