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