2 * Copyright (C) 2006 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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.DisplayManager;
47 import android.hardware.display.DisplayManagerGlobal;
48 import android.net.IConnectivityManager;
49 import android.net.Proxy;
50 import android.net.ProxyProperties;
51 import android.opengl.GLUtils;
52 import android.os.AsyncTask;
53 import android.os.Binder;
54 import android.os.Bundle;
55 import android.os.Debug;
56 import android.os.DropBoxManager;
57 import android.os.Environment;
58 import android.os.Handler;
59 import android.os.IBinder;
60 import android.os.Looper;
61 import android.os.Message;
62 import android.os.MessageQueue;
63 import android.os.ParcelFileDescriptor;
64 import android.os.Process;
65 import android.os.RemoteException;
66 import android.os.ServiceManager;
67 import android.os.StrictMode;
68 import android.os.SystemClock;
69 import android.os.SystemProperties;
70 import android.os.Trace;
71 import android.os.UserHandle;
72 import android.util.AndroidRuntimeException;
73 import android.util.DisplayMetrics;
74 import android.util.EventLog;
75 import android.util.Log;
76 import android.util.LogPrinter;
77 import android.util.PrintWriterPrinter;
78 import android.util.Slog;
79 import android.view.CompatibilityInfoHolder;
80 import android.view.Display;
81 import android.view.HardwareRenderer;
82 import android.view.View;
83 import android.view.ViewDebug;
84 import android.view.ViewManager;
85 import android.view.ViewRootImpl;
86 import android.view.Window;
87 import android.view.WindowManager;
88 import android.view.WindowManagerGlobal;
89 import android.renderscript.RenderScript;
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;
96 import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
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;
115 import libcore.io.DropBox;
116 import libcore.io.EventLogger;
117 import libcore.io.IoUtils;
119 import dalvik.system.CloseGuard;
121 final class SuperNotCalledException extends AndroidRuntimeException {
122 public SuperNotCalledException(String msg) {
127 final class RemoteServiceException extends AndroidRuntimeException {
128 public RemoteServiceException(String msg) {
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
141 public final class ActivityThread {
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;
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;
161 static ContextImpl mSystemContext = null;
163 static IPackageManager sPackageManager;
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;
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 static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
191 Instrumentation mInstrumentation;
192 String mInstrumentationAppDir = null;
193 String mInstrumentationAppLibraryDir = null;
194 String mInstrumentationAppPackage = null;
195 String mInstrumentedAppDir = null;
196 String mInstrumentedAppLibraryDir = null;
197 boolean mSystemThread = false;
198 boolean mJitEnabled = false;
200 // These can be accessed by multiple threads; mPackages is the lock.
201 // XXX For now we keep around information about all packages we have
202 // seen, not removing entries from this map.
203 // NOTE: The activity and window managers need to call in to
204 // ActivityThread to do things like update resource configurations,
205 // which means this lock gets held while the activity and window managers
206 // holds their own lock. Thus you MUST NEVER call back into the activity manager
207 // or window manager or anything that depends on them while holding this lock.
208 final HashMap<String, WeakReference<LoadedApk>> mPackages
209 = new HashMap<String, WeakReference<LoadedApk>>();
210 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
211 = new HashMap<String, WeakReference<LoadedApk>>();
212 final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
213 = new HashMap<CompatibilityInfo, DisplayMetrics>();
214 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
215 = new HashMap<ResourcesKey, WeakReference<Resources> >();
216 final ArrayList<ActivityClientRecord> mRelaunchingActivities
217 = new ArrayList<ActivityClientRecord>();
218 Configuration mPendingConfiguration = null;
220 private static final class ProviderKey {
221 final String authority;
224 public ProviderKey(String authority, int userId) {
225 this.authority = authority;
226 this.userId = userId;
230 public boolean equals(Object o) {
231 if (o instanceof ProviderKey) {
232 final ProviderKey other = (ProviderKey) o;
233 return Objects.equal(authority, other.authority) && userId == other.userId;
239 public int hashCode() {
240 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
244 // The lock of mProviderMap protects the following variables.
245 final HashMap<ProviderKey, ProviderClientRecord> mProviderMap
246 = new HashMap<ProviderKey, ProviderClientRecord>();
247 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
248 = new HashMap<IBinder, ProviderRefCount>();
249 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
250 = new HashMap<IBinder, ProviderClientRecord>();
251 final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
252 = new HashMap<ComponentName, ProviderClientRecord>();
254 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
255 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
257 final GcIdler mGcIdler = new GcIdler();
258 boolean mGcIdlerScheduled = false;
260 static Handler sMainThreadHandler; // set once in main()
262 Bundle mCoreSettings = null;
264 static final class ActivityClientRecord {
273 Activity.NonConfigurationInstances lastNonConfigurationInstances;
277 Configuration newConfig;
278 Configuration createdConfig;
279 ActivityClientRecord nextIdle;
282 ParcelFileDescriptor profileFd;
283 boolean autoStopProfiler;
285 ActivityInfo activityInfo;
286 CompatibilityInfo compatInfo;
287 LoadedApk packageInfo;
289 List<ResultInfo> pendingResults;
290 List<Intent> pendingIntents;
292 boolean startsNotResumed;
294 int pendingConfigChanges;
295 boolean onlyLocalRequest;
297 View mPendingRemoveWindow;
298 WindowManager mPendingRemoveWindowManager;
300 ActivityClientRecord() {
309 public boolean isPreHoneycomb() {
310 if (activity != null) {
311 return activity.getApplicationInfo().targetSdkVersion
312 < android.os.Build.VERSION_CODES.HONEYCOMB;
317 public String toString() {
318 ComponentName componentName = intent != null ? intent.getComponent() : null;
319 return "ActivityRecord{"
320 + Integer.toHexString(System.identityHashCode(this))
321 + " token=" + token + " " + (componentName == null
322 ? "no component name" : componentName.toShortString())
327 final class ProviderClientRecord {
328 final String[] mNames;
329 final IContentProvider mProvider;
330 final ContentProvider mLocalProvider;
331 final IActivityManager.ContentProviderHolder mHolder;
333 ProviderClientRecord(String[] names, IContentProvider provider,
334 ContentProvider localProvider,
335 IActivityManager.ContentProviderHolder holder) {
337 mProvider = provider;
338 mLocalProvider = localProvider;
343 static final class NewIntentData {
344 List<Intent> intents;
346 public String toString() {
347 return "NewIntentData{intents=" + intents + " token=" + token + "}";
351 static final class ReceiverData extends BroadcastReceiver.PendingResult {
352 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
353 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
354 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
356 this.intent = intent;
361 CompatibilityInfo compatInfo;
362 public String toString() {
363 return "ReceiverData{intent=" + intent + " packageName=" +
364 info.packageName + " resultCode=" + getResultCode()
365 + " resultData=" + getResultData() + " resultExtras="
366 + getResultExtras(false) + "}";
370 static final class CreateBackupAgentData {
371 ApplicationInfo appInfo;
372 CompatibilityInfo compatInfo;
374 public String toString() {
375 return "CreateBackupAgentData{appInfo=" + appInfo
376 + " backupAgent=" + appInfo.backupAgentName
377 + " mode=" + backupMode + "}";
381 static final class CreateServiceData {
384 CompatibilityInfo compatInfo;
386 public String toString() {
387 return "CreateServiceData{token=" + token + " className="
388 + info.name + " packageName=" + info.packageName
389 + " intent=" + intent + "}";
393 static final class BindServiceData {
397 public String toString() {
398 return "BindServiceData{token=" + token + " intent=" + intent + "}";
402 static final class ServiceArgsData {
408 public String toString() {
409 return "ServiceArgsData{token=" + token + " startId=" + startId
410 + " args=" + args + "}";
414 static final class AppBindData {
417 ApplicationInfo appInfo;
418 List<ProviderInfo> providers;
419 ComponentName instrumentationName;
420 Bundle instrumentationArgs;
421 IInstrumentationWatcher instrumentationWatcher;
423 boolean enableOpenGlTrace;
424 boolean restrictedBackupMode;
426 Configuration config;
427 CompatibilityInfo compatInfo;
429 /** Initial values for {@link Profiler}. */
430 String initProfileFile;
431 ParcelFileDescriptor initProfileFd;
432 boolean initAutoStopProfiler;
434 public String toString() {
435 return "AppBindData{appInfo=" + appInfo + "}";
439 static final class Profiler {
441 ParcelFileDescriptor profileFd;
442 boolean autoStopProfiler;
444 boolean handlingProfiling;
445 public void setProfiler(String file, ParcelFileDescriptor fd) {
450 } catch (IOException e) {
456 if (profileFd != null) {
459 } catch (IOException e) {
466 public void startProfiling() {
467 if (profileFd == null || profiling) {
471 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
474 } catch (RuntimeException e) {
475 Slog.w(TAG, "Profiling failed on path " + profileFile);
479 } catch (IOException e2) {
480 Slog.w(TAG, "Failure closing profile fd", e2);
484 public void stopProfiling() {
487 Debug.stopMethodTracing();
488 if (profileFd != null) {
491 } catch (IOException e) {
500 static final class DumpComponentInfo {
501 ParcelFileDescriptor fd;
507 static final class ResultData {
509 List<ResultInfo> results;
510 public String toString() {
511 return "ResultData{token=" + token + " results" + results + "}";
515 static final class ContextCleanupInfo {
521 static final class ProfilerControlData {
523 ParcelFileDescriptor fd;
526 static final class DumpHeapData {
528 ParcelFileDescriptor fd;
531 static final class UpdateCompatibilityData {
533 CompatibilityInfo info;
536 private native void dumpGraphicsInfo(FileDescriptor fd);
538 private class ApplicationThread extends ApplicationThreadNative {
539 private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
540 private static final String ONE_COUNT_COLUMN = "%21s %8d";
541 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
542 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
544 // Formatting for checkin service - update version if row format changes
545 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
547 private void updatePendingConfiguration(Configuration config) {
548 synchronized (mPackages) {
549 if (mPendingConfiguration == null ||
550 mPendingConfiguration.isOtherSeqNewer(config)) {
551 mPendingConfiguration = config;
556 public final void schedulePauseActivity(IBinder token, boolean finished,
557 boolean userLeaving, int configChanges) {
559 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
561 (userLeaving ? 1 : 0),
565 public final void scheduleStopActivity(IBinder token, boolean showWindow,
568 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
569 token, 0, configChanges);
572 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
574 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
578 public final void scheduleSleeping(IBinder token, boolean sleeping) {
579 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
582 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
583 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
586 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
587 ResultData res = new ResultData();
589 res.results = results;
590 queueOrSendMessage(H.SEND_RESULT, res);
593 // we use token to identify this activity without having to send the
594 // activity itself back to the activity manager. (matters more with ipc)
595 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
596 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
597 Bundle state, List<ResultInfo> pendingResults,
598 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
599 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
600 ActivityClientRecord r = new ActivityClientRecord();
605 r.activityInfo = info;
606 r.compatInfo = compatInfo;
609 r.pendingResults = pendingResults;
610 r.pendingIntents = pendingNewIntents;
612 r.startsNotResumed = notResumed;
613 r.isForward = isForward;
615 r.profileFile = profileName;
616 r.profileFd = profileFd;
617 r.autoStopProfiler = autoStopProfiler;
619 updatePendingConfiguration(curConfig);
621 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
624 public final void scheduleRelaunchActivity(IBinder token,
625 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
626 int configChanges, boolean notResumed, Configuration config) {
627 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
628 configChanges, notResumed, config, true);
631 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
632 NewIntentData data = new NewIntentData();
633 data.intents = intents;
636 queueOrSendMessage(H.NEW_INTENT, data);
639 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
641 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
645 public final void scheduleReceiver(Intent intent, ActivityInfo info,
646 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
647 boolean sync, int sendingUser) {
648 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
649 sync, false, mAppThread.asBinder(), sendingUser);
651 r.compatInfo = compatInfo;
652 queueOrSendMessage(H.RECEIVER, r);
655 public final void scheduleCreateBackupAgent(ApplicationInfo app,
656 CompatibilityInfo compatInfo, int backupMode) {
657 CreateBackupAgentData d = new CreateBackupAgentData();
659 d.compatInfo = compatInfo;
660 d.backupMode = backupMode;
662 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
665 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
666 CompatibilityInfo compatInfo) {
667 CreateBackupAgentData d = new CreateBackupAgentData();
669 d.compatInfo = compatInfo;
671 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
674 public final void scheduleCreateService(IBinder token,
675 ServiceInfo info, CompatibilityInfo compatInfo) {
676 CreateServiceData s = new CreateServiceData();
679 s.compatInfo = compatInfo;
681 queueOrSendMessage(H.CREATE_SERVICE, s);
684 public final void scheduleBindService(IBinder token, Intent intent,
686 BindServiceData s = new BindServiceData();
692 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
693 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
694 queueOrSendMessage(H.BIND_SERVICE, s);
697 public final void scheduleUnbindService(IBinder token, Intent intent) {
698 BindServiceData s = new BindServiceData();
702 queueOrSendMessage(H.UNBIND_SERVICE, s);
705 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
706 int flags ,Intent args) {
707 ServiceArgsData s = new ServiceArgsData();
709 s.taskRemoved = taskRemoved;
714 queueOrSendMessage(H.SERVICE_ARGS, s);
717 public final void scheduleStopService(IBinder token) {
718 queueOrSendMessage(H.STOP_SERVICE, token);
721 public final void bindApplication(String processName,
722 ApplicationInfo appInfo, List<ProviderInfo> providers,
723 ComponentName instrumentationName, String profileFile,
724 ParcelFileDescriptor profileFd, boolean autoStopProfiler,
725 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
726 int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,
727 boolean persistent, Configuration config, CompatibilityInfo compatInfo,
728 Map<String, IBinder> services, Bundle coreSettings) {
730 if (services != null) {
731 // Setup the service cache in the ServiceManager
732 ServiceManager.initServiceCache(services);
735 setCoreSettings(coreSettings);
737 AppBindData data = new AppBindData();
738 data.processName = processName;
739 data.appInfo = appInfo;
740 data.providers = providers;
741 data.instrumentationName = instrumentationName;
742 data.instrumentationArgs = instrumentationArgs;
743 data.instrumentationWatcher = instrumentationWatcher;
744 data.debugMode = debugMode;
745 data.enableOpenGlTrace = enableOpenGlTrace;
746 data.restrictedBackupMode = isRestrictedBackupMode;
747 data.persistent = persistent;
748 data.config = config;
749 data.compatInfo = compatInfo;
750 data.initProfileFile = profileFile;
751 data.initProfileFd = profileFd;
752 data.initAutoStopProfiler = false;
753 queueOrSendMessage(H.BIND_APPLICATION, data);
756 public final void scheduleExit() {
757 queueOrSendMessage(H.EXIT_APPLICATION, null);
760 public final void scheduleSuicide() {
761 queueOrSendMessage(H.SUICIDE, null);
764 public void requestThumbnail(IBinder token) {
765 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
768 public void scheduleConfigurationChanged(Configuration config) {
769 updatePendingConfiguration(config);
770 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
773 public void updateTimeZone() {
774 TimeZone.setDefault(null);
777 public void clearDnsCache() {
778 // a non-standard API to get this to libcore
779 InetAddress.clearDnsCache();
782 public void setHttpProxy(String host, String port, String exclList) {
783 Proxy.setHttpProxySystemProperty(host, port, exclList);
786 public void processInBackground() {
787 mH.removeMessages(H.GC_WHEN_IDLE);
788 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
791 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
792 DumpComponentInfo data = new DumpComponentInfo();
794 data.fd = ParcelFileDescriptor.dup(fd);
795 data.token = servicetoken;
797 queueOrSendMessage(H.DUMP_SERVICE, data);
798 } catch (IOException e) {
799 Slog.w(TAG, "dumpService failed", e);
803 // This function exists to make sure all receiver dispatching is
804 // correctly ordered, since these are one-way calls and the binder driver
805 // applies transaction ordering per object for such calls.
806 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
807 int resultCode, String dataStr, Bundle extras, boolean ordered,
808 boolean sticky, int sendingUser) throws RemoteException {
809 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
810 sticky, sendingUser);
813 public void scheduleLowMemory() {
814 queueOrSendMessage(H.LOW_MEMORY, null);
817 public void scheduleActivityConfigurationChanged(IBinder token) {
818 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
821 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
823 ProfilerControlData pcd = new ProfilerControlData();
826 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
829 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
830 DumpHeapData dhd = new DumpHeapData();
833 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
836 public void setSchedulingGroup(int group) {
837 // Note: do this immediately, since going into the foreground
838 // should happen regardless of what pending work we have to do
839 // and the activity manager will wait for us to report back that
840 // we are done before sending us to the background.
842 Process.setProcessGroup(Process.myPid(), group);
843 } catch (Exception e) {
844 Slog.w(TAG, "Failed setting process group to " + group, e);
848 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
849 Debug.getMemoryInfo(outInfo);
852 public void dispatchPackageBroadcast(int cmd, String[] packages) {
853 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
856 public void scheduleCrash(String msg) {
857 queueOrSendMessage(H.SCHEDULE_CRASH, msg);
860 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
861 String prefix, String[] args) {
862 DumpComponentInfo data = new DumpComponentInfo();
864 data.fd = ParcelFileDescriptor.dup(fd);
865 data.token = activitytoken;
866 data.prefix = prefix;
868 queueOrSendMessage(H.DUMP_ACTIVITY, data);
869 } catch (IOException e) {
870 Slog.w(TAG, "dumpActivity failed", e);
874 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
876 DumpComponentInfo data = new DumpComponentInfo();
878 data.fd = ParcelFileDescriptor.dup(fd);
879 data.token = providertoken;
881 queueOrSendMessage(H.DUMP_PROVIDER, data);
882 } catch (IOException e) {
883 Slog.w(TAG, "dumpProvider failed", e);
888 public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
889 boolean all, String[] args) {
890 FileOutputStream fout = new FileOutputStream(fd);
891 PrintWriter pw = new PrintWriter(fout);
893 return dumpMemInfo(pw, checkin, all);
899 private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
900 long nativeMax = Debug.getNativeHeapSize() / 1024;
901 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
902 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
904 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
905 Debug.getMemoryInfo(memInfo);
911 Runtime runtime = Runtime.getRuntime();
913 long dalvikMax = runtime.totalMemory() / 1024;
914 long dalvikFree = runtime.freeMemory() / 1024;
915 long dalvikAllocated = dalvikMax - dalvikFree;
916 long viewInstanceCount = ViewDebug.getViewInstanceCount();
917 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
918 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
919 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
920 int globalAssetCount = AssetManager.getGlobalAssetCount();
921 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
922 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
923 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
924 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
925 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
926 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
928 // For checkin, we print one long comma-separated list of values
930 // NOTE: if you change anything significant below, also consider changing
931 // ACTIVITY_THREAD_CHECKIN_VERSION.
932 String processName = (mBoundApplication != null)
933 ? mBoundApplication.processName : "unknown";
936 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
937 pw.print(Process.myPid()); pw.print(',');
938 pw.print(processName); pw.print(',');
941 pw.print(nativeMax); pw.print(',');
942 pw.print(dalvikMax); pw.print(',');
944 pw.print(nativeMax + dalvikMax); pw.print(',');
946 // Heap info - allocated
947 pw.print(nativeAllocated); pw.print(',');
948 pw.print(dalvikAllocated); pw.print(',');
950 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
953 pw.print(nativeFree); pw.print(',');
954 pw.print(dalvikFree); pw.print(',');
956 pw.print(nativeFree + dalvikFree); pw.print(',');
958 // Heap info - proportional set size
959 pw.print(memInfo.nativePss); pw.print(',');
960 pw.print(memInfo.dalvikPss); pw.print(',');
961 pw.print(memInfo.otherPss); pw.print(',');
962 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
964 // Heap info - shared
965 pw.print(memInfo.nativeSharedDirty); pw.print(',');
966 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
967 pw.print(memInfo.otherSharedDirty); pw.print(',');
968 pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
969 + memInfo.otherSharedDirty); pw.print(',');
971 // Heap info - private
972 pw.print(memInfo.nativePrivateDirty); pw.print(',');
973 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
974 pw.print(memInfo.otherPrivateDirty); pw.print(',');
975 pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
976 + memInfo.otherPrivateDirty); pw.print(',');
979 pw.print(viewInstanceCount); pw.print(',');
980 pw.print(viewRootInstanceCount); pw.print(',');
981 pw.print(appContextInstanceCount); pw.print(',');
982 pw.print(activityInstanceCount); pw.print(',');
984 pw.print(globalAssetCount); pw.print(',');
985 pw.print(globalAssetManagerCount); pw.print(',');
986 pw.print(binderLocalObjectCount); pw.print(',');
987 pw.print(binderProxyObjectCount); pw.print(',');
989 pw.print(binderDeathObjectCount); pw.print(',');
990 pw.print(openSslSocketCount); pw.print(',');
993 pw.print(stats.memoryUsed / 1024); pw.print(',');
994 pw.print(stats.memoryUsed / 1024); pw.print(',');
995 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
996 pw.print(stats.largestMemAlloc / 1024);
997 for (int i = 0; i < stats.dbStats.size(); i++) {
998 DbStats dbStats = stats.dbStats.get(i);
999 pw.print(','); pw.print(dbStats.dbName);
1000 pw.print(','); pw.print(dbStats.pageSize);
1001 pw.print(','); pw.print(dbStats.dbSize);
1002 pw.print(','); pw.print(dbStats.lookaside);
1003 pw.print(','); pw.print(dbStats.cache);
1004 pw.print(','); pw.print(dbStats.cache);
1011 // otherwise, show human-readable format
1012 printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
1013 printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
1014 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
1016 printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
1017 memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
1018 printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
1019 memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
1021 int otherPss = memInfo.otherPss;
1022 int otherSharedDirty = memInfo.otherSharedDirty;
1023 int otherPrivateDirty = memInfo.otherPrivateDirty;
1025 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1026 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
1027 memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
1028 memInfo.getOtherPrivateDirty(i), "", "", "");
1029 otherPss -= memInfo.getOtherPss(i);
1030 otherSharedDirty -= memInfo.getOtherSharedDirty(i);
1031 otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
1034 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
1035 otherPrivateDirty, "", "", "");
1036 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
1037 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
1038 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
1039 nativeFree+dalvikFree);
1042 pw.println(" Objects");
1043 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
1044 viewRootInstanceCount);
1046 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1047 "Activities:", activityInstanceCount);
1049 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1050 "AssetManagers:", globalAssetManagerCount);
1052 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1053 "Proxy Binders:", binderProxyObjectCount);
1054 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
1056 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
1061 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1062 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1063 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
1065 int N = stats.dbStats.size();
1067 pw.println(" DATABASES");
1068 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1070 for (int i = 0; i < N; i++) {
1071 DbStats dbStats = stats.dbStats.get(i);
1072 printRow(pw, DB_INFO_FORMAT,
1073 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1074 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1075 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1076 dbStats.cache, dbStats.dbName);
1081 String assetAlloc = AssetManager.getAssetAllocations();
1082 if (assetAlloc != null) {
1084 pw.println(" Asset Allocations");
1085 pw.print(assetAlloc);
1092 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1093 dumpGraphicsInfo(fd);
1094 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
1098 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1099 PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
1100 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1101 SQLiteDebug.dump(printer, args);
1106 public void unstableProviderDied(IBinder provider) {
1107 queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1110 private void printRow(PrintWriter pw, String format, Object...objs) {
1111 pw.println(String.format(format, objs));
1114 public void setCoreSettings(Bundle coreSettings) {
1115 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
1118 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1119 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1122 queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1125 public void scheduleTrimMemory(int level) {
1126 queueOrSendMessage(H.TRIM_MEMORY, null, level);
1131 private class H extends Handler {
1132 public static final int LAUNCH_ACTIVITY = 100;
1133 public static final int PAUSE_ACTIVITY = 101;
1134 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1135 public static final int STOP_ACTIVITY_SHOW = 103;
1136 public static final int STOP_ACTIVITY_HIDE = 104;
1137 public static final int SHOW_WINDOW = 105;
1138 public static final int HIDE_WINDOW = 106;
1139 public static final int RESUME_ACTIVITY = 107;
1140 public static final int SEND_RESULT = 108;
1141 public static final int DESTROY_ACTIVITY = 109;
1142 public static final int BIND_APPLICATION = 110;
1143 public static final int EXIT_APPLICATION = 111;
1144 public static final int NEW_INTENT = 112;
1145 public static final int RECEIVER = 113;
1146 public static final int CREATE_SERVICE = 114;
1147 public static final int SERVICE_ARGS = 115;
1148 public static final int STOP_SERVICE = 116;
1149 public static final int REQUEST_THUMBNAIL = 117;
1150 public static final int CONFIGURATION_CHANGED = 118;
1151 public static final int CLEAN_UP_CONTEXT = 119;
1152 public static final int GC_WHEN_IDLE = 120;
1153 public static final int BIND_SERVICE = 121;
1154 public static final int UNBIND_SERVICE = 122;
1155 public static final int DUMP_SERVICE = 123;
1156 public static final int LOW_MEMORY = 124;
1157 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1158 public static final int RELAUNCH_ACTIVITY = 126;
1159 public static final int PROFILER_CONTROL = 127;
1160 public static final int CREATE_BACKUP_AGENT = 128;
1161 public static final int DESTROY_BACKUP_AGENT = 129;
1162 public static final int SUICIDE = 130;
1163 public static final int REMOVE_PROVIDER = 131;
1164 public static final int ENABLE_JIT = 132;
1165 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
1166 public static final int SCHEDULE_CRASH = 134;
1167 public static final int DUMP_HEAP = 135;
1168 public static final int DUMP_ACTIVITY = 136;
1169 public static final int SLEEPING = 137;
1170 public static final int SET_CORE_SETTINGS = 138;
1171 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
1172 public static final int TRIM_MEMORY = 140;
1173 public static final int DUMP_PROVIDER = 141;
1174 public static final int UNSTABLE_PROVIDER_DIED = 142;
1175 String codeToString(int code) {
1176 if (DEBUG_MESSAGES) {
1178 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1179 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1180 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1181 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1182 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1183 case SHOW_WINDOW: return "SHOW_WINDOW";
1184 case HIDE_WINDOW: return "HIDE_WINDOW";
1185 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1186 case SEND_RESULT: return "SEND_RESULT";
1187 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1188 case BIND_APPLICATION: return "BIND_APPLICATION";
1189 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1190 case NEW_INTENT: return "NEW_INTENT";
1191 case RECEIVER: return "RECEIVER";
1192 case CREATE_SERVICE: return "CREATE_SERVICE";
1193 case SERVICE_ARGS: return "SERVICE_ARGS";
1194 case STOP_SERVICE: return "STOP_SERVICE";
1195 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
1196 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1197 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1198 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1199 case BIND_SERVICE: return "BIND_SERVICE";
1200 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1201 case DUMP_SERVICE: return "DUMP_SERVICE";
1202 case LOW_MEMORY: return "LOW_MEMORY";
1203 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1204 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1205 case PROFILER_CONTROL: return "PROFILER_CONTROL";
1206 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1207 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1208 case SUICIDE: return "SUICIDE";
1209 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1210 case ENABLE_JIT: return "ENABLE_JIT";
1211 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1212 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1213 case DUMP_HEAP: return "DUMP_HEAP";
1214 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1215 case SLEEPING: return "SLEEPING";
1216 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1217 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1218 case TRIM_MEMORY: return "TRIM_MEMORY";
1219 case DUMP_PROVIDER: return "DUMP_PROVIDER";
1220 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1223 return Integer.toString(code);
1225 public void handleMessage(Message msg) {
1226 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1228 case LAUNCH_ACTIVITY: {
1229 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1230 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1232 r.packageInfo = getPackageInfoNoCheck(
1233 r.activityInfo.applicationInfo, r.compatInfo);
1234 handleLaunchActivity(r, null);
1235 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1237 case RELAUNCH_ACTIVITY: {
1238 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1239 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1240 handleRelaunchActivity(r);
1241 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1243 case PAUSE_ACTIVITY:
1244 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1245 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
1247 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1249 case PAUSE_ACTIVITY_FINISHING:
1250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1251 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
1252 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1254 case STOP_ACTIVITY_SHOW:
1255 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1256 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
1257 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1259 case STOP_ACTIVITY_HIDE:
1260 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1261 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
1262 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1265 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1266 handleWindowVisibility((IBinder)msg.obj, true);
1267 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1270 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1271 handleWindowVisibility((IBinder)msg.obj, false);
1272 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1274 case RESUME_ACTIVITY:
1275 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1276 handleResumeActivity((IBinder)msg.obj, true,
1277 msg.arg1 != 0, true);
1278 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1281 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1282 handleSendResult((ResultData)msg.obj);
1283 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1285 case DESTROY_ACTIVITY:
1286 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1287 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1289 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1291 case BIND_APPLICATION:
1292 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1293 AppBindData data = (AppBindData)msg.obj;
1294 handleBindApplication(data);
1295 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1297 case EXIT_APPLICATION:
1298 if (mInitialApplication != null) {
1299 mInitialApplication.onTerminate();
1301 Looper.myLooper().quit();
1304 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1305 handleNewIntent((NewIntentData)msg.obj);
1306 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1309 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1310 handleReceiver((ReceiverData)msg.obj);
1312 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1314 case CREATE_SERVICE:
1315 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
1316 handleCreateService((CreateServiceData)msg.obj);
1317 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1320 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1321 handleBindService((BindServiceData)msg.obj);
1322 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1324 case UNBIND_SERVICE:
1325 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1326 handleUnbindService((BindServiceData)msg.obj);
1327 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1330 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
1331 handleServiceArgs((ServiceArgsData)msg.obj);
1332 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1335 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1336 handleStopService((IBinder)msg.obj);
1338 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1340 case REQUEST_THUMBNAIL:
1341 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
1342 handleRequestThumbnail((IBinder)msg.obj);
1343 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1345 case CONFIGURATION_CHANGED:
1346 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1347 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1348 handleConfigurationChanged((Configuration)msg.obj, null);
1349 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1351 case CLEAN_UP_CONTEXT:
1352 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1353 cci.context.performFinalCleanup(cci.who, cci.what);
1359 handleDumpService((DumpComponentInfo)msg.obj);
1362 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1364 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1366 case ACTIVITY_CONFIGURATION_CHANGED:
1367 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1368 handleActivityConfigurationChanged((IBinder)msg.obj);
1369 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1371 case PROFILER_CONTROL:
1372 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
1374 case CREATE_BACKUP_AGENT:
1375 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1376 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1377 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1379 case DESTROY_BACKUP_AGENT:
1380 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1381 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1382 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1385 Process.killProcess(Process.myPid());
1387 case REMOVE_PROVIDER:
1388 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1389 completeRemoveProvider((ProviderRefCount)msg.obj);
1390 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1395 case DISPATCH_PACKAGE_BROADCAST:
1396 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1397 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1398 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1400 case SCHEDULE_CRASH:
1401 throw new RemoteServiceException((String)msg.obj);
1403 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1406 handleDumpActivity((DumpComponentInfo)msg.obj);
1409 handleDumpProvider((DumpComponentInfo)msg.obj);
1412 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1413 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1414 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1416 case SET_CORE_SETTINGS:
1417 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1418 handleSetCoreSettings((Bundle) msg.obj);
1419 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1421 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1422 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1425 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1426 handleTrimMemory(msg.arg1);
1427 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1429 case UNSTABLE_PROVIDER_DIED:
1430 handleUnstableProviderDied((IBinder)msg.obj, false);
1433 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1436 private void maybeSnapshot() {
1437 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
1438 // convert the *private* ActivityThread.PackageInfo to *public* known
1439 // android.content.pm.PackageInfo
1440 String packageName = mBoundApplication.info.mPackageName;
1441 android.content.pm.PackageInfo packageInfo = null;
1443 Context context = getSystemContext();
1444 if(context == null) {
1445 Log.e(TAG, "cannot get a valid context");
1448 PackageManager pm = context.getPackageManager();
1450 Log.e(TAG, "cannot get a valid PackageManager");
1453 packageInfo = pm.getPackageInfo(
1454 packageName, PackageManager.GET_ACTIVITIES);
1455 } catch (NameNotFoundException e) {
1456 Log.e(TAG, "cannot get package info for " + packageName, e);
1458 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1463 private class Idler implements MessageQueue.IdleHandler {
1464 public final boolean queueIdle() {
1465 ActivityClientRecord a = mNewActivities;
1466 boolean stopProfiling = false;
1467 if (mBoundApplication != null && mProfiler.profileFd != null
1468 && mProfiler.autoStopProfiler) {
1469 stopProfiling = true;
1472 mNewActivities = null;
1473 IActivityManager am = ActivityManagerNative.getDefault();
1474 ActivityClientRecord prev;
1476 if (localLOGV) Slog.v(
1477 TAG, "Reporting idle of " + a +
1479 (a.activity != null && a.activity.mFinished));
1480 if (a.activity != null && !a.activity.mFinished) {
1482 am.activityIdle(a.token, a.createdConfig, stopProfiling);
1483 a.createdConfig = null;
1484 } catch (RemoteException ex) {
1490 prev.nextIdle = null;
1491 } while (a != null);
1493 if (stopProfiling) {
1494 mProfiler.stopProfiling();
1501 final class GcIdler implements MessageQueue.IdleHandler {
1502 public final boolean queueIdle() {
1508 private static class ResourcesKey {
1509 final private String mResDir;
1510 final private int mDisplayId;
1511 final private Configuration mOverrideConfiguration;
1512 final private float mScale;
1513 final private int mHash;
1515 ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
1517 mDisplayId = displayId;
1518 if (overrideConfiguration != null) {
1519 if (Configuration.EMPTY.equals(overrideConfiguration)) {
1520 overrideConfiguration = null;
1523 mOverrideConfiguration = overrideConfiguration;
1526 hash = 31 * hash + mResDir.hashCode();
1527 hash = 31 * hash + mDisplayId;
1528 hash = 31 * hash + (mOverrideConfiguration != null
1529 ? mOverrideConfiguration.hashCode() : 0);
1530 hash = 31 * hash + Float.floatToIntBits(mScale);
1535 public int hashCode() {
1540 public boolean equals(Object obj) {
1541 if (!(obj instanceof ResourcesKey)) {
1544 ResourcesKey peer = (ResourcesKey) obj;
1545 if (!mResDir.equals(peer.mResDir)) {
1548 if (mDisplayId != peer.mDisplayId) {
1551 if (mOverrideConfiguration != peer.mOverrideConfiguration) {
1552 if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
1555 if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
1559 if (mScale != peer.mScale) {
1566 public static ActivityThread currentActivityThread() {
1567 return sThreadLocal.get();
1570 public static String currentPackageName() {
1571 ActivityThread am = currentActivityThread();
1572 return (am != null && am.mBoundApplication != null)
1573 ? am.mBoundApplication.processName : null;
1576 public static Application currentApplication() {
1577 ActivityThread am = currentActivityThread();
1578 return am != null ? am.mInitialApplication : null;
1581 public static IPackageManager getPackageManager() {
1582 if (sPackageManager != null) {
1583 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1584 return sPackageManager;
1586 IBinder b = ServiceManager.getService("package");
1587 //Slog.v("PackageManager", "default service binder = " + b);
1588 sPackageManager = IPackageManager.Stub.asInterface(b);
1589 //Slog.v("PackageManager", "default service = " + sPackageManager);
1590 return sPackageManager;
1593 private void flushDisplayMetricsLocked() {
1594 mDefaultDisplayMetrics.clear();
1597 DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
1598 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1599 DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
1603 dm = new DisplayMetrics();
1605 DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
1606 if (displayManager == null) {
1607 // may be null early in system startup
1612 if (isDefaultDisplay) {
1613 mDefaultDisplayMetrics.put(ci, dm);
1616 CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
1618 Display d = displayManager.getCompatibleDisplay(displayId, cih);
1622 // Display no longer exists
1623 // FIXME: This would not be a problem if we kept the Display object around
1624 // instead of using the raw display id everywhere. The Display object caches
1625 // its information even after the display has been removed.
1628 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1629 // + metrics.heightPixels + " den=" + metrics.density
1630 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
1634 private Configuration mMainThreadConfig = new Configuration();
1635 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1636 CompatibilityInfo compat) {
1637 if (config == null) {
1640 if (compat != null && !compat.supportsScreen()) {
1641 mMainThreadConfig.setTo(config);
1642 config = mMainThreadConfig;
1643 compat.applyToConfiguration(displayDensity, config);
1649 * Creates the top level Resources for applications with the given compatibility info.
1651 * @param resDir the resource directory.
1652 * @param compInfo the compability info. It will use the default compatibility info when it's
1655 Resources getTopLevelResources(String resDir,
1656 int displayId, Configuration overrideConfiguration,
1657 CompatibilityInfo compInfo) {
1658 ResourcesKey key = new ResourcesKey(resDir,
1659 displayId, overrideConfiguration,
1660 compInfo.applicationScale);
1662 synchronized (mPackages) {
1663 // Resources is app scale dependent.
1665 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1666 + compInfo.applicationScale);
1668 WeakReference<Resources> wr = mActiveResources.get(key);
1669 r = wr != null ? wr.get() : null;
1670 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1671 if (r != null && r.getAssets().isUpToDate()) {
1673 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1674 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1681 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1682 // + r + " " + resDir);
1685 AssetManager assets = new AssetManager();
1686 if (assets.addAssetPath(resDir) == 0) {
1690 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
1691 DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
1692 Configuration config;
1693 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1694 if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
1695 config = new Configuration(getConfiguration());
1696 if (!isDefaultDisplay) {
1697 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
1699 if (key.mOverrideConfiguration != null) {
1700 config.updateFrom(key.mOverrideConfiguration);
1703 config = getConfiguration();
1705 r = new Resources(assets, dm, config, compInfo);
1707 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1708 + r.getConfiguration() + " appScale="
1709 + r.getCompatibilityInfo().applicationScale);
1712 synchronized (mPackages) {
1713 WeakReference<Resources> wr = mActiveResources.get(key);
1714 Resources existing = wr != null ? wr.get() : null;
1715 if (existing != null && existing.getAssets().isUpToDate()) {
1716 // Someone else already created the resources while we were
1717 // unlocked; go ahead and use theirs.
1718 r.getAssets().close();
1722 // XXX need to remove entries when weak references go away
1723 mActiveResources.put(key, new WeakReference<Resources>(r));
1729 * Creates the top level resources for the given package.
1731 Resources getTopLevelResources(String resDir,
1732 int displayId, Configuration overrideConfiguration,
1733 LoadedApk pkgInfo) {
1734 return getTopLevelResources(resDir, displayId, overrideConfiguration,
1735 pkgInfo.mCompatibilityInfo.get());
1738 final Handler getHandler() {
1742 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1744 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1747 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1748 int flags, int userId) {
1749 synchronized (mPackages) {
1750 WeakReference<LoadedApk> ref;
1751 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1752 ref = mPackages.get(packageName);
1754 ref = mResourcePackages.get(packageName);
1756 LoadedApk packageInfo = ref != null ? ref.get() : null;
1757 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
1758 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1759 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
1760 if (packageInfo != null && (packageInfo.mResources == null
1761 || packageInfo.mResources.getAssets().isUpToDate())) {
1762 if (packageInfo.isSecurityViolation()
1763 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1764 throw new SecurityException(
1765 "Requesting code from " + packageName
1766 + " to be run in process "
1767 + mBoundApplication.processName
1768 + "/" + mBoundApplication.appInfo.uid);
1774 ApplicationInfo ai = null;
1776 ai = getPackageManager().getApplicationInfo(packageName,
1777 PackageManager.GET_SHARED_LIBRARY_FILES, userId);
1778 } catch (RemoteException e) {
1783 return getPackageInfo(ai, compatInfo, flags);
1789 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1791 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1792 boolean securityViolation = includeCode && ai.uid != 0
1793 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1794 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
1796 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1797 |Context.CONTEXT_IGNORE_SECURITY))
1798 == Context.CONTEXT_INCLUDE_CODE) {
1799 if (securityViolation) {
1800 String msg = "Requesting code from " + ai.packageName
1801 + " (with uid " + ai.uid + ")";
1802 if (mBoundApplication != null) {
1803 msg = msg + " to be run in process "
1804 + mBoundApplication.processName + " (with uid "
1805 + mBoundApplication.appInfo.uid + ")";
1807 throw new SecurityException(msg);
1810 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
1813 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1814 CompatibilityInfo compatInfo) {
1815 return getPackageInfo(ai, compatInfo, null, false, true);
1818 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1819 synchronized (mPackages) {
1820 WeakReference<LoadedApk> ref;
1822 ref = mPackages.get(packageName);
1824 ref = mResourcePackages.get(packageName);
1826 return ref != null ? ref.get() : null;
1830 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
1831 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1832 synchronized (mPackages) {
1833 WeakReference<LoadedApk> ref;
1835 ref = mPackages.get(aInfo.packageName);
1837 ref = mResourcePackages.get(aInfo.packageName);
1839 LoadedApk packageInfo = ref != null ? ref.get() : null;
1840 if (packageInfo == null || (packageInfo.mResources != null
1841 && !packageInfo.mResources.getAssets().isUpToDate())) {
1842 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
1843 : "Loading resource-only package ") + aInfo.packageName
1844 + " (in " + (mBoundApplication != null
1845 ? mBoundApplication.processName : null)
1848 new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
1849 securityViolation, includeCode &&
1850 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1852 mPackages.put(aInfo.packageName,
1853 new WeakReference<LoadedApk>(packageInfo));
1855 mResourcePackages.put(aInfo.packageName,
1856 new WeakReference<LoadedApk>(packageInfo));
1866 public ApplicationThread getApplicationThread()
1871 public Instrumentation getInstrumentation()
1873 return mInstrumentation;
1876 public Configuration getConfiguration() {
1877 return mResConfiguration;
1880 public boolean isProfiling() {
1881 return mProfiler != null && mProfiler.profileFile != null
1882 && mProfiler.profileFd == null;
1885 public String getProfileFilePath() {
1886 return mProfiler.profileFile;
1889 public Looper getLooper() {
1893 public Application getApplication() {
1894 return mInitialApplication;
1897 public String getProcessName() {
1898 return mBoundApplication.processName;
1901 public ContextImpl getSystemContext() {
1902 synchronized (this) {
1903 if (mSystemContext == null) {
1904 ContextImpl context =
1905 ContextImpl.createSystemContext(this);
1906 LoadedApk info = new LoadedApk(this, "android", context, null,
1907 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
1908 context.init(info, null, this);
1909 context.getResources().updateConfiguration(
1910 getConfiguration(), getDisplayMetricsLocked(
1911 Display.DEFAULT_DISPLAY,
1912 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
1913 mSystemContext = context;
1914 //Slog.i(TAG, "Created system resources " + context.getResources()
1915 // + ": " + context.getResources().getConfiguration());
1918 return mSystemContext;
1921 public void installSystemApplicationInfo(ApplicationInfo info) {
1922 synchronized (this) {
1923 ContextImpl context = getSystemContext();
1924 context.init(new LoadedApk(this, "android", context, info,
1925 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
1927 // give ourselves a default profiler
1928 mProfiler = new Profiler();
1932 void ensureJitEnabled() {
1935 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1939 void scheduleGcIdler() {
1940 if (!mGcIdlerScheduled) {
1941 mGcIdlerScheduled = true;
1942 Looper.myQueue().addIdleHandler(mGcIdler);
1944 mH.removeMessages(H.GC_WHEN_IDLE);
1947 void unscheduleGcIdler() {
1948 if (mGcIdlerScheduled) {
1949 mGcIdlerScheduled = false;
1950 Looper.myQueue().removeIdleHandler(mGcIdler);
1952 mH.removeMessages(H.GC_WHEN_IDLE);
1955 void doGcIfNeeded() {
1956 mGcIdlerScheduled = false;
1957 final long now = SystemClock.uptimeMillis();
1958 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
1959 // + "m now=" + now);
1960 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
1961 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
1962 BinderInternal.forceGc("bg");
1966 public void registerOnActivityPausedListener(Activity activity,
1967 OnActivityPausedListener listener) {
1968 synchronized (mOnPauseListeners) {
1969 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1971 list = new ArrayList<OnActivityPausedListener>();
1972 mOnPauseListeners.put(activity, list);
1978 public void unregisterOnActivityPausedListener(Activity activity,
1979 OnActivityPausedListener listener) {
1980 synchronized (mOnPauseListeners) {
1981 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1983 list.remove(listener);
1988 public final ActivityInfo resolveActivityInfo(Intent intent) {
1989 ActivityInfo aInfo = intent.resolveActivityInfo(
1990 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
1991 if (aInfo == null) {
1992 // Throw an exception.
1993 Instrumentation.checkStartActivityResult(
1994 ActivityManager.START_CLASS_NOT_FOUND, intent);
1999 public final Activity startActivityNow(Activity parent, String id,
2000 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2001 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2002 ActivityClientRecord r = new ActivityClientRecord();
2009 r.activityInfo = activityInfo;
2010 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2012 ComponentName compname = intent.getComponent();
2014 if (compname != null) {
2015 name = compname.toShortString();
2017 name = "(Intent " + intent + ").getComponent() returned null";
2019 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2021 + ", token=" + token);
2023 return performLaunchActivity(r, null);
2026 public final Activity getActivity(IBinder token) {
2027 return mActivities.get(token).activity;
2030 public final void sendActivityResult(
2031 IBinder token, String id, int requestCode,
2032 int resultCode, Intent data) {
2033 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2034 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2035 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2036 list.add(new ResultInfo(id, requestCode, resultCode, data));
2037 mAppThread.scheduleSendResult(token, list);
2040 // if the thread hasn't started yet, we don't have the handler, so just
2041 // save the messages until we're ready.
2042 private void queueOrSendMessage(int what, Object obj) {
2043 queueOrSendMessage(what, obj, 0, 0);
2046 private void queueOrSendMessage(int what, Object obj, int arg1) {
2047 queueOrSendMessage(what, obj, arg1, 0);
2050 private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
2051 synchronized (this) {
2052 if (DEBUG_MESSAGES) Slog.v(
2053 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2054 + ": " + arg1 + " / " + obj);
2055 Message msg = Message.obtain();
2060 mH.sendMessage(msg);
2064 final void scheduleContextCleanup(ContextImpl context, String who,
2066 ContextCleanupInfo cci = new ContextCleanupInfo();
2067 cci.context = context;
2070 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
2073 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2074 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2076 ActivityInfo aInfo = r.activityInfo;
2077 if (r.packageInfo == null) {
2078 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2079 Context.CONTEXT_INCLUDE_CODE);
2082 ComponentName component = r.intent.getComponent();
2083 if (component == null) {
2084 component = r.intent.resolveActivity(
2085 mInitialApplication.getPackageManager());
2086 r.intent.setComponent(component);
2089 if (r.activityInfo.targetActivity != null) {
2090 component = new ComponentName(r.activityInfo.packageName,
2091 r.activityInfo.targetActivity);
2094 Activity activity = null;
2096 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2097 activity = mInstrumentation.newActivity(
2098 cl, component.getClassName(), r.intent);
2099 StrictMode.incrementExpectedActivityCount(activity.getClass());
2100 r.intent.setExtrasClassLoader(cl);
2101 if (r.state != null) {
2102 r.state.setClassLoader(cl);
2104 } catch (Exception e) {
2105 if (!mInstrumentation.onException(activity, e)) {
2106 throw new RuntimeException(
2107 "Unable to instantiate activity " + component
2108 + ": " + e.toString(), e);
2113 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2115 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2116 if (localLOGV) Slog.v(
2117 TAG, r + ": app=" + app
2118 + ", appName=" + app.getPackageName()
2119 + ", pkg=" + r.packageInfo.getPackageName()
2120 + ", comp=" + r.intent.getComponent().toShortString()
2121 + ", dir=" + r.packageInfo.getAppDir());
2123 if (activity != null) {
2124 Context appContext = createBaseContextForActivity(r, activity);
2125 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2126 Configuration config = new Configuration(mCompatConfiguration);
2127 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2128 + r.activityInfo.name + " with config " + config);
2129 activity.attach(appContext, this, getInstrumentation(), r.token,
2130 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2131 r.embeddedID, r.lastNonConfigurationInstances, config);
2133 if (customIntent != null) {
2134 activity.mIntent = customIntent;
2136 r.lastNonConfigurationInstances = null;
2137 activity.mStartedActivity = false;
2138 int theme = r.activityInfo.getThemeResource();
2140 activity.setTheme(theme);
2143 activity.mCalled = false;
2144 mInstrumentation.callActivityOnCreate(activity, r.state);
2145 if (!activity.mCalled) {
2146 throw new SuperNotCalledException(
2147 "Activity " + r.intent.getComponent().toShortString() +
2148 " did not call through to super.onCreate()");
2150 r.activity = activity;
2152 if (!r.activity.mFinished) {
2153 activity.performStart();
2156 if (!r.activity.mFinished) {
2157 if (r.state != null) {
2158 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2161 if (!r.activity.mFinished) {
2162 activity.mCalled = false;
2163 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2164 if (!activity.mCalled) {
2165 throw new SuperNotCalledException(
2166 "Activity " + r.intent.getComponent().toShortString() +
2167 " did not call through to super.onPostCreate()");
2173 mActivities.put(r.token, r);
2175 } catch (SuperNotCalledException e) {
2178 } catch (Exception e) {
2179 if (!mInstrumentation.onException(activity, e)) {
2180 throw new RuntimeException(
2181 "Unable to start activity " + component
2182 + ": " + e.toString(), e);
2189 private Context createBaseContextForActivity(ActivityClientRecord r,
2190 final Activity activity) {
2191 ContextImpl appContext = new ContextImpl();
2192 appContext.init(r.packageInfo, r.token, this);
2193 appContext.setOuterContext(activity);
2195 // For debugging purposes, if the activity's package name contains the value of
2196 // the "debug.use-second-display" system property as a substring, then show
2197 // its content on a secondary display if there is one.
2198 Context baseContext = appContext;
2199 String pkgName = SystemProperties.get("debug.second-display.pkg");
2200 if (pkgName != null && !pkgName.isEmpty()
2201 && r.packageInfo.mPackageName.contains(pkgName)) {
2202 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2203 for (int displayId : dm.getDisplayIds()) {
2204 if (displayId != Display.DEFAULT_DISPLAY) {
2205 Display display = dm.getRealDisplay(displayId);
2206 baseContext = appContext.createDisplayContext(display);
2214 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2215 // If we are getting ready to gc after going to the background, well
2216 // we are back active so skip it.
2217 unscheduleGcIdler();
2219 if (r.profileFd != null) {
2220 mProfiler.setProfiler(r.profileFile, r.profileFd);
2221 mProfiler.startProfiling();
2222 mProfiler.autoStopProfiler = r.autoStopProfiler;
2225 // Make sure we are running with the most recent config.
2226 handleConfigurationChanged(null, null);
2228 if (localLOGV) Slog.v(
2229 TAG, "Handling launch of " + r);
2230 Activity a = performLaunchActivity(r, customIntent);
2233 r.createdConfig = new Configuration(mConfiguration);
2234 Bundle oldState = r.state;
2235 handleResumeActivity(r.token, false, r.isForward,
2236 !r.activity.mFinished && !r.startsNotResumed);
2238 if (!r.activity.mFinished && r.startsNotResumed) {
2239 // The activity manager actually wants this one to start out
2240 // paused, because it needs to be visible but isn't in the
2241 // foreground. We accomplish this by going through the
2242 // normal startup (because activities expect to go through
2243 // onResume() the first time they run, before their window
2244 // is displayed), and then pausing it. However, in this case
2245 // we do -not- need to do the full pause cycle (of freezing
2246 // and such) because the activity manager assumes it can just
2247 // retain the current state it has.
2249 r.activity.mCalled = false;
2250 mInstrumentation.callActivityOnPause(r.activity);
2251 // We need to keep around the original state, in case
2252 // we need to be created again. But we only do this
2253 // for pre-Honeycomb apps, which always save their state
2254 // when pausing, so we can not have them save their state
2255 // when restarting from a paused state. For HC and later,
2256 // we want to (and can) let the state be saved as the normal
2257 // part of stopping the activity.
2258 if (r.isPreHoneycomb()) {
2261 if (!r.activity.mCalled) {
2262 throw new SuperNotCalledException(
2263 "Activity " + r.intent.getComponent().toShortString() +
2264 " did not call through to super.onPause()");
2267 } catch (SuperNotCalledException e) {
2270 } catch (Exception e) {
2271 if (!mInstrumentation.onException(r.activity, e)) {
2272 throw new RuntimeException(
2273 "Unable to pause activity "
2274 + r.intent.getComponent().toShortString()
2275 + ": " + e.toString(), e);
2281 // If there was an error, for any reason, tell the activity
2282 // manager to stop us.
2284 ActivityManagerNative.getDefault()
2285 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
2286 } catch (RemoteException ex) {
2292 private void deliverNewIntents(ActivityClientRecord r,
2293 List<Intent> intents) {
2294 final int N = intents.size();
2295 for (int i=0; i<N; i++) {
2296 Intent intent = intents.get(i);
2297 intent.setExtrasClassLoader(r.activity.getClassLoader());
2298 r.activity.mFragments.noteStateNotSaved();
2299 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2303 public final void performNewIntents(IBinder token,
2304 List<Intent> intents) {
2305 ActivityClientRecord r = mActivities.get(token);
2307 final boolean resumed = !r.paused;
2309 r.activity.mTemporaryPause = true;
2310 mInstrumentation.callActivityOnPause(r.activity);
2312 deliverNewIntents(r, intents);
2314 r.activity.performResume();
2315 r.activity.mTemporaryPause = false;
2320 private void handleNewIntent(NewIntentData data) {
2321 performNewIntents(data.token, data.intents);
2324 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2327 * Return the Intent that's currently being handled by a
2328 * BroadcastReceiver on this thread, or null if none.
2331 public static Intent getIntentBeingBroadcast() {
2332 return sCurrentBroadcastIntent.get();
2335 private void handleReceiver(ReceiverData data) {
2336 // If we are getting ready to gc after going to the background, well
2337 // we are back active so skip it.
2338 unscheduleGcIdler();
2340 String component = data.intent.getComponent().getClassName();
2342 LoadedApk packageInfo = getPackageInfoNoCheck(
2343 data.info.applicationInfo, data.compatInfo);
2345 IActivityManager mgr = ActivityManagerNative.getDefault();
2347 BroadcastReceiver receiver;
2349 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2350 data.intent.setExtrasClassLoader(cl);
2351 data.setExtrasClassLoader(cl);
2352 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2353 } catch (Exception e) {
2354 if (DEBUG_BROADCAST) Slog.i(TAG,
2355 "Finishing failed broadcast to " + data.intent.getComponent());
2356 data.sendFinished(mgr);
2357 throw new RuntimeException(
2358 "Unable to instantiate receiver " + component
2359 + ": " + e.toString(), e);
2363 Application app = packageInfo.makeApplication(false, mInstrumentation);
2365 if (localLOGV) Slog.v(
2366 TAG, "Performing receive of " + data.intent
2368 + ", appName=" + app.getPackageName()
2369 + ", pkg=" + packageInfo.getPackageName()
2370 + ", comp=" + data.intent.getComponent().toShortString()
2371 + ", dir=" + packageInfo.getAppDir());
2373 ContextImpl context = (ContextImpl)app.getBaseContext();
2374 sCurrentBroadcastIntent.set(data.intent);
2375 receiver.setPendingResult(data);
2376 receiver.onReceive(context.getReceiverRestrictedContext(),
2378 } catch (Exception e) {
2379 if (DEBUG_BROADCAST) Slog.i(TAG,
2380 "Finishing failed broadcast to " + data.intent.getComponent());
2381 data.sendFinished(mgr);
2382 if (!mInstrumentation.onException(receiver, e)) {
2383 throw new RuntimeException(
2384 "Unable to start receiver " + component
2385 + ": " + e.toString(), e);
2388 sCurrentBroadcastIntent.set(null);
2391 if (receiver.getPendingResult() != null) {
2396 // Instantiate a BackupAgent and tell it that it's alive
2397 private void handleCreateBackupAgent(CreateBackupAgentData data) {
2398 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
2400 // Sanity check the requested target package's uid against ours
2402 PackageInfo requestedPackage = getPackageManager().getPackageInfo(
2403 data.appInfo.packageName, 0, UserHandle.myUserId());
2404 if (requestedPackage.applicationInfo.uid != Process.myUid()) {
2405 Slog.w(TAG, "Asked to instantiate non-matching package "
2406 + data.appInfo.packageName);
2409 } catch (RemoteException e) {
2410 Slog.e(TAG, "Can't reach package manager", e);
2414 // no longer idle; we have backup work to do
2415 unscheduleGcIdler();
2417 // instantiate the BackupAgent class named in the manifest
2418 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2419 String packageName = packageInfo.mPackageName;
2420 if (packageName == null) {
2421 Slog.d(TAG, "Asked to create backup agent for nonexistent package");
2425 if (mBackupAgents.get(packageName) != null) {
2426 Slog.d(TAG, "BackupAgent " + " for " + packageName
2427 + " already exists");
2431 BackupAgent agent = null;
2432 String classname = data.appInfo.backupAgentName;
2434 // full backup operation but no app-supplied agent? use the default implementation
2435 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2436 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
2437 classname = "android.app.backup.FullBackupAgent";
2441 IBinder binder = null;
2443 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2445 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2446 agent = (BackupAgent) cl.loadClass(classname).newInstance();
2448 // set up the agent's context
2449 ContextImpl context = new ContextImpl();
2450 context.init(packageInfo, null, this);
2451 context.setOuterContext(agent);
2452 agent.attach(context);
2455 binder = agent.onBind();
2456 mBackupAgents.put(packageName, agent);
2457 } catch (Exception e) {
2458 // If this is during restore, fail silently; otherwise go
2459 // ahead and let the user see the crash.
2460 Slog.e(TAG, "Agent threw during creation: " + e);
2461 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2462 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
2465 // falling through with 'binder' still null
2468 // tell the OS that we're live now
2470 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2471 } catch (RemoteException e) {
2474 } catch (Exception e) {
2475 throw new RuntimeException("Unable to create BackupAgent "
2476 + classname + ": " + e.toString(), e);
2480 // Tear down a BackupAgent
2481 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
2482 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
2484 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2485 String packageName = packageInfo.mPackageName;
2486 BackupAgent agent = mBackupAgents.get(packageName);
2487 if (agent != null) {
2490 } catch (Exception e) {
2491 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
2492 e.printStackTrace();
2494 mBackupAgents.remove(packageName);
2496 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
2500 private void handleCreateService(CreateServiceData data) {
2501 // If we are getting ready to gc after going to the background, well
2502 // we are back active so skip it.
2503 unscheduleGcIdler();
2505 LoadedApk packageInfo = getPackageInfoNoCheck(
2506 data.info.applicationInfo, data.compatInfo);
2507 Service service = null;
2509 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2510 service = (Service) cl.loadClass(data.info.name).newInstance();
2511 } catch (Exception e) {
2512 if (!mInstrumentation.onException(service, e)) {
2513 throw new RuntimeException(
2514 "Unable to instantiate service " + data.info.name
2515 + ": " + e.toString(), e);
2520 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
2522 ContextImpl context = new ContextImpl();
2523 context.init(packageInfo, null, this);
2525 Application app = packageInfo.makeApplication(false, mInstrumentation);
2526 context.setOuterContext(service);
2527 service.attach(context, this, data.info.name, data.token, app,
2528 ActivityManagerNative.getDefault());
2530 mServices.put(data.token, service);
2532 ActivityManagerNative.getDefault().serviceDoneExecuting(
2533 data.token, 0, 0, 0);
2534 } catch (RemoteException e) {
2537 } catch (Exception e) {
2538 if (!mInstrumentation.onException(service, e)) {
2539 throw new RuntimeException(
2540 "Unable to create service " + data.info.name
2541 + ": " + e.toString(), e);
2546 private void handleBindService(BindServiceData data) {
2547 Service s = mServices.get(data.token);
2549 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
2552 data.intent.setExtrasClassLoader(s.getClassLoader());
2555 IBinder binder = s.onBind(data.intent);
2556 ActivityManagerNative.getDefault().publishService(
2557 data.token, data.intent, binder);
2559 s.onRebind(data.intent);
2560 ActivityManagerNative.getDefault().serviceDoneExecuting(
2561 data.token, 0, 0, 0);
2564 } catch (RemoteException ex) {
2566 } catch (Exception e) {
2567 if (!mInstrumentation.onException(s, e)) {
2568 throw new RuntimeException(
2569 "Unable to bind to service " + s
2570 + " with " + data.intent + ": " + e.toString(), e);
2576 private void handleUnbindService(BindServiceData data) {
2577 Service s = mServices.get(data.token);
2580 data.intent.setExtrasClassLoader(s.getClassLoader());
2581 boolean doRebind = s.onUnbind(data.intent);
2584 ActivityManagerNative.getDefault().unbindFinished(
2585 data.token, data.intent, doRebind);
2587 ActivityManagerNative.getDefault().serviceDoneExecuting(
2588 data.token, 0, 0, 0);
2590 } catch (RemoteException ex) {
2592 } catch (Exception e) {
2593 if (!mInstrumentation.onException(s, e)) {
2594 throw new RuntimeException(
2595 "Unable to unbind to service " + s
2596 + " with " + data.intent + ": " + e.toString(), e);
2602 private void handleDumpService(DumpComponentInfo info) {
2603 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2605 Service s = mServices.get(info.token);
2607 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2608 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2612 IoUtils.closeQuietly(info.fd);
2613 StrictMode.setThreadPolicy(oldPolicy);
2617 private void handleDumpActivity(DumpComponentInfo info) {
2618 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2620 ActivityClientRecord r = mActivities.get(info.token);
2621 if (r != null && r.activity != null) {
2622 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2623 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2627 IoUtils.closeQuietly(info.fd);
2628 StrictMode.setThreadPolicy(oldPolicy);
2632 private void handleDumpProvider(DumpComponentInfo info) {
2633 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2635 ProviderClientRecord r = mLocalProviders.get(info.token);
2636 if (r != null && r.mLocalProvider != null) {
2637 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2638 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2642 IoUtils.closeQuietly(info.fd);
2643 StrictMode.setThreadPolicy(oldPolicy);
2647 private void handleServiceArgs(ServiceArgsData data) {
2648 Service s = mServices.get(data.token);
2651 if (data.args != null) {
2652 data.args.setExtrasClassLoader(s.getClassLoader());
2655 if (!data.taskRemoved) {
2656 res = s.onStartCommand(data.args, data.flags, data.startId);
2658 s.onTaskRemoved(data.args);
2659 res = Service.START_TASK_REMOVED_COMPLETE;
2662 QueuedWork.waitToFinish();
2665 ActivityManagerNative.getDefault().serviceDoneExecuting(
2666 data.token, 1, data.startId, res);
2667 } catch (RemoteException e) {
2671 } catch (Exception e) {
2672 if (!mInstrumentation.onException(s, e)) {
2673 throw new RuntimeException(
2674 "Unable to start service " + s
2675 + " with " + data.args + ": " + e.toString(), e);
2681 private void handleStopService(IBinder token) {
2682 Service s = mServices.remove(token);
2685 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
2687 Context context = s.getBaseContext();
2688 if (context instanceof ContextImpl) {
2689 final String who = s.getClassName();
2690 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
2693 QueuedWork.waitToFinish();
2696 ActivityManagerNative.getDefault().serviceDoneExecuting(
2698 } catch (RemoteException e) {
2701 } catch (Exception e) {
2702 if (!mInstrumentation.onException(s, e)) {
2703 throw new RuntimeException(
2704 "Unable to stop service " + s
2705 + ": " + e.toString(), e);
2709 //Slog.i(TAG, "Running services: " + mServices);
2712 public final ActivityClientRecord performResumeActivity(IBinder token,
2713 boolean clearHide) {
2714 ActivityClientRecord r = mActivities.get(token);
2715 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
2716 + " finished=" + r.activity.mFinished);
2717 if (r != null && !r.activity.mFinished) {
2719 r.hideForNow = false;
2720 r.activity.mStartedActivity = false;
2723 r.activity.mFragments.noteStateNotSaved();
2724 if (r.pendingIntents != null) {
2725 deliverNewIntents(r, r.pendingIntents);
2726 r.pendingIntents = null;
2728 if (r.pendingResults != null) {
2729 deliverResults(r, r.pendingResults);
2730 r.pendingResults = null;
2732 r.activity.performResume();
2734 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
2735 UserHandle.myUserId(), r.activity.getComponentName().getClassName());
2740 } catch (Exception e) {
2741 if (!mInstrumentation.onException(r.activity, e)) {
2742 throw new RuntimeException(
2743 "Unable to resume activity "
2744 + r.intent.getComponent().toShortString()
2745 + ": " + e.toString(), e);
2752 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
2753 if (r.mPendingRemoveWindow != null) {
2754 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2755 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2756 if (wtoken != null) {
2757 WindowManagerGlobal.getInstance().closeAll(wtoken,
2758 r.activity.getClass().getName(), "Activity");
2761 r.mPendingRemoveWindow = null;
2762 r.mPendingRemoveWindowManager = null;
2765 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2766 boolean reallyResume) {
2767 // If we are getting ready to gc after going to the background, well
2768 // we are back active so skip it.
2769 unscheduleGcIdler();
2771 ActivityClientRecord r = performResumeActivity(token, clearHide);
2774 final Activity a = r.activity;
2776 if (localLOGV) Slog.v(
2777 TAG, "Resume " + r + " started activity: " +
2778 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2779 + ", finished: " + a.mFinished);
2781 final int forwardBit = isForward ?
2782 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
2784 // If the window hasn't yet been added to the window manager,
2785 // and this guy didn't finish itself or start another activity,
2786 // then go ahead and add the window.
2787 boolean willBeVisible = !a.mStartedActivity;
2788 if (!willBeVisible) {
2790 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2791 a.getActivityToken());
2792 } catch (RemoteException e) {
2795 if (r.window == null && !a.mFinished && willBeVisible) {
2796 r.window = r.activity.getWindow();
2797 View decor = r.window.getDecorView();
2798 decor.setVisibility(View.INVISIBLE);
2799 ViewManager wm = a.getWindowManager();
2800 WindowManager.LayoutParams l = r.window.getAttributes();
2802 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2803 l.softInputMode |= forwardBit;
2804 if (a.mVisibleFromClient) {
2805 a.mWindowAdded = true;
2806 wm.addView(decor, l);
2809 // If the window has already been added, but during resume
2810 // we started another activity, then don't yet make the
2812 } else if (!willBeVisible) {
2813 if (localLOGV) Slog.v(
2814 TAG, "Launch " + r + " mStartedActivity set");
2815 r.hideForNow = true;
2818 // Get rid of anything left hanging around.
2819 cleanUpPendingRemoveWindows(r);
2821 // The window is now visible if it has been added, we are not
2822 // simply finishing, and we are not starting another activity.
2823 if (!r.activity.mFinished && willBeVisible
2824 && r.activity.mDecor != null && !r.hideForNow) {
2825 if (r.newConfig != null) {
2826 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
2827 + r.activityInfo.name + " with newConfig " + r.newConfig);
2828 performConfigurationChanged(r.activity, r.newConfig);
2829 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
2832 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
2834 WindowManager.LayoutParams l = r.window.getAttributes();
2835 if ((l.softInputMode
2836 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2838 l.softInputMode = (l.softInputMode
2839 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2841 if (r.activity.mVisibleFromClient) {
2842 ViewManager wm = a.getWindowManager();
2843 View decor = r.window.getDecorView();
2844 wm.updateViewLayout(decor, l);
2847 r.activity.mVisibleFromServer = true;
2848 mNumVisibleActivities++;
2849 if (r.activity.mVisibleFromClient) {
2850 r.activity.makeVisible();
2854 if (!r.onlyLocalRequest) {
2855 r.nextIdle = mNewActivities;
2857 if (localLOGV) Slog.v(
2858 TAG, "Scheduling idle handler for " + r);
2859 Looper.myQueue().addIdleHandler(new Idler());
2861 r.onlyLocalRequest = false;
2863 // Tell the activity manager we have resumed.
2866 ActivityManagerNative.getDefault().activityResumed(token);
2867 } catch (RemoteException ex) {
2872 // If an exception was thrown when trying to resume, then
2873 // just end this activity.
2875 ActivityManagerNative.getDefault()
2876 .finishActivity(token, Activity.RESULT_CANCELED, null);
2877 } catch (RemoteException ex) {
2882 private int mThumbnailWidth = -1;
2883 private int mThumbnailHeight = -1;
2884 private Bitmap mAvailThumbnailBitmap = null;
2885 private Canvas mThumbnailCanvas = null;
2887 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
2888 Bitmap thumbnail = mAvailThumbnailBitmap;
2890 if (thumbnail == null) {
2891 int w = mThumbnailWidth;
2894 Resources res = r.activity.getResources();
2895 mThumbnailHeight = h =
2896 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2898 mThumbnailWidth = w =
2899 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2901 h = mThumbnailHeight;
2904 // On platforms where we don't want thumbnails, set dims to (0,0)
2905 if ((w > 0) && (h > 0)) {
2906 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
2907 w, h, THUMBNAIL_FORMAT);
2908 thumbnail.eraseColor(0);
2912 if (thumbnail != null) {
2913 Canvas cv = mThumbnailCanvas;
2915 mThumbnailCanvas = cv = new Canvas();
2918 cv.setBitmap(thumbnail);
2919 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2920 mAvailThumbnailBitmap = thumbnail;
2926 } catch (Exception e) {
2927 if (!mInstrumentation.onException(r.activity, e)) {
2928 throw new RuntimeException(
2929 "Unable to create thumbnail of "
2930 + r.intent.getComponent().toShortString()
2931 + ": " + e.toString(), e);
2939 private void handlePauseActivity(IBinder token, boolean finished,
2940 boolean userLeaving, int configChanges) {
2941 ActivityClientRecord r = mActivities.get(token);
2943 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
2945 performUserLeavingActivity(r);
2948 r.activity.mConfigChangeFlags |= configChanges;
2949 performPauseActivity(token, finished, r.isPreHoneycomb());
2951 // Make sure any pending writes are now committed.
2952 if (r.isPreHoneycomb()) {
2953 QueuedWork.waitToFinish();
2956 // Tell the activity manager we have paused.
2958 ActivityManagerNative.getDefault().activityPaused(token);
2959 } catch (RemoteException ex) {
2964 final void performUserLeavingActivity(ActivityClientRecord r) {
2965 mInstrumentation.callActivityOnUserLeaving(r.activity);
2968 final Bundle performPauseActivity(IBinder token, boolean finished,
2969 boolean saveState) {
2970 ActivityClientRecord r = mActivities.get(token);
2971 return r != null ? performPauseActivity(r, finished, saveState) : null;
2974 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
2975 boolean saveState) {
2977 if (r.activity.mFinished) {
2978 // If we are finishing, we won't call onResume() in certain cases.
2979 // So here we likewise don't want to call onPause() if the activity
2983 RuntimeException e = new RuntimeException(
2984 "Performing pause of activity that is not resumed: "
2985 + r.intent.getComponent().toShortString());
2986 Slog.e(TAG, e.getMessage(), e);
2988 Bundle state = null;
2990 r.activity.mFinished = true;
2993 // Next have the activity save its current state and managed dialogs...
2994 if (!r.activity.mFinished && saveState) {
2995 state = new Bundle();
2996 state.setAllowFds(false);
2997 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3001 r.activity.mCalled = false;
3002 mInstrumentation.callActivityOnPause(r.activity);
3003 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3004 r.activity.getComponentName().getClassName());
3005 if (!r.activity.mCalled) {
3006 throw new SuperNotCalledException(
3007 "Activity " + r.intent.getComponent().toShortString() +
3008 " did not call through to super.onPause()");
3011 } catch (SuperNotCalledException e) {
3014 } catch (Exception e) {
3015 if (!mInstrumentation.onException(r.activity, e)) {
3016 throw new RuntimeException(
3017 "Unable to pause activity "
3018 + r.intent.getComponent().toShortString()
3019 + ": " + e.toString(), e);
3024 // Notify any outstanding on paused listeners
3025 ArrayList<OnActivityPausedListener> listeners;
3026 synchronized (mOnPauseListeners) {
3027 listeners = mOnPauseListeners.remove(r.activity);
3029 int size = (listeners != null ? listeners.size() : 0);
3030 for (int i = 0; i < size; i++) {
3031 listeners.get(i).onPaused(r.activity);
3037 final void performStopActivity(IBinder token, boolean saveState) {
3038 ActivityClientRecord r = mActivities.get(token);
3039 performStopActivityInner(r, null, false, saveState);
3042 private static class StopInfo implements Runnable {
3043 ActivityClientRecord activity;
3046 CharSequence description;
3048 @Override public void run() {
3049 // Tell activity manager we have been stopped.
3051 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3052 ActivityManagerNative.getDefault().activityStopped(
3053 activity.token, state, thumbnail, description);
3054 } catch (RemoteException ex) {
3059 private static final class ProviderRefCount {
3060 public final IActivityManager.ContentProviderHolder holder;
3061 public final ProviderClientRecord client;
3062 public int stableCount;
3063 public int unstableCount;
3065 // When this is set, the stable and unstable ref counts are 0 and
3066 // we have a pending operation scheduled to remove the ref count
3067 // from the activity manager. On the activity manager we are still
3068 // holding an unstable ref, though it is not reflected in the counts
3070 public boolean removePending;
3072 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3073 ProviderClientRecord inClient, int sCount, int uCount) {
3076 stableCount = sCount;
3077 unstableCount = uCount;
3082 * Core implementation of stopping an activity. Note this is a little
3083 * tricky because the server's meaning of stop is slightly different
3084 * than our client -- for the server, stop means to save state and give
3085 * it the result when it is done, but the window may still be visible.
3086 * For the client, we want to call onStop()/onStart() to indicate when
3087 * the activity's UI visibillity changes.
3089 private void performStopActivityInner(ActivityClientRecord r,
3090 StopInfo info, boolean keepShown, boolean saveState) {
3091 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3092 Bundle state = null;
3094 if (!keepShown && r.stopped) {
3095 if (r.activity.mFinished) {
3096 // If we are finishing, we won't call onResume() in certain
3097 // cases. So here we likewise don't want to call onStop()
3098 // if the activity isn't resumed.
3101 RuntimeException e = new RuntimeException(
3102 "Performing stop of activity that is not resumed: "
3103 + r.intent.getComponent().toShortString());
3104 Slog.e(TAG, e.getMessage(), e);
3109 // First create a thumbnail for the activity...
3110 // For now, don't create the thumbnail here; we are
3111 // doing that by doing a screen snapshot.
3112 info.thumbnail = null; //createThumbnailBitmap(r);
3113 info.description = r.activity.onCreateDescription();
3114 } catch (Exception e) {
3115 if (!mInstrumentation.onException(r.activity, e)) {
3116 throw new RuntimeException(
3117 "Unable to save state of activity "
3118 + r.intent.getComponent().toShortString()
3119 + ": " + e.toString(), e);
3124 // Next have the activity save its current state and managed dialogs...
3125 if (!r.activity.mFinished && saveState) {
3126 if (r.state == null) {
3127 state = new Bundle();
3128 state.setAllowFds(false);
3129 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3139 r.activity.performStop();
3140 } catch (Exception e) {
3141 if (!mInstrumentation.onException(r.activity, e)) {
3142 throw new RuntimeException(
3143 "Unable to stop activity "
3144 + r.intent.getComponent().toShortString()
3145 + ": " + e.toString(), e);
3155 private void updateVisibility(ActivityClientRecord r, boolean show) {
3156 View v = r.activity.mDecor;
3159 if (!r.activity.mVisibleFromServer) {
3160 r.activity.mVisibleFromServer = true;
3161 mNumVisibleActivities++;
3162 if (r.activity.mVisibleFromClient) {
3163 r.activity.makeVisible();
3166 if (r.newConfig != null) {
3167 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3168 + r.activityInfo.name + " with new config " + r.newConfig);
3169 performConfigurationChanged(r.activity, r.newConfig);
3170 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3174 if (r.activity.mVisibleFromServer) {
3175 r.activity.mVisibleFromServer = false;
3176 mNumVisibleActivities--;
3177 v.setVisibility(View.INVISIBLE);
3183 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
3184 ActivityClientRecord r = mActivities.get(token);
3185 r.activity.mConfigChangeFlags |= configChanges;
3187 StopInfo info = new StopInfo();
3188 performStopActivityInner(r, info, show, true);
3190 if (localLOGV) Slog.v(
3191 TAG, "Finishing stop of " + r + ": show=" + show
3192 + " win=" + r.window);
3194 updateVisibility(r, show);
3196 // Make sure any pending writes are now committed.
3197 if (!r.isPreHoneycomb()) {
3198 QueuedWork.waitToFinish();
3201 // Schedule the call to tell the activity manager we have
3202 // stopped. We don't do this immediately, because we want to
3203 // have a chance for any other pending work (in particular memory
3204 // trim requests) to complete before you tell the activity
3205 // manager to proceed and allow us to go fully into the background.
3207 info.state = r.state;
3211 final void performRestartActivity(IBinder token) {
3212 ActivityClientRecord r = mActivities.get(token);
3214 r.activity.performRestart();
3219 private void handleWindowVisibility(IBinder token, boolean show) {
3220 ActivityClientRecord r = mActivities.get(token);
3223 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3227 if (!show && !r.stopped) {
3228 performStopActivityInner(r, null, show, false);
3229 } else if (show && r.stopped) {
3230 // If we are getting ready to gc after going to the background, well
3231 // we are back active so skip it.
3232 unscheduleGcIdler();
3234 r.activity.performRestart();
3237 if (r.activity.mDecor != null) {
3239 TAG, "Handle window " + r + " visibility: " + show);
3240 updateVisibility(r, show);
3244 private void handleSleeping(IBinder token, boolean sleeping) {
3245 ActivityClientRecord r = mActivities.get(token);
3248 Log.w(TAG, "handleSleeping: no activity for token " + token);
3253 if (!r.stopped && !r.isPreHoneycomb()) {
3256 r.activity.performStop();
3257 } catch (Exception e) {
3258 if (!mInstrumentation.onException(r.activity, e)) {
3259 throw new RuntimeException(
3260 "Unable to stop activity "
3261 + r.intent.getComponent().toShortString()
3262 + ": " + e.toString(), e);
3268 // Make sure any pending writes are now committed.
3269 if (!r.isPreHoneycomb()) {
3270 QueuedWork.waitToFinish();
3273 // Tell activity manager we slept.
3275 ActivityManagerNative.getDefault().activitySlept(r.token);
3276 } catch (RemoteException ex) {
3279 if (r.stopped && r.activity.mVisibleFromServer) {
3280 r.activity.performRestart();
3286 private void handleSetCoreSettings(Bundle coreSettings) {
3287 synchronized (mPackages) {
3288 mCoreSettings = coreSettings;
3292 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3293 LoadedApk apk = peekPackageInfo(data.pkg, false);
3295 apk.mCompatibilityInfo.set(data.info);
3297 apk = peekPackageInfo(data.pkg, true);
3299 apk.mCompatibilityInfo.set(data.info);
3301 handleConfigurationChanged(mConfiguration, data.info);
3302 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
3305 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
3306 final int N = results.size();
3307 for (int i=0; i<N; i++) {
3308 ResultInfo ri = results.get(i);
3310 if (ri.mData != null) {
3311 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3313 if (DEBUG_RESULTS) Slog.v(TAG,
3314 "Delivering result to activity " + r + " : " + ri);
3315 r.activity.dispatchActivityResult(ri.mResultWho,
3316 ri.mRequestCode, ri.mResultCode, ri.mData);
3317 } catch (Exception e) {
3318 if (!mInstrumentation.onException(r.activity, e)) {
3319 throw new RuntimeException(
3320 "Failure delivering result " + ri + " to activity "
3321 + r.intent.getComponent().toShortString()
3322 + ": " + e.toString(), e);
3328 private void handleSendResult(ResultData res) {
3329 ActivityClientRecord r = mActivities.get(res.token);
3330 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
3332 final boolean resumed = !r.paused;
3333 if (!r.activity.mFinished && r.activity.mDecor != null
3334 && r.hideForNow && resumed) {
3335 // We had hidden the activity because it started another
3336 // one... we have gotten a result back and we are not
3337 // paused, so make sure our window is visible.
3338 updateVisibility(r, true);
3343 r.activity.mCalled = false;
3344 r.activity.mTemporaryPause = true;
3345 mInstrumentation.callActivityOnPause(r.activity);
3346 if (!r.activity.mCalled) {
3347 throw new SuperNotCalledException(
3348 "Activity " + r.intent.getComponent().toShortString()
3349 + " did not call through to super.onPause()");
3351 } catch (SuperNotCalledException e) {
3353 } catch (Exception e) {
3354 if (!mInstrumentation.onException(r.activity, e)) {
3355 throw new RuntimeException(
3356 "Unable to pause activity "
3357 + r.intent.getComponent().toShortString()
3358 + ": " + e.toString(), e);
3362 deliverResults(r, res.results);
3364 r.activity.performResume();
3365 r.activity.mTemporaryPause = false;
3370 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
3371 return performDestroyActivity(token, finishing, 0, false);
3374 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
3375 int configChanges, boolean getNonConfigInstance) {
3376 ActivityClientRecord r = mActivities.get(token);
3377 Class activityClass = null;
3378 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
3380 activityClass = r.activity.getClass();
3381 r.activity.mConfigChangeFlags |= configChanges;
3383 r.activity.mFinished = true;
3387 r.activity.mCalled = false;
3388 mInstrumentation.callActivityOnPause(r.activity);
3389 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3390 r.activity.getComponentName().getClassName());
3391 if (!r.activity.mCalled) {
3392 throw new SuperNotCalledException(
3393 "Activity " + safeToComponentShortString(r.intent)
3394 + " did not call through to super.onPause()");
3396 } catch (SuperNotCalledException e) {
3398 } catch (Exception e) {
3399 if (!mInstrumentation.onException(r.activity, e)) {
3400 throw new RuntimeException(
3401 "Unable to pause activity "
3402 + safeToComponentShortString(r.intent)
3403 + ": " + e.toString(), e);
3410 r.activity.performStop();
3411 } catch (SuperNotCalledException e) {
3413 } catch (Exception e) {
3414 if (!mInstrumentation.onException(r.activity, e)) {
3415 throw new RuntimeException(
3416 "Unable to stop activity "
3417 + safeToComponentShortString(r.intent)
3418 + ": " + e.toString(), e);
3423 if (getNonConfigInstance) {
3425 r.lastNonConfigurationInstances
3426 = r.activity.retainNonConfigurationInstances();
3427 } catch (Exception e) {
3428 if (!mInstrumentation.onException(r.activity, e)) {
3429 throw new RuntimeException(
3430 "Unable to retain activity "
3431 + r.intent.getComponent().toShortString()
3432 + ": " + e.toString(), e);
3437 r.activity.mCalled = false;
3438 mInstrumentation.callActivityOnDestroy(r.activity);
3439 if (!r.activity.mCalled) {
3440 throw new SuperNotCalledException(
3441 "Activity " + safeToComponentShortString(r.intent) +
3442 " did not call through to super.onDestroy()");
3444 if (r.window != null) {
3445 r.window.closeAllPanels();
3447 } catch (SuperNotCalledException e) {
3449 } catch (Exception e) {
3450 if (!mInstrumentation.onException(r.activity, e)) {
3451 throw new RuntimeException(
3452 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3453 + ": " + e.toString(), e);
3457 mActivities.remove(token);
3458 StrictMode.decrementExpectedActivityCount(activityClass);
3462 private static String safeToComponentShortString(Intent intent) {
3463 ComponentName component = intent.getComponent();
3464 return component == null ? "[Unknown]" : component.toShortString();
3467 private void handleDestroyActivity(IBinder token, boolean finishing,
3468 int configChanges, boolean getNonConfigInstance) {
3469 ActivityClientRecord r = performDestroyActivity(token, finishing,
3470 configChanges, getNonConfigInstance);
3472 cleanUpPendingRemoveWindows(r);
3473 WindowManager wm = r.activity.getWindowManager();
3474 View v = r.activity.mDecor;
3476 if (r.activity.mVisibleFromServer) {
3477 mNumVisibleActivities--;
3479 IBinder wtoken = v.getWindowToken();
3480 if (r.activity.mWindowAdded) {
3481 if (r.onlyLocalRequest) {
3482 // Hold off on removing this until the new activity's
3483 // window is being added.
3484 r.mPendingRemoveWindow = v;
3485 r.mPendingRemoveWindowManager = wm;
3487 wm.removeViewImmediate(v);
3490 if (wtoken != null && r.mPendingRemoveWindow == null) {
3491 WindowManagerGlobal.getInstance().closeAll(wtoken,
3492 r.activity.getClass().getName(), "Activity");
3494 r.activity.mDecor = null;
3496 if (r.mPendingRemoveWindow == null) {
3497 // If we are delaying the removal of the activity window, then
3498 // we can't clean up all windows here. Note that we can't do
3499 // so later either, which means any windows that aren't closed
3500 // by the app will leak. Well we try to warning them a lot
3501 // about leaking windows, because that is a bug, so if they are
3502 // using this recreate facility then they get to live with leaks.
3503 WindowManagerGlobal.getInstance().closeAll(token,
3504 r.activity.getClass().getName(), "Activity");
3507 // Mocked out contexts won't be participating in the normal
3508 // process lifecycle, but if we're running with a proper
3509 // ApplicationContext we need to have it tear down things
3511 Context c = r.activity.getBaseContext();
3512 if (c instanceof ContextImpl) {
3513 ((ContextImpl) c).scheduleFinalCleanup(
3514 r.activity.getClass().getName(), "Activity");
3519 ActivityManagerNative.getDefault().activityDestroyed(token);
3520 } catch (RemoteException ex) {
3521 // If the system process has died, it's game over for everyone.
3526 public final void requestRelaunchActivity(IBinder token,
3527 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3528 int configChanges, boolean notResumed, Configuration config,
3529 boolean fromServer) {
3530 ActivityClientRecord target = null;
3532 synchronized (mPackages) {
3533 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3534 ActivityClientRecord r = mRelaunchingActivities.get(i);
3535 if (r.token == token) {
3537 if (pendingResults != null) {
3538 if (r.pendingResults != null) {
3539 r.pendingResults.addAll(pendingResults);
3541 r.pendingResults = pendingResults;
3544 if (pendingNewIntents != null) {
3545 if (r.pendingIntents != null) {
3546 r.pendingIntents.addAll(pendingNewIntents);
3548 r.pendingIntents = pendingNewIntents;
3555 if (target == null) {
3556 target = new ActivityClientRecord();
3557 target.token = token;
3558 target.pendingResults = pendingResults;
3559 target.pendingIntents = pendingNewIntents;
3561 ActivityClientRecord existing = mActivities.get(token);
3562 if (existing != null) {
3563 target.startsNotResumed = existing.paused;
3565 target.onlyLocalRequest = true;
3567 mRelaunchingActivities.add(target);
3568 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
3572 target.startsNotResumed = notResumed;
3573 target.onlyLocalRequest = false;
3575 if (config != null) {
3576 target.createdConfig = config;
3578 target.pendingConfigChanges |= configChanges;
3582 private void handleRelaunchActivity(ActivityClientRecord tmp) {
3583 // If we are getting ready to gc after going to the background, well
3584 // we are back active so skip it.
3585 unscheduleGcIdler();
3587 Configuration changedConfig = null;
3588 int configChanges = 0;
3590 // First: make sure we have the most recent configuration and most
3591 // recent version of the activity, or skip it if some previous call
3592 // had taken a more recent version.
3593 synchronized (mPackages) {
3594 int N = mRelaunchingActivities.size();
3595 IBinder token = tmp.token;
3597 for (int i=0; i<N; i++) {
3598 ActivityClientRecord r = mRelaunchingActivities.get(i);
3599 if (r.token == token) {
3601 configChanges |= tmp.pendingConfigChanges;
3602 mRelaunchingActivities.remove(i);
3609 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
3613 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3614 + tmp.token + " with configChanges=0x"
3615 + Integer.toHexString(configChanges));
3617 if (mPendingConfiguration != null) {
3618 changedConfig = mPendingConfiguration;
3619 mPendingConfiguration = null;
3623 if (tmp.createdConfig != null) {
3624 // If the activity manager is passing us its current config,
3625 // assume that is really what we want regardless of what we
3626 // may have pending.
3627 if (mConfiguration == null
3628 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3629 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3630 if (changedConfig == null
3631 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3632 changedConfig = tmp.createdConfig;
3637 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3638 + tmp.token + ": changedConfig=" + changedConfig);
3640 // If there was a pending configuration change, execute it first.
3641 if (changedConfig != null) {
3642 mCurDefaultDisplayDpi = changedConfig.densityDpi;
3643 updateDefaultDensity();
3644 handleConfigurationChanged(changedConfig, null);
3647 ActivityClientRecord r = mActivities.get(tmp.token);
3648 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
3653 r.activity.mConfigChangeFlags |= configChanges;
3654 r.onlyLocalRequest = tmp.onlyLocalRequest;
3655 Intent currentIntent = r.activity.mIntent;
3657 r.activity.mChangingConfigurations = true;
3659 // Need to ensure state is saved.
3661 performPauseActivity(r.token, false, r.isPreHoneycomb());
3663 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3664 r.state = new Bundle();
3665 r.state.setAllowFds(false);
3666 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
3669 handleDestroyActivity(r.token, false, configChanges, true);
3673 r.hideForNow = false;
3675 // Merge any pending results and pending intents; don't just replace them
3676 if (tmp.pendingResults != null) {
3677 if (r.pendingResults == null) {
3678 r.pendingResults = tmp.pendingResults;
3680 r.pendingResults.addAll(tmp.pendingResults);
3683 if (tmp.pendingIntents != null) {
3684 if (r.pendingIntents == null) {
3685 r.pendingIntents = tmp.pendingIntents;
3687 r.pendingIntents.addAll(tmp.pendingIntents);
3690 r.startsNotResumed = tmp.startsNotResumed;
3692 handleLaunchActivity(r, currentIntent);
3695 private void handleRequestThumbnail(IBinder token) {
3696 ActivityClientRecord r = mActivities.get(token);
3697 Bitmap thumbnail = createThumbnailBitmap(r);
3698 CharSequence description = null;
3700 description = r.activity.onCreateDescription();
3701 } catch (Exception e) {
3702 if (!mInstrumentation.onException(r.activity, e)) {
3703 throw new RuntimeException(
3704 "Unable to create description of activity "
3705 + r.intent.getComponent().toShortString()
3706 + ": " + e.toString(), e);
3709 //System.out.println("Reporting top thumbnail " + thumbnail);
3711 ActivityManagerNative.getDefault().reportThumbnail(
3712 token, thumbnail, description);
3713 } catch (RemoteException ex) {
3717 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
3718 boolean allActivities, Configuration newConfig) {
3719 ArrayList<ComponentCallbacks2> callbacks
3720 = new ArrayList<ComponentCallbacks2>();
3722 synchronized (mPackages) {
3723 final int N = mAllApplications.size();
3724 for (int i=0; i<N; i++) {
3725 callbacks.add(mAllApplications.get(i));
3727 if (mActivities.size() > 0) {
3728 for (ActivityClientRecord ar : mActivities.values()) {
3729 Activity a = ar.activity;
3731 Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
3732 newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
3733 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3734 // If the activity is currently resumed, its configuration
3735 // needs to change right now.
3737 } else if (thisConfig != null) {
3738 // Otherwise, we will tell it about the change
3739 // the next time it is resumed or shown. Note that
3740 // the activity manager may, before then, decide the
3741 // activity needs to be destroyed to handle its new
3743 if (DEBUG_CONFIGURATION) {
3744 Slog.v(TAG, "Setting activity "
3745 + ar.activityInfo.name + " newConfig=" + thisConfig);
3747 ar.newConfig = thisConfig;
3752 if (mServices.size() > 0) {
3753 for (Service service : mServices.values()) {
3754 callbacks.add(service);
3758 synchronized (mProviderMap) {
3759 if (mLocalProviders.size() > 0) {
3760 for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
3761 callbacks.add(providerClientRecord.mLocalProvider);
3769 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
3770 // Only for Activity objects, check that they actually call up to their
3771 // superclass implementation. ComponentCallbacks2 is an interface, so
3772 // we check the runtime type and act accordingly.
3773 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3774 if (activity != null) {
3775 activity.mCalled = false;
3778 boolean shouldChangeConfig = false;
3779 if ((activity == null) || (activity.mCurrentConfig == null)) {
3780 shouldChangeConfig = true;
3783 // If the new config is the same as the config this Activity
3784 // is already running with then don't bother calling
3785 // onConfigurationChanged
3786 int diff = activity.mCurrentConfig.diff(config);
3788 // If this activity doesn't handle any of the config changes
3789 // then don't bother calling onConfigurationChanged as we're
3790 // going to destroy it.
3791 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
3792 shouldChangeConfig = true;
3797 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
3798 + ": shouldChangeConfig=" + shouldChangeConfig);
3799 if (shouldChangeConfig) {
3800 cb.onConfigurationChanged(config);
3802 if (activity != null) {
3803 if (!activity.mCalled) {
3804 throw new SuperNotCalledException(
3805 "Activity " + activity.getLocalClassName() +
3806 " did not call through to super.onConfigurationChanged()");
3808 activity.mConfigChangeFlags = 0;
3809 activity.mCurrentConfig = new Configuration(config);
3814 public final void applyConfigurationToResources(Configuration config) {
3815 synchronized (mPackages) {
3816 applyConfigurationToResourcesLocked(config, null);
3820 final boolean applyConfigurationToResourcesLocked(Configuration config,
3821 CompatibilityInfo compat) {
3822 if (mResConfiguration == null) {
3823 mResConfiguration = new Configuration();
3825 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
3826 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
3827 + mResConfiguration.seq + ", newSeq=" + config.seq);
3830 int changes = mResConfiguration.updateFrom(config);
3831 flushDisplayMetricsLocked();
3832 DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
3833 Display.DEFAULT_DISPLAY, null);
3835 if (compat != null && (mResCompatibilityInfo == null ||
3836 !mResCompatibilityInfo.equals(compat))) {
3837 mResCompatibilityInfo = compat;
3838 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
3839 | ActivityInfo.CONFIG_SCREEN_SIZE
3840 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
3843 // set it for java, this also affects newly created Resources
3844 if (config.locale != null) {
3845 Locale.setDefault(config.locale);
3848 Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
3850 ApplicationPackageManager.configurationChanged();
3851 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
3853 Configuration tmpConfig = null;
3855 Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
3856 mActiveResources.entrySet().iterator();
3857 while (it.hasNext()) {
3858 Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
3859 Resources r = entry.getValue().get();
3861 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
3862 + r + " config to: " + config);
3863 int displayId = entry.getKey().mDisplayId;
3864 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
3865 DisplayMetrics dm = defaultDisplayMetrics;
3866 Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
3867 if (!isDefaultDisplay || overrideConfig != null) {
3868 if (tmpConfig == null) {
3869 tmpConfig = new Configuration();
3871 tmpConfig.setTo(config);
3872 if (!isDefaultDisplay) {
3873 dm = getDisplayMetricsLocked(displayId, null);
3874 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
3876 if (overrideConfig != null) {
3877 tmpConfig.updateFrom(overrideConfig);
3879 r.updateConfiguration(tmpConfig, dm, compat);
3881 r.updateConfiguration(config, dm, compat);
3883 //Slog.i(TAG, "Updated app resources " + v.getKey()
3884 // + " " + r + ": " + r.getConfiguration());
3886 //Slog.i(TAG, "Removing old resources " + v.getKey());
3891 return changes != 0;
3894 final void applyNonDefaultDisplayMetricsToConfigurationLocked(
3895 DisplayMetrics dm, Configuration config) {
3896 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
3897 config.densityDpi = dm.densityDpi;
3898 config.screenWidthDp = (int)(dm.widthPixels / dm.density);
3899 config.screenHeightDp = (int)(dm.heightPixels / dm.density);
3900 int sl = Configuration.resetScreenLayout(config.screenLayout);
3901 if (dm.widthPixels > dm.heightPixels) {
3902 config.orientation = Configuration.ORIENTATION_LANDSCAPE;
3903 config.screenLayout = Configuration.reduceScreenLayout(sl,
3904 config.screenWidthDp, config.screenHeightDp);
3906 config.orientation = Configuration.ORIENTATION_PORTRAIT;
3907 config.screenLayout = Configuration.reduceScreenLayout(sl,
3908 config.screenHeightDp, config.screenWidthDp);
3910 config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
3911 config.compatScreenWidthDp = config.screenWidthDp;
3912 config.compatScreenHeightDp = config.screenHeightDp;
3913 config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
3916 final Configuration applyCompatConfiguration(int displayDensity) {
3917 Configuration config = mConfiguration;
3918 if (mCompatConfiguration == null) {
3919 mCompatConfiguration = new Configuration();
3921 mCompatConfiguration.setTo(mConfiguration);
3922 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
3923 mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration);
3924 config = mCompatConfiguration;
3929 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
3933 synchronized (mPackages) {
3934 if (mPendingConfiguration != null) {
3935 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3936 config = mPendingConfiguration;
3937 mCurDefaultDisplayDpi = config.densityDpi;
3938 updateDefaultDensity();
3940 mPendingConfiguration = null;
3943 if (config == null) {
3947 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
3950 applyConfigurationToResourcesLocked(config, compat);
3952 if (mConfiguration == null) {
3953 mConfiguration = new Configuration();
3955 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
3958 configDiff = mConfiguration.diff(config);
3959 mConfiguration.updateFrom(config);
3960 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
3963 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
3965 // Cleanup hardware accelerated stuff
3966 WindowManagerGlobal.getInstance().trimLocalMemory();
3968 freeTextLayoutCachesIfNeeded(configDiff);
3970 if (callbacks != null) {
3971 final int N = callbacks.size();
3972 for (int i=0; i<N; i++) {
3973 performConfigurationChanged(callbacks.get(i), config);
3978 final void freeTextLayoutCachesIfNeeded(int configDiff) {
3979 if (configDiff != 0) {
3980 // Ask text layout engine to free its caches if there is a locale change
3981 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
3982 if (hasLocaleConfigChange) {
3983 Canvas.freeTextLayoutCaches();
3984 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
3989 final void handleActivityConfigurationChanged(IBinder token) {
3990 ActivityClientRecord r = mActivities.get(token);
3991 if (r == null || r.activity == null) {
3995 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
3996 + r.activityInfo.name);
3998 performConfigurationChanged(r.activity, mCompatConfiguration);
4000 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
4003 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
4006 switch (profileType) {
4008 mProfiler.setProfiler(pcd.path, pcd.fd);
4009 mProfiler.autoStopProfiler = false;
4010 mProfiler.startProfiling();
4013 } catch (RuntimeException e) {
4014 Slog.w(TAG, "Profiling failed on path " + pcd.path
4015 + " -- can the process access this path?");
4019 } catch (IOException e) {
4020 Slog.w(TAG, "Failure closing profile fd", e);
4024 switch (profileType) {
4026 mProfiler.stopProfiling();
4032 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4035 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4036 } catch (IOException e) {
4037 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4038 + " -- can the process access this path?");
4042 } catch (IOException e) {
4043 Slog.w(TAG, "Failure closing profile fd", e);
4047 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4051 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4052 boolean hasPkgInfo = false;
4053 if (packages != null) {
4054 for (int i=packages.length-1; i>=0; i--) {
4055 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4057 WeakReference<LoadedApk> ref;
4058 ref = mPackages.get(packages[i]);
4059 if (ref != null && ref.get() != null) {
4062 ref = mResourcePackages.get(packages[i]);
4063 if (ref != null && ref.get() != null) {
4068 mPackages.remove(packages[i]);
4069 mResourcePackages.remove(packages[i]);
4072 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4076 final void handleLowMemory() {
4077 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4079 final int N = callbacks.size();
4080 for (int i=0; i<N; i++) {
4081 callbacks.get(i).onLowMemory();
4084 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4085 if (Process.myUid() != Process.SYSTEM_UID) {
4086 int sqliteReleased = SQLiteDatabase.releaseMemory();
4087 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4090 // Ask graphics to free up as much as possible (font/image caches)
4091 Canvas.freeCaches();
4093 // Ask text layout engine to free also as much as possible
4094 Canvas.freeTextLayoutCaches();
4096 BinderInternal.forceGc("mem");
4099 final void handleTrimMemory(int level) {
4100 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4102 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
4103 windowManager.startTrimMemory(level);
4105 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4107 final int N = callbacks.size();
4108 for (int i = 0; i < N; i++) {
4109 callbacks.get(i).onTrimMemory(level);
4112 windowManager.endTrimMemory();
4115 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4116 if (Process.isIsolated()) {
4117 // Isolated processes aren't going to do UI.
4121 int uid = Process.myUid();
4122 String[] packages = getPackageManager().getPackagesForUid(uid);
4124 // If there are several packages in this application we won't
4125 // initialize the graphics disk caches
4126 if (packages != null && packages.length == 1) {
4127 HardwareRenderer.setupDiskCache(cacheDir);
4128 RenderScript.setupDiskCache(cacheDir);
4130 } catch (RemoteException e) {
4135 private void updateDefaultDensity() {
4136 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4137 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4138 && !mDensityCompatMode) {
4139 Slog.i(TAG, "Switching default density from "
4140 + DisplayMetrics.DENSITY_DEVICE + " to "
4141 + mCurDefaultDisplayDpi);
4142 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4143 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4147 private void handleBindApplication(AppBindData data) {
4148 mBoundApplication = data;
4149 mConfiguration = new Configuration(data.config);
4150 mCompatConfiguration = new Configuration(data.config);
4152 mProfiler = new Profiler();
4153 mProfiler.profileFile = data.initProfileFile;
4154 mProfiler.profileFd = data.initProfileFd;
4155 mProfiler.autoStopProfiler = data.initAutoStopProfiler;
4157 // send up app name; do this *before* waiting for debugger
4158 Process.setArgV0(data.processName);
4159 android.ddm.DdmHandleAppName.setAppName(data.processName,
4160 UserHandle.myUserId());
4162 if (data.persistent) {
4163 // Persistent processes on low-memory devices do not get to
4164 // use hardware accelerated drawing, since this can add too much
4165 // overhead to the process.
4166 if (!ActivityManager.isHighEndGfx()) {
4167 HardwareRenderer.disable(false);
4171 if (mProfiler.profileFd != null) {
4172 mProfiler.startProfiling();
4175 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4176 // implementation to use the pool executor. Normally, we use the
4177 // serialized executor as the default. This has to happen in the
4178 // main thread so the main looper is set right.
4179 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
4180 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4184 * Before spawning a new process, reset the time zone to be the system time zone.
4185 * This needs to be done because the system time zone could have changed after the
4186 * the spawning of this process. Without doing this this process would have the incorrect
4189 TimeZone.setDefault(null);
4192 * Initialize the default locale in this process for the reasons we set the time zone.
4194 Locale.setDefault(data.config.locale);
4197 * Update the system configuration since its preloaded and might not
4198 * reflect configuration changes. The configuration object passed
4199 * in AppBindData can be safely assumed to be up to date
4201 applyConfigurationToResourcesLocked(data.config, data.compatInfo);
4202 mCurDefaultDisplayDpi = data.config.densityDpi;
4203 applyCompatConfiguration(mCurDefaultDisplayDpi);
4205 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
4208 * Switch this process to density compatibility mode if needed.
4210 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4212 mDensityCompatMode = true;
4213 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4215 updateDefaultDensity();
4217 final ContextImpl appContext = new ContextImpl();
4218 appContext.init(data.info, null, this);
4219 if (!Process.isIsolated()) {
4220 final File cacheDir = appContext.getCacheDir();
4222 if (cacheDir != null) {
4223 // Provide a usable directory for temporary files
4224 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4226 setupGraphicsSupport(data.info, cacheDir);
4228 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4232 * For system applications on userdebug/eng builds, log stack
4233 * traces of disk and network access to dropbox for analysis.
4235 if ((data.appInfo.flags &
4236 (ApplicationInfo.FLAG_SYSTEM |
4237 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4238 StrictMode.conditionallyEnableDebugLogging();
4242 * For apps targetting SDK Honeycomb or later, we don't allow
4243 * network usage on the main event loop / UI thread.
4245 * Note to those grepping: this is what ultimately throws
4246 * NetworkOnMainThreadException ...
4248 if (data.appInfo.targetSdkVersion > 9) {
4249 StrictMode.enableDeathOnNetwork();
4252 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4253 // XXX should have option to change the port.
4254 Debug.changeDebugPort(8100);
4255 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
4256 Slog.w(TAG, "Application " + data.info.getPackageName()
4257 + " is waiting for the debugger on port 8100...");
4259 IActivityManager mgr = ActivityManagerNative.getDefault();
4261 mgr.showWaitingForDebugger(mAppThread, true);
4262 } catch (RemoteException ex) {
4265 Debug.waitForDebugger();
4268 mgr.showWaitingForDebugger(mAppThread, false);
4269 } catch (RemoteException ex) {
4273 Slog.w(TAG, "Application " + data.info.getPackageName()
4274 + " can be debugged on port 8100...");
4278 // Enable OpenGL tracing if required
4279 if (data.enableOpenGlTrace) {
4280 GLUtils.enableTracing();
4284 * Initialize the default http proxy in this process for the reasons we set the time zone.
4286 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
4288 // In pre-boot mode (doing initial launch to collect password), not
4289 // all system is up. This includes the connectivity service, so don't
4290 // crash if we can't get it.
4291 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4293 ProxyProperties proxyProperties = service.getProxy();
4294 Proxy.setHttpProxySystemProperty(proxyProperties);
4295 } catch (RemoteException e) {}
4298 if (data.instrumentationName != null) {
4299 InstrumentationInfo ii = null;
4301 ii = appContext.getPackageManager().
4302 getInstrumentationInfo(data.instrumentationName, 0);
4303 } catch (PackageManager.NameNotFoundException e) {
4306 throw new RuntimeException(
4307 "Unable to find instrumentation info for: "
4308 + data.instrumentationName);
4311 mInstrumentationAppDir = ii.sourceDir;
4312 mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
4313 mInstrumentationAppPackage = ii.packageName;
4314 mInstrumentedAppDir = data.info.getAppDir();
4315 mInstrumentedAppLibraryDir = data.info.getLibDir();
4317 ApplicationInfo instrApp = new ApplicationInfo();
4318 instrApp.packageName = ii.packageName;
4319 instrApp.sourceDir = ii.sourceDir;
4320 instrApp.publicSourceDir = ii.publicSourceDir;
4321 instrApp.dataDir = ii.dataDir;
4322 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
4323 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
4324 appContext.getClassLoader(), false, true);
4325 ContextImpl instrContext = new ContextImpl();
4326 instrContext.init(pi, null, this);
4329 java.lang.ClassLoader cl = instrContext.getClassLoader();
4330 mInstrumentation = (Instrumentation)
4331 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4332 } catch (Exception e) {
4333 throw new RuntimeException(
4334 "Unable to instantiate instrumentation "
4335 + data.instrumentationName + ": " + e.toString(), e);
4338 mInstrumentation.init(this, instrContext, appContext,
4339 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
4341 if (mProfiler.profileFile != null && !ii.handleProfiling
4342 && mProfiler.profileFd == null) {
4343 mProfiler.handlingProfiling = true;
4344 File file = new File(mProfiler.profileFile);
4345 file.getParentFile().mkdirs();
4346 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4350 mInstrumentation = new Instrumentation();
4353 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
4354 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
4357 // Allow disk access during application and provider setup. This could
4358 // block processing ordered broadcasts, but later processing would
4359 // probably end up doing the same disk access.
4360 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4362 // If the app is being launched for full backup or restore, bring it up in
4363 // a restricted environment with the base application class.
4364 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4365 mInitialApplication = app;
4367 // don't bring up providers in restricted mode; they may depend on the
4368 // app's custom Application class
4369 if (!data.restrictedBackupMode) {
4370 List<ProviderInfo> providers = data.providers;
4371 if (providers != null) {
4372 installContentProviders(app, providers);
4373 // For process that contains content providers, we want to
4374 // ensure that the JIT is enabled "at some point".
4375 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4379 // Do this after providers, since instrumentation tests generally start their
4380 // test thread at this point, and we don't want that racing.
4382 mInstrumentation.onCreate(data.instrumentationArgs);
4384 catch (Exception e) {
4385 throw new RuntimeException(
4386 "Exception thrown in onCreate() of "
4387 + data.instrumentationName + ": " + e.toString(), e);
4391 mInstrumentation.callApplicationOnCreate(app);
4392 } catch (Exception e) {
4393 if (!mInstrumentation.onException(app, e)) {
4394 throw new RuntimeException(
4395 "Unable to create application " + app.getClass().getName()
4396 + ": " + e.toString(), e);
4400 StrictMode.setThreadPolicy(savedPolicy);
4404 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4405 IActivityManager am = ActivityManagerNative.getDefault();
4406 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4407 && mProfiler.profileFd == null) {
4408 Debug.stopMethodTracing();
4410 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
4411 // + ", app thr: " + mAppThread);
4413 am.finishInstrumentation(mAppThread, resultCode, results);
4414 } catch (RemoteException ex) {
4418 private void installContentProviders(
4419 Context context, List<ProviderInfo> providers) {
4420 final ArrayList<IActivityManager.ContentProviderHolder> results =
4421 new ArrayList<IActivityManager.ContentProviderHolder>();
4423 for (ProviderInfo cpi : providers) {
4424 if (DEBUG_PROVIDER) {
4425 StringBuilder buf = new StringBuilder(128);
4427 buf.append(cpi.authority);
4429 buf.append(cpi.name);
4430 Log.i(TAG, buf.toString());
4432 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4433 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4435 cph.noReleaseNeeded = true;
4441 ActivityManagerNative.getDefault().publishContentProviders(
4442 getApplicationThread(), results);
4443 } catch (RemoteException ex) {
4447 public final IContentProvider acquireProvider(
4448 Context c, String auth, int userId, boolean stable) {
4449 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4450 if (provider != null) {
4454 // There is a possible race here. Another thread may try to acquire
4455 // the same provider at the same time. When this happens, we want to ensure
4456 // that the first one wins.
4457 // Note that we cannot hold the lock while acquiring and installing the
4458 // provider since it might take a long time to run and it could also potentially
4459 // be re-entrant in the case where the provider is in the same process.
4460 IActivityManager.ContentProviderHolder holder = null;
4462 holder = ActivityManagerNative.getDefault().getContentProvider(
4463 getApplicationThread(), auth, userId, stable);
4464 } catch (RemoteException ex) {
4466 if (holder == null) {
4467 Slog.e(TAG, "Failed to find provider info for " + auth);
4471 // Install provider will increment the reference count for us, and break
4472 // any ties in the race.
4473 holder = installProvider(c, holder, holder.info,
4474 true /*noisy*/, holder.noReleaseNeeded, stable);
4475 return holder.provider;
4478 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4480 prc.stableCount += 1;
4481 if (prc.stableCount == 1) {
4482 // We are acquiring a new stable reference on the provider.
4484 if (prc.removePending) {
4485 // We have a pending remove operation, which is holding the
4486 // last unstable reference. At this point we are converting
4487 // that unstable reference to our new stable reference.
4489 // Cancel the removal of the provider.
4490 if (DEBUG_PROVIDER) {
4491 Slog.v(TAG, "incProviderRef: stable "
4492 + "snatched provider from the jaws of death");
4494 prc.removePending = false;
4495 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4500 if (DEBUG_PROVIDER) {
4501 Slog.v(TAG, "incProviderRef Now stable - "
4502 + prc.holder.info.name + ": unstableDelta="
4505 ActivityManagerNative.getDefault().refContentProvider(
4506 prc.holder.connection, 1, unstableDelta);
4507 } catch (RemoteException e) {
4508 //do nothing content provider object is dead any way
4512 prc.unstableCount += 1;
4513 if (prc.unstableCount == 1) {
4514 // We are acquiring a new unstable reference on the provider.
4515 if (prc.removePending) {
4516 // Oh look, we actually have a remove pending for the
4517 // provider, which is still holding the last unstable
4518 // reference. We just need to cancel that to take new
4519 // ownership of the reference.
4520 if (DEBUG_PROVIDER) {
4521 Slog.v(TAG, "incProviderRef: unstable "
4522 + "snatched provider from the jaws of death");
4524 prc.removePending = false;
4525 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4527 // First unstable ref, increment our count in the
4528 // activity manager.
4530 if (DEBUG_PROVIDER) {
4531 Slog.v(TAG, "incProviderRef: Now unstable - "
4532 + prc.holder.info.name);
4534 ActivityManagerNative.getDefault().refContentProvider(
4535 prc.holder.connection, 0, 1);
4536 } catch (RemoteException e) {
4537 //do nothing content provider object is dead any way
4544 public final IContentProvider acquireExistingProvider(
4545 Context c, String auth, int userId, boolean stable) {
4546 synchronized (mProviderMap) {
4547 final ProviderKey key = new ProviderKey(auth, userId);
4548 final ProviderClientRecord pr = mProviderMap.get(key);
4553 IContentProvider provider = pr.mProvider;
4554 IBinder jBinder = provider.asBinder();
4555 if (!jBinder.isBinderAlive()) {
4556 // The hosting process of the provider has died; we can't
4558 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4559 + ": existing object's process dead");
4560 handleUnstableProviderDiedLocked(jBinder, true);
4564 // Only increment the ref count if we have one. If we don't then the
4565 // provider is not reference counted and never needs to be released.
4566 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4568 incProviderRefLocked(prc, stable);
4574 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4575 if (provider == null) {
4579 IBinder jBinder = provider.asBinder();
4580 synchronized (mProviderMap) {
4581 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4583 // The provider has no ref count, no release is needed.
4587 boolean lastRef = false;
4589 if (prc.stableCount == 0) {
4590 if (DEBUG_PROVIDER) Slog.v(TAG,
4591 "releaseProvider: stable ref count already 0, how?");
4594 prc.stableCount -= 1;
4595 if (prc.stableCount == 0) {
4596 // What we do at this point depends on whether there are
4597 // any unstable refs left: if there are, we just tell the
4598 // activity manager to decrement its stable count; if there
4599 // aren't, we need to enqueue this provider to be removed,
4600 // and convert to holding a single unstable ref while
4602 lastRef = prc.unstableCount == 0;
4604 if (DEBUG_PROVIDER) {
4605 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4606 + lastRef + " - " + prc.holder.info.name);
4608 ActivityManagerNative.getDefault().refContentProvider(
4609 prc.holder.connection, -1, lastRef ? 1 : 0);
4610 } catch (RemoteException e) {
4611 //do nothing content provider object is dead any way
4615 if (prc.unstableCount == 0) {
4616 if (DEBUG_PROVIDER) Slog.v(TAG,
4617 "releaseProvider: unstable ref count already 0, how?");
4620 prc.unstableCount -= 1;
4621 if (prc.unstableCount == 0) {
4622 // If this is the last reference, we need to enqueue
4623 // this provider to be removed instead of telling the
4624 // activity manager to remove it at this point.
4625 lastRef = prc.stableCount == 0;
4628 if (DEBUG_PROVIDER) {
4629 Slog.v(TAG, "releaseProvider: No longer unstable - "
4630 + prc.holder.info.name);
4632 ActivityManagerNative.getDefault().refContentProvider(
4633 prc.holder.connection, 0, -1);
4634 } catch (RemoteException e) {
4635 //do nothing content provider object is dead any way
4642 if (!prc.removePending) {
4643 // Schedule the actual remove asynchronously, since we don't know the context
4644 // this will be called in.
4645 // TODO: it would be nice to post a delayed message, so
4646 // if we come back and need the same provider quickly
4647 // we will still have it available.
4648 if (DEBUG_PROVIDER) {
4649 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4650 + prc.holder.info.name);
4652 prc.removePending = true;
4653 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4654 mH.sendMessage(msg);
4656 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4663 final void completeRemoveProvider(ProviderRefCount prc) {
4664 synchronized (mProviderMap) {
4665 if (!prc.removePending) {
4666 // There was a race! Some other client managed to acquire
4667 // the provider before the removal was completed.
4668 // Abort the removal. We will do it later.
4669 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
4670 + "provider still in use");
4674 final IBinder jBinder = prc.holder.provider.asBinder();
4675 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4676 if (existingPrc == prc) {
4677 mProviderRefCountMap.remove(jBinder);
4680 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
4681 while (iter.hasNext()) {
4682 ProviderClientRecord pr = iter.next();
4683 IBinder myBinder = pr.mProvider.asBinder();
4684 if (myBinder == jBinder) {
4691 if (DEBUG_PROVIDER) {
4692 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4693 + "removeContentProvider(" + prc.holder.info.name + ")");
4695 ActivityManagerNative.getDefault().removeContentProvider(
4696 prc.holder.connection, false);
4697 } catch (RemoteException e) {
4698 //do nothing content provider object is dead any way
4702 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4703 synchronized (mProviderMap) {
4704 handleUnstableProviderDiedLocked(provider, fromClient);
4708 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
4709 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4711 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4712 + provider + " " + prc.holder.info.name);
4713 mProviderRefCountMap.remove(provider);
4714 if (prc.client != null && prc.client.mNames != null) {
4715 for (String name : prc.client.mNames) {
4716 ProviderClientRecord pr = mProviderMap.get(name);
4717 if (pr != null && pr.mProvider.asBinder() == provider) {
4718 Slog.i(TAG, "Removing dead content provider: " + name);
4719 mProviderMap.remove(name);
4724 // We found out about this due to execution in our client
4725 // code. Tell the activity manager about it now, to ensure
4726 // that the next time we go to do anything with the provider
4727 // it knows it is dead (so we don't race with its death
4730 ActivityManagerNative.getDefault().unstableProviderDied(
4731 prc.holder.connection);
4732 } catch (RemoteException e) {
4733 //do nothing content provider object is dead any way
4739 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4740 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4741 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4742 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4744 final ProviderClientRecord pcr = new ProviderClientRecord(
4745 auths, provider, localProvider, holder);
4746 for (String auth : auths) {
4747 final ProviderKey key = new ProviderKey(auth, userId);
4748 final ProviderClientRecord existing = mProviderMap.get(key);
4749 if (existing != null) {
4750 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
4751 + " already published as " + auth);
4753 mProviderMap.put(key, pcr);
4760 * Installs the provider.
4762 * Providers that are local to the process or that come from the system server
4763 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4764 * Other remote providers are reference counted. The initial reference count
4765 * for all reference counted providers is one. Providers that are not reference
4766 * counted do not have a reference count (at all).
4768 * This method detects when a provider has already been installed. When this happens,
4769 * it increments the reference count of the existing provider (if appropriate)
4770 * and returns the existing provider. This can happen due to concurrent
4771 * attempts to acquire the same provider.
4773 private IActivityManager.ContentProviderHolder installProvider(Context context,
4774 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4775 boolean noisy, boolean noReleaseNeeded, boolean stable) {
4776 ContentProvider localProvider = null;
4777 IContentProvider provider;
4778 if (holder == null || holder.provider == null) {
4779 if (DEBUG_PROVIDER || noisy) {
4780 Slog.d(TAG, "Loading provider " + info.authority + ": "
4784 ApplicationInfo ai = info.applicationInfo;
4785 if (context.getPackageName().equals(ai.packageName)) {
4787 } else if (mInitialApplication != null &&
4788 mInitialApplication.getPackageName().equals(ai.packageName)) {
4789 c = mInitialApplication;
4792 c = context.createPackageContext(ai.packageName,
4793 Context.CONTEXT_INCLUDE_CODE);
4794 } catch (PackageManager.NameNotFoundException e) {
4799 Slog.w(TAG, "Unable to get context for package " +
4801 " while loading content provider " +
4806 final java.lang.ClassLoader cl = c.getClassLoader();
4807 localProvider = (ContentProvider)cl.
4808 loadClass(info.name).newInstance();
4809 provider = localProvider.getIContentProvider();
4810 if (provider == null) {
4811 Slog.e(TAG, "Failed to instantiate class " +
4812 info.name + " from sourceDir " +
4813 info.applicationInfo.sourceDir);
4816 if (DEBUG_PROVIDER) Slog.v(
4817 TAG, "Instantiating local provider " + info.name);
4818 // XXX Need to create the correct context for this provider.
4819 localProvider.attachInfo(c, info);
4820 } catch (java.lang.Exception e) {
4821 if (!mInstrumentation.onException(null, e)) {
4822 throw new RuntimeException(
4823 "Unable to get provider " + info.name
4824 + ": " + e.toString(), e);
4829 provider = holder.provider;
4830 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
4834 IActivityManager.ContentProviderHolder retHolder;
4836 synchronized (mProviderMap) {
4837 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4838 + " / " + info.name);
4839 IBinder jBinder = provider.asBinder();
4840 if (localProvider != null) {
4841 ComponentName cname = new ComponentName(info.packageName, info.name);
4842 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
4844 if (DEBUG_PROVIDER) {
4845 Slog.v(TAG, "installProvider: lost the race, "
4846 + "using existing local provider");
4848 provider = pr.mProvider;
4850 holder = new IActivityManager.ContentProviderHolder(info);
4851 holder.provider = provider;
4852 holder.noReleaseNeeded = true;
4853 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
4854 mLocalProviders.put(jBinder, pr);
4855 mLocalProvidersByName.put(cname, pr);
4857 retHolder = pr.mHolder;
4859 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4861 if (DEBUG_PROVIDER) {
4862 Slog.v(TAG, "installProvider: lost the race, updating ref count");
4864 // We need to transfer our new reference to the existing
4865 // ref count, releasing the old one... but only if
4866 // release is needed (that is, it is not running in the
4868 if (!noReleaseNeeded) {
4869 incProviderRefLocked(prc, stable);
4871 ActivityManagerNative.getDefault().removeContentProvider(
4872 holder.connection, stable);
4873 } catch (RemoteException e) {
4874 //do nothing content provider object is dead any way
4878 ProviderClientRecord client = installProviderAuthoritiesLocked(
4879 provider, localProvider, holder);
4880 if (noReleaseNeeded) {
4881 prc = new ProviderRefCount(holder, client, 1000, 1000);
4884 ? new ProviderRefCount(holder, client, 1, 0)
4885 : new ProviderRefCount(holder, client, 0, 1);
4887 mProviderRefCountMap.put(jBinder, prc);
4889 retHolder = prc.holder;
4896 private void attach(boolean system) {
4897 sThreadLocal.set(this);
4898 mSystemThread = system;
4900 ViewRootImpl.addFirstDrawHandler(new Runnable() {
4905 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
4906 UserHandle.myUserId());
4907 RuntimeInit.setApplicationObject(mAppThread.asBinder());
4908 IActivityManager mgr = ActivityManagerNative.getDefault();
4910 mgr.attachApplication(mAppThread);
4911 } catch (RemoteException ex) {
4915 // Don't set application object here -- if the system crashes,
4916 // we can't display an alert, we just want to die die die.
4917 android.ddm.DdmHandleAppName.setAppName("system_process",
4918 UserHandle.myUserId());
4920 mInstrumentation = new Instrumentation();
4921 ContextImpl context = new ContextImpl();
4922 context.init(getSystemContext().mPackageInfo, null, this);
4923 Application app = Instrumentation.newApplication(Application.class, context);
4924 mAllApplications.add(app);
4925 mInitialApplication = app;
4927 } catch (Exception e) {
4928 throw new RuntimeException(
4929 "Unable to instantiate Application():" + e.toString(), e);
4933 // add dropbox logging to libcore
4934 DropBox.setReporter(new DropBoxReporter());
4936 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
4937 public void onConfigurationChanged(Configuration newConfig) {
4938 synchronized (mPackages) {
4939 // We need to apply this change to the resources
4940 // immediately, because upon returning the view
4941 // hierarchy will be informed about it.
4942 if (applyConfigurationToResourcesLocked(newConfig, null)) {
4943 // This actually changed the resources! Tell
4944 // everyone about it.
4945 if (mPendingConfiguration == null ||
4946 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
4947 mPendingConfiguration = newConfig;
4949 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
4954 public void onLowMemory() {
4956 public void onTrimMemory(int level) {
4961 public static ActivityThread systemMain() {
4962 HardwareRenderer.disable(true);
4963 ActivityThread thread = new ActivityThread();
4964 thread.attach(true);
4968 public final void installSystemProviders(List<ProviderInfo> providers) {
4969 if (providers != null) {
4970 installContentProviders(mInitialApplication, providers);
4974 public int getIntCoreSetting(String key, int defaultValue) {
4975 synchronized (mPackages) {
4976 if (mCoreSettings != null) {
4977 return mCoreSettings.getInt(key, defaultValue);
4979 return defaultValue;
4984 private static class EventLoggingReporter implements EventLogger.Reporter {
4986 public void report (int code, Object... list) {
4987 EventLog.writeEvent(code, list);
4991 private class DropBoxReporter implements DropBox.Reporter {
4993 private DropBoxManager dropBox;
4995 public DropBoxReporter() {
4996 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
5000 public void addData(String tag, byte[] data, int flags) {
5001 dropBox.addData(tag, data, flags);
5005 public void addText(String tag, String data) {
5006 dropBox.addText(tag, data);
5010 public static void main(String[] args) {
5011 SamplingProfilerIntegration.start();
5013 // CloseGuard defaults to true and can be quite spammy. We
5014 // disable it here, but selectively enable it later (via
5015 // StrictMode) on debug builds, but using DropBox, not logs.
5016 CloseGuard.setEnabled(false);
5018 Environment.initForCurrentUser();
5020 // Set the reporter for event logging in libcore
5021 EventLogger.setReporter(new EventLoggingReporter());
5023 Process.setArgV0("<pre-initialized>");
5025 Looper.prepareMainLooper();
5027 ActivityThread thread = new ActivityThread();
5028 thread.attach(false);
5030 if (sMainThreadHandler == null) {
5031 sMainThreadHandler = thread.getHandler();
5037 Looper.myLooper().setMessageLogging(new
5038 LogPrinter(Log.DEBUG, "ActivityThread"));
5043 throw new RuntimeException("Main thread loop unexpectedly exited");